The gap
The People API ships purpose-built batch mutation endpoints:
people:batchCreateContacts — up to 200 contacts per request
people:batchUpdateContacts — up to 200 contacts per request
people:batchDeleteContacts — a list of resource names per request
people:batchGet — up to 200 resource names per request
gog contacts reaches none of them. create, update and delete each take one contact and issue one call, and get takes one resourceName.
Where it shows
gog contacts dedupe is the command that makes this concrete. Deduplicating a real address book means deleting tens or hundreds of contacts, and today that is one people.deleteContact per contact. A 300-duplicate cleanup is 300 sequential calls, each independently failable, with a partial-completion state that is hard to reason about and no single call the user can inspect before it runs.
The same shape applies to an import: bringing in a CSV of 200 contacts is 200 calls where the API offers one.
gog contacts export plus get has the mirror problem on the read side. Resolving 200 contacts one at a time is 200 calls where batchGet takes 200 resource names.
What a caller has to do today
Loop, rate-limit by hand, and write its own resume logic after a partial failure.
Proposed surface
Unlike Slides, Sheets and Forms, this is not the accumulate-then-submit gog batch pattern. The People API takes a list of contacts in one call rather than a list of heterogeneous request objects, so variadic arguments and a file input fit better and keep gog batch scoped to batchUpdate-shaped services:
gog contacts delete <resourceName> ... # batchDeleteContacts, chunked at the API cap
gog contacts get <resourceName> ... # batchGet
gog contacts create --from-json=<file> # batchCreateContacts, list of contacts
gog contacts update --from-json=<file> # batchUpdateContacts, keyed by resourceName
gog contacts dedupe # internally uses batchDeleteContacts
Making delete and get variadic matches how gmail archive, gmail trash and gmail mark-read already accept [<messageId> ...], so the CLI grammar is already established in the repo. Chunking at the documented per-request cap, with a stderr note per chunk, keeps a large cleanup to a handful of calls.
dedupe should route through the batch delete whether or not the user-facing flags change, since that is where the count is highest and the user has already confirmed the action.
The gap
The People API ships purpose-built batch mutation endpoints:
people:batchCreateContacts— up to 200 contacts per requestpeople:batchUpdateContacts— up to 200 contacts per requestpeople:batchDeleteContacts— a list of resource names per requestpeople:batchGet— up to 200 resource names per requestgog contactsreaches none of them.create,updateanddeleteeach take one contact and issue one call, andgettakes oneresourceName.Where it shows
gog contacts dedupeis the command that makes this concrete. Deduplicating a real address book means deleting tens or hundreds of contacts, and today that is onepeople.deleteContactper contact. A 300-duplicate cleanup is 300 sequential calls, each independently failable, with a partial-completion state that is hard to reason about and no single call the user can inspect before it runs.The same shape applies to an import: bringing in a CSV of 200 contacts is 200 calls where the API offers one.
gog contacts exportplusgethas the mirror problem on the read side. Resolving 200 contacts one at a time is 200 calls wherebatchGettakes 200 resource names.What a caller has to do today
Loop, rate-limit by hand, and write its own resume logic after a partial failure.
Proposed surface
Unlike Slides, Sheets and Forms, this is not the accumulate-then-submit
gog batchpattern. The People API takes a list of contacts in one call rather than a list of heterogeneous request objects, so variadic arguments and a file input fit better and keepgog batchscoped tobatchUpdate-shaped services:Making
deleteandgetvariadic matches howgmail archive,gmail trashandgmail mark-readalready accept[<messageId> ...], so the CLI grammar is already established in the repo. Chunking at the documented per-request cap, with a stderr note per chunk, keeps a large cleanup to a handful of calls.dedupeshould route through the batch delete whether or not the user-facing flags change, since that is where the count is highest and the user has already confirmed the action.