Skip to the documentation
API

Contacts

Every operation in this group: what it accepts, what it returns and the errors it can answer with.

Operations

The address book, and it belongs to the workspace rather than to whoever saved a row. Every member and every key on the workspace reads and writes the same book.

A contact is addressed by its email address on every route here, because no id is exposed. Two things write rows: somebody saving one, in the app or through this API, which lands as manual, and a member sending mail from the app composer, which lands as auto. Mail ARRIVING from an address creates nothing, so an empty book on a busy mailbox is the expected state rather than a fault.

GET/contacts

List contacts

Scopescontacts:readReads

The address book belongs to the workspace, so every key on it reads the same rows and a contact saved by one member is visible to the rest.

Most recently seen first, with contacts that have never been mailed last. source is manual for an address somebody saved, in the app or through this API, and auto for one recorded because a member sent mail to it from the composer. Mail arriving from an address creates no contact.

Paging is keyset. Pass nextCursor back as cursor while hasMore is true.

Requires the contacts:read scope.

Query parameters

limitinteger

Rows per page, a whole number from 1 to 200. The server defaults to 50.

At least 1At most 200Default50
cursorstring

The nextCursor from the previous page. Never build one yourself.

sourcestring

Narrows the page to contacts recorded that way.

One of"manual""auto""form"
qstring

Searches the name and the address. When nothing matches exactly on the first page, close spellings are returned instead, and the pages that follow keep matching the same way.

Up to 200 characters

Returns

Contacts in this workspace.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.list()nextmail.contacts.listAll()nextmail.contacts.iterate()
Python
contacts.list()contacts.list_all()contacts.iterate()
Ruby
contacts.listcontacts.list_allcontacts.iterate
PHP
contacts->listcontacts->listAllcontacts->iterate
Go
Contacts.ListContacts.ListAllContacts.Iterate
Java
contacts().listcontacts().listAllcontacts().iterate
C#
Contacts.ListAsyncContacts.ListAllAsyncContacts.IterateAsync
CLI
nextmail contacts list
MCP
listContacts

POST/contacts

Create a contact

Scopescontacts:writeChanges data

The address is the identity, so there is no id to choose and no id in the response. It is trimmed and lower cased before it is stored, and the contact is saved with source set to manual.

The new contact joins the built-in default audience as it is written, and any audience named in audienceIds alongside it. Naming audiences also requires the audiences:write scope.

An address already in the book is refused rather than merged, so a retry cannot overwrite a name somebody edited in the app.

Requires the contacts:write scope.

Request body

emailstringRequired

Trimmed and lower cased before it is stored.

Up to 320 charactersFormatemail
namestring

Display name. Leave it out to save the contact without one.

Can be nullUp to 200 characters
notesstring

Free text kept with the contact and shown beside it in the app.

Can be nullUp to 5000 characters
attributesRecord<string, string>

Custom fields to set, as an object of keys and text values. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of at most 500 characters, trimmed before it is stored. null or an empty string removes a field, and a field you leave out keeps its value. A contact holds at most 50. A key or value that breaks a rule, or a 51st field, is 422 invalid_contact with param set to attributes.<key> or attributes, and nothing is written.

audienceIdsstring[]

Audiences to put the new contact in. The default audience is joined whether or not it is named here. Sending this also requires the audiences:write scope.

Up to 25 items

Returns

Created.

Errors

409

contact_exists: that address is already in this workspace book. PATCH it instead.

422

invalid_contact when the address is not one or a custom field in attributes breaks a rule, with param naming the field.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.create()
Python
contacts.create()
Ruby
contacts.create
PHP
contacts->create
Go
Contacts.Create
Java
contacts().create
C#
Contacts.CreateAsync
CLI
nextmail contacts create
MCP
createContactsaveContactupdateContact

GET/contacts/people

List people

Scopescontacts:readReads

Everyone on the Contacts page in the app: the saved contacts, and every address seen in mail as the sender or a recipient of a thread's newest message, with the number of threads and when mail last moved. A person seen in mail and saved is one row.

The addresses seen in mail are listed only when the key also holds threads:read, because they are read out of the mail. Without it the rows are the saved contacts alone and seen is false. A key limited to particular addresses or domains gets the saved contacts alone too, with seen false, even when it holds threads:read, because the other addresses would be read out of the mail of every address in the workspace. Deleted addresses and the mailbox's own addresses are left out.

blockedBy names the workspace blocklist rule that blocks a row, the same rule blocked=true filters on.

Requires the contacts:read scope.

Query parameters

limitinteger

Rows per page, 1 to 100.

At least 1At most 100Default25
cursorstring

An opaque cursor from the previous page, with the same sort, q and blocked. Keyset, not offset: pass the previous page's nextCursor. One that names nothing in this list is a 400 invalid_cursor.

sortstring

recent puts the newest mail first, then saved contacts never seen in mail. name goes by name, or by address where there is none, ignoring case. threads puts the people with the most threads first.

One of"recent""name""threads"Default"recent"
qstring

Searches names, addresses and notes, with close spellings when nothing matches exactly.

Up to 200 characters
emailstring

One address only, matched case insensitively: the way to read one person's thread count and last mail.

Up to 320 characters
blockedstring

true for only the people the workspace blocklist blocks, whole-domain rules included.

One of"true""false"

Returns

A page of people.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.listPeople()nextmail.contacts.listAllPeople()nextmail.contacts.iteratePeople()
Python
contacts.list_people()contacts.list_all_people()contacts.iterate_people()
Ruby
contacts.list_peoplecontacts.list_all_peoplecontacts.iterate_people
PHP
contacts->listPeoplecontacts->listAllPeoplecontacts->iteratePeople
Go
Contacts.ListPeopleContacts.ListAllPeopleContacts.IteratePeople
Java
contacts().listPeoplecontacts().listAllPeoplecontacts().iteratePeople
C#
Contacts.ListPeopleAsyncContacts.ListAllPeopleAsyncContacts.IteratePeopleAsync
CLI
nextmail contacts list-people
MCP
listPeople

POST/contacts/batch-delete

Delete contacts in bulk

Scopescontacts:writeDeletes

Deletes up to 200 addresses in one call, each the way DELETE /contacts/{email} deletes one: a saved contact goes with its notes, photo and audience memberships, and every address is hidden, so a send does not record it again. Addresses that were only seen in mail are hidden too. An entry that is not an address comes back in invalid and the rest still go through.

Requires the contacts:write scope.

Request body

emailsstring[]Required

Addresses, matched case insensitively. A repeated address counts once.

1 to 200 items

Returns

What was deleted.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.deleteMany()
Python
contacts.delete_many()
Ruby
contacts.delete_many
PHP
contacts->deleteMany
Go
Contacts.DeleteMany
Java
contacts().deleteMany
C#
Contacts.DeleteManyAsync
CLI
nextmail contacts delete-many
MCP
deleteContacts

GET/contacts/{email}

Retrieve a contact

Scopescontacts:readReads

The book is the workspace's. The address is matched case insensitively, and it is a path segment, so URL encode it: grace@example.com travels as grace%40example.com.

A 404 means only that the address is not in the book. It says nothing about whether mail has been exchanged with it.

A caller that also holds forms:read gets signUps: what this address sent through sign-up forms, with every answer.

Requires the contacts:read scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Returns

The contact.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.get()
Python
contacts.get()
Ruby
contacts.get
PHP
contacts->get
Go
Contacts.Get
Java
contacts().get
C#
Contacts.GetAsync
CLI
nextmail contacts get
MCP
getContact

PATCH/contacts/{email}

Update a contact

Scopescontacts:writeChanges data

A partial update, never an upsert. An address not in the book is a 404.

The address itself cannot be changed: it is the identity and the path segment, so moving a contact to a new address is a delete and a create. source and lastSeenAt are the server's and are not accepted here.

Requires the contacts:write scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Request body

namestring

New display name. Null clears it.

Can be nullUp to 200 characters
notesstring

New notes. Null clears them.

Can be nullUp to 5000 characters
attributesRecord<string, string>

Custom fields to set, as an object of keys and text values. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of at most 500 characters, trimmed before it is stored. null or an empty string removes a field, and a field you leave out keeps its value. A contact holds at most 50. A key or value that breaks a rule, or a 51st field, is 422 invalid_contact with param set to attributes.<key> or attributes, and nothing is written.

Returns

Saved.

Errors

422

invalid_contact when a custom field in attributes breaks a rule, with param naming the field.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.update()
Python
contacts.update()
Ruby
contacts.update
PHP
contacts->update
Go
Contacts.Update
Java
contacts().update
C#
Contacts.UpdateAsync
CLI
nextmail contacts update
MCP
createContactsaveContactupdateContact

PUT/contacts/{email}

Save a contact

Scopescontacts:writeChanges data

Saves the address the way Add to contacts and Keep in contacts do in the app. An address that is not a contact yet becomes one, answered with 201. One recorded from a send becomes manual, and one already saved keeps what it has, answered with 200. A deleted address is brought back. The body is optional.

Requires the contacts:write scope.

Path parameters

emailstringRequired

The address, trimmed and lower cased on the server.

Request body

namestring

Up to 200 characters. Left out, the stored name is kept.

Up to 200 characters
notesstring

Up to 5,000 characters. null clears the notes; left out, they are kept.

Can be nullUp to 5000 characters
attributesRecord<string, string>

Custom fields to set, as an object of keys and text values. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of at most 500 characters, trimmed before it is stored. null or an empty string removes a field, and a field you leave out keeps its value. A contact holds at most 50. A key or value that breaks a rule, or a 51st field, is 422 invalid_contact with param set to attributes.<key> or attributes, and nothing is written.

Returns

Already a contact, now kept as manual.

Saved as a new contact.

Errors

422

unknown_parameter for any key but name, notes and attributes, or invalid_contact when a custom field breaks a rule.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.save()
Python
contacts.save()
Ruby
contacts.save
PHP
contacts->save
Go
Contacts.Save
Java
contacts().save
C#
Contacts.SaveAsync
CLI
nextmail contacts save
MCP
createContactsaveContactupdateContact

DELETE/contacts/{email}

Delete a contact

Scopescontacts:writeDeletes

Deletes somebody from the contacts the way Delete does in the app. A saved contact goes with its notes, its photo and every audience membership, the built-in default one included. The address is then hidden: it leaves GET /contacts/people, and mail sent to it from the app composer no longer records it. The address can be one that was only ever seen in mail.

No mail moves. Saving the address again, with POST /contacts or PUT /contacts/{email}, brings it back as a new contact.

Requires the contacts:write scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Returns

Deleted and hidden.

Errors

422

invalid_contact when the path is not an address.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.delete()
Python
contacts.delete()
Ruby
contacts.delete
PHP
contacts->delete
Go
Contacts.Delete
Java
contacts().delete
C#
Contacts.DeleteAsync
CLI
nextmail contacts delete
MCP
deleteContact

PUT/contacts/{email}/photo

Set a contact photo

Scopescontacts:writeChanges data

Uploads the photo shown for the contact, replacing any there was. Send the image itself as the body, not JSON, with its type in Content-Type: image/png, image/jpeg, image/webp, image/gif. Up to 5 MB goes in. It is fitted into a 512 pixel square and stored as WebP, and an animated image keeps its first frame.

The address has to be a saved contact: save it with PUT /contacts/{email} first.

Requires the contacts:write scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Request body

Content typeimage/png, image/jpeg, image/webp, image/gif

binary

Returns

The contact, with its new photoUrl.

Errors

404

contact_not_found on email: the address is not a saved contact.

422

invalid_image when the body is not an image of an accepted type, is too large or cannot be read.

502

image_not_stored: the image was read but could not be stored. Try again.

503

image_busy: the image service is saturated. Try again shortly.

The errors every operation can return400401403429500Error catalog

Also available in

TypeScript
nextmail.contacts.setPhoto()
Python
contacts.set_photo()
Ruby
contacts.set_photo
PHP
contacts->setPhoto
Go
Contacts.SetPhoto
Java
contacts().setPhoto
C#
Contacts.SetPhotoAsync
CLI
nextmail contacts set-photo
MCP
setContactPhoto

DELETE/contacts/{email}/photo

Remove a contact photo

Scopescontacts:writeDeletes

Removes the contact photo and deletes the stored image. Removing a photo from a contact that has none changes nothing.

Requires the contacts:write scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Returns

The contact, with photoUrl null.

Errors

404

contact_not_found on email: the address is not a saved contact.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.contacts.removePhoto()
Python
contacts.remove_photo()
Ruby
contacts.remove_photo
PHP
contacts->removePhoto
Go
Contacts.RemovePhoto
Java
contacts().removePhoto
C#
Contacts.RemovePhotoAsync
CLI
nextmail contacts remove-photo
MCP
removeContactPhoto

POST/contacts/{email}/block

Block a contact

Scopessettings:writeChanges data

Puts the address on the workspace blocklist, the one PATCH /settings edits as blockedSenders, so mail from it is refused from then on. A plus tag is dropped: blocking ada+news@example.com blocks ada@example.com. When a rule already blocks the address, a whole-domain one included, nothing is added and created is false. The address does not have to be a contact.

It needs settings:write, because it writes the blocklist rather than the contact.

Requires the settings:write scope.

Path parameters

emailstringRequired

The address to block.

Returns

Blocked.

Errors

422

invalid_contact when the path is not an address, blocklist_entry_too_broad when it has fewer than two letters or numbers, or the narrowed-key refusal. capability_unsupported on addressAllowlist: the blocklist belongs to the whole workspace and filters the mail of every address in it, so a key limited to particular addresses or domains cannot change it. Use a key with no address or domain restriction.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.block()
Python
contacts.block()
Ruby
contacts.block
PHP
contacts->block
Go
Contacts.Block
Java
contacts().block
C#
Contacts.BlockAsync
CLI
nextmail contacts block

DELETE/contacts/{email}/block

Unblock a contact

Scopessettings:writeDeletes

Takes every workspace blocklist rule that blocks the address off the list, and lists them in removed. When one is a whole-domain rule, everybody at that domain is unblocked with it. Rules set for one address or one domain in the settings are not touched. An address no rule blocks answers with removed empty.

Requires the settings:write scope.

Path parameters

emailstringRequired

The address to unblock.

Returns

Unblocked.

Errors

422

invalid_contact when the path is not an address, or the narrowed-key refusal. capability_unsupported on addressAllowlist: the blocklist belongs to the whole workspace and filters the mail of every address in it, so a key limited to particular addresses or domains cannot change it. Use a key with no address or domain restriction.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.unblock()
Python
contacts.unblock()
Ruby
contacts.unblock
PHP
contacts->unblock
Go
Contacts.Unblock
Java
contacts().unblock
C#
Contacts.UnblockAsync
CLI
nextmail contacts unblock

GET/contacts/{email}/threads

List conversations with a contact

Scopesthreads:readReads

Every thread the address wrote or was written to, in every folder, the Mail tab on a contact in the app. The address does not have to be a saved contact. Each row is a summary of the thread; GET /threads/{id} reads the messages.

Requires the threads:read scope.

Path parameters

emailstringRequired

The address. It does not have to be a saved contact.

Query parameters

limitinteger

Threads per page, 1 to 100.

At least 1At most 100Default25
cursorstring

The previous page's nextCursor, with the same q and sort.

qstring

Searches inside those threads, with the same syntax as the mailbox search.

Up to 200 characters
sortstring

newest (the default), oldest, sender or subject.

One of"newest""oldest""sender""subject"Default"newest"

Returns

A page of threads.

Errors

422

invalid_contact when the path is not an address, or the narrowed-key refusal. capability_unsupported on addressAllowlist: a contact's threads and activity are read from the mail of every address in the workspace, so a key limited to particular addresses or domains cannot read them. Use a key with no address or domain restriction.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.listThreads()nextmail.contacts.listAllThreads()nextmail.contacts.iterateThreads()
Python
contacts.list_threads()contacts.list_all_threads()contacts.iterate_threads()
Ruby
contacts.list_threadscontacts.list_all_threadscontacts.iterate_threads
PHP
contacts->listThreadscontacts->listAllThreadscontacts->iterateThreads
Go
Contacts.ListThreadsContacts.ListAllThreadsContacts.IterateThreads
Java
contacts().listThreadscontacts().listAllThreadscontacts().iterateThreads
C#
Contacts.ListThreadsAsyncContacts.ListAllThreadsAsyncContacts.IterateThreadsAsync
CLI
nextmail contacts list-threads

GET/contacts/{email}/activity

Read activity with a contact

Scopesthreads:readReads

The Activity tab on a contact in the app: messages received from the address and sent to it, per bucket, over a window that ends now, with the threads that moved, the threads waiting on a reply from the mailbox, and the median time each side takes to answer. Mail in the bin or in spam is left out.

Requires the threads:read scope.

Path parameters

emailstringRequired

The address. It does not have to be a saved contact.

Query parameters

minutesinteger

How far back the window reaches from now. The default is 90 days.

At least 1At most 10540800Default129600
grainstring

Bucket width: minute, hour or day, defaulting to day.

One of"minute""hour""day"Default"day"
offsetMinutesinteger

The reader's offset from UTC in minutes, so that a day bucket falls on their calendar.

At least -840At most 840Default0

Returns

The activity.

Errors

422

invalid_contact when the path is not an address, or the narrowed-key refusal. capability_unsupported on addressAllowlist: a contact's threads and activity are read from the mail of every address in the workspace, so a key limited to particular addresses or domains cannot read them. Use a key with no address or domain restriction.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.activity()
Python
contacts.activity()
Ruby
contacts.activity
PHP
contacts->activity
Go
Contacts.Activity
Java
contacts().activity
C#
Contacts.ActivityAsync
CLI
nextmail contacts activity
MCP
getContactActivity

PUT/contacts/{email}/audiences

Set a contact's audiences

Scopesaudiences:writeChanges data

Sets exactly which audiences the contact is in, the way the audience picker on a contact does in the app. The contact joins every listed audience it is not in yet and leaves every other one, in one transaction. The built-in default audience is always kept, so { "audienceIds": [] } leaves the contact in the default audience alone. Memberships it keeps also keep their addedAt.

The address is matched case insensitively and has to be a contact already. Create it with POST /contacts, which takes audienceIds too. An id that names no audience in this workspace refuses the whole call and changes nothing.

audiences:write is the only scope checked, because this writes memberships rather than the contact. Sending the same list again changes nothing, so a retry is safe.

Requires the audiences:write scope.

Path parameters

emailstringRequired

The contact's address, matched case insensitively.

Request body

audienceIdsstring[]Required

Every audience the contact should be in once the call returns, up to 100. The default audience is kept whether or not it is named, so an empty array leaves only the default one. A repeated id counts once.

Up to 100 items

Returns

The contact, with the audiences it is in after the change.

Errors

404

contact_not_found on email when the address is not in the workspace book, or audience_not_found on audienceIds when an id names no audience here. Nothing is changed.

422

invalid_parameter on audienceIds for more than 100 ids, and on the entry, such as audienceIds.0, for an empty one, unknown_parameter for any other key in the body.

The errors every operation can return400401403429500Error catalog

Also available in

TypeScript
nextmail.contacts.setAudiences()
Python
contacts.set_audiences()
Ruby
contacts.set_audiences
PHP
contacts->setAudiences
Go
Contacts.SetAudiences
Java
contacts().setAudiences
C#
Contacts.SetAudiencesAsync
CLI
nextmail contacts set-audiences
MCP
setContactAudiences

GET/contacts/cards

List contact cards

Scopescontacts:readReads

The address book in full: every saved contact as a card with its phone numbers, postal addresses, organisation, birthday and other details, plus the cards that have no email address, such as a plumber saved on a phone. It is the same address book phones and computers sync over CardDAV.

Newest first. Pass email for the card of one saved contact, or withoutEmail=true for only the cards with no address. An address that was only ever mailed, and never saved, has no card. Paging is keyset: pass nextCursor back as cursor while hasMore is true.

Requires the contacts:read scope.

Query parameters

limitinteger

Cards per page, 1 to 200. 50 when left out.

At least 1At most 200
cursorstring

The nextCursor from the previous page. One that names no card is a 400 invalid_cursor.

1 to 64 characters
emailstring

Only the card of the saved contact with this address.

1 to 320 characters
withoutEmailstring

true lists only the cards that have no email address.

One of"true""false"
kindstring

group lists only the groups, individual only the people and companies.

One of"individual""group"
groupIdstring

Only the cards in the group with this id.

1 to 64 characters

Returns

One page of cards.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.listCards()nextmail.contacts.listAllCards()nextmail.contacts.iterateCards()
Python
contacts.list_cards()contacts.list_all_cards()contacts.iterate_cards()
Ruby
contacts.list_cardscontacts.list_all_cardscontacts.iterate_cards
PHP
contacts->listCardscontacts->listAllCardscontacts->iterateCards
Go
Contacts.ListCardsContacts.ListAllCardsContacts.IterateCards
Java
contacts().listCardscontacts().listAllCardscontacts().iterateCards
C#
Contacts.ListCardsAsyncContacts.ListAllCardsAsyncContacts.IterateCardsAsync
CLI
nextmail contacts list-cards
MCP
getContactCardlistContactCards

POST/contacts/cards

Create a contact card

Scopescontacts:writeChanges data

Adds a card to the address book. With email it is a saved contact as well, the same one POST /contacts makes, and an address the workspace already knows from mail becomes saved. Without one it is a card on its own, kept for its name, phone numbers and the rest. A card needs at least a name, an email address, a phone number or an organisation.

Requires the contacts:write scope.

Request body

emailstring

The address Nextmail knows the contact by. Give it to a card that has none and the card becomes a saved contact. A saved contact keeps its address, so put any other address in emails.

Can be nullUp to 320 charactersFormatemail
namestring

The full name the address book shows.

Can be nullUp to 200 characters
namePartsobject

The name in parts, the way phones keep it. Left out, phones split name themselves.

Can be null
prefixstring

A title before the name, such as Dr.

Can be nullUp to 200 charactersDefaultnull
givenstring

The first name.

Can be nullUp to 200 charactersDefaultnull
middlestring

Any middle names.

Can be nullUp to 200 charactersDefaultnull
familystring

The surname.

Can be nullUp to 200 charactersDefaultnull
suffixstring

Anything after the name, such as Jr.

Can be nullUp to 200 charactersDefaultnull
nicknamestring

A nickname.

Can be nullUp to 200 characters
organizationstring

The company or organisation.

Can be nullUp to 200 characters
departmentstring

The department within the organisation.

Can be nullUp to 200 characters
titlestring

The job title.

Can be nullUp to 200 characters
birthdaystring

YYYY-MM-DD, or --MM-DD when the year is not known.

Can be nullPattern^(?:\d{4}-|--)(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
notesstring

Free-form notes. On a saved contact these are the notes the contact page shows.

Can be nullUp to 5000 characters
emailsobject[]

Other email addresses, besides email. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The email address.

Up to 320 charactersFormatemail
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
phonesobject[]

Phone numbers. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The number or the link.

1 to 320 characters
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
addressesobject[]

Postal addresses. Given, it replaces the whole list.

Up to 50 items
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
streetstring

The street and house number, on as many lines as it needs.

Can be nullUp to 200 charactersDefaultnull
localitystring

The city or town.

Can be nullUp to 200 charactersDefaultnull
regionstring

The state, county or province.

Can be nullUp to 200 charactersDefaultnull
postalCodestring

The postal code.

Can be nullUp to 200 charactersDefaultnull
countrystring

The country.

Can be nullUp to 200 charactersDefaultnull
urlsobject[]

Websites and profile links. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The number or the link.

1 to 320 characters
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
kindstring

individual for a person or a company, group for a list of other cards, the groups phones keep.

One of"individual""group"
membersstring[]

The ids of the cards in the group. Only a group takes it, and a list you send replaces the whole list.

Up to 2000 items

Returns

The new card.

Errors

409

contact_card_email_taken: another card already has that address. contact_card_limit: the workspace keeps as many cards as it may.

422

invalid_contact_card: the card has nothing to keep, or a field is not valid.

The errors every operation can return400401403404429500Error catalog

Also available in

TypeScript
nextmail.contacts.createCard()
Python
contacts.create_card()
Ruby
contacts.create_card
PHP
contacts->createCard
Go
Contacts.CreateCard
Java
contacts().createCard
C#
Contacts.CreateCardAsync
CLI
nextmail contacts create-card
MCP
createContactCard

GET/contacts/cards/{id}

Get a contact card

Scopescontacts:readReads

One card with everything it holds.

Requires the contacts:read scope.

Path parameters

idstringRequired

The card id from GET /contacts/cards.

Returns

The card.

Errors

404

contact_card_not_found: no card has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.contacts.getCard()
Python
contacts.get_card()
Ruby
contacts.get_card
PHP
contacts->getCard
Go
Contacts.GetCard
Java
contacts().getCard
C#
Contacts.GetCardAsync
CLI
nextmail contacts get-card
MCP
getContactCard

PATCH/contacts/cards/{id}

Update a contact card

Scopescontacts:writeChanges data

Changes the fields you send and leaves the rest alone. null clears a field, and a list you send replaces the whole list. On a saved contact, name and notes are the contact's own, so the contact page shows the change. email can only be given to a card that has none, which makes it a saved contact: a saved contact keeps its address, so add another address to emails instead. Phones and computers that sync the address book over CardDAV get the change on their next sync.

Requires the contacts:write scope.

Path parameters

idstringRequired

The card id from GET /contacts/cards.

Request body

emailstring

The address Nextmail knows the contact by. Give it to a card that has none and the card becomes a saved contact. A saved contact keeps its address, so put any other address in emails.

Can be nullUp to 320 charactersFormatemail
namestring

The full name the address book shows.

Can be nullUp to 200 characters
namePartsobject

The name in parts, the way phones keep it. Left out, phones split name themselves.

Can be null
prefixstring

A title before the name, such as Dr.

Can be nullUp to 200 charactersDefaultnull
givenstring

The first name.

Can be nullUp to 200 charactersDefaultnull
middlestring

Any middle names.

Can be nullUp to 200 charactersDefaultnull
familystring

The surname.

Can be nullUp to 200 charactersDefaultnull
suffixstring

Anything after the name, such as Jr.

Can be nullUp to 200 charactersDefaultnull
nicknamestring

A nickname.

Can be nullUp to 200 characters
organizationstring

The company or organisation.

Can be nullUp to 200 characters
departmentstring

The department within the organisation.

Can be nullUp to 200 characters
titlestring

The job title.

Can be nullUp to 200 characters
birthdaystring

YYYY-MM-DD, or --MM-DD when the year is not known.

Can be nullPattern^(?:\d{4}-|--)(?:0[1-9]|1[0-2])-(?:0[1-9]|[12]\d|3[01])$
notesstring

Free-form notes. On a saved contact these are the notes the contact page shows.

Can be nullUp to 5000 characters
emailsobject[]

Other email addresses, besides email. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The email address.

Up to 320 charactersFormatemail
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
phonesobject[]

Phone numbers. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The number or the link.

1 to 320 characters
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
addressesobject[]

Postal addresses. Given, it replaces the whole list.

Up to 50 items
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
streetstring

The street and house number, on as many lines as it needs.

Can be nullUp to 200 charactersDefaultnull
localitystring

The city or town.

Can be nullUp to 200 charactersDefaultnull
regionstring

The state, county or province.

Can be nullUp to 200 charactersDefaultnull
postalCodestring

The postal code.

Can be nullUp to 200 charactersDefaultnull
countrystring

The country.

Can be nullUp to 200 charactersDefaultnull
urlsobject[]

Websites and profile links. Given, it replaces the whole list.

Up to 50 items
valuestringRequired

The number or the link.

1 to 320 characters
labelstring

What the entry is for: home, work, mobile, main, fax, pager or other.

One of"home""work""mobile""main""fax""pager""other"Default"other"
customLabelstring

A label of your own, such as Assistant. Address books that support it show it instead of label.

Can be nullUp to 60 charactersDefaultnull
kindstring

individual for a person or a company, group for a list of other cards, the groups phones keep.

One of"individual""group"
membersstring[]

The ids of the cards in the group. Only a group takes it, and a list you send replaces the whole list.

Up to 2000 items

Returns

The card as it is now.

Errors

404

contact_card_not_found: no card has that id.

409

contact_card_email_taken: another card already has that address.

422

invalid_contact_card: a field is not valid, or the call tries to change the address of a saved contact.

The errors every operation can return400401403429500Error catalog

Also available in

TypeScript
nextmail.contacts.updateCard()
Python
contacts.update_card()
Ruby
contacts.update_card
PHP
contacts->updateCard
Go
Contacts.UpdateCard
Java
contacts().updateCard
C#
Contacts.UpdateCardAsync
CLI
nextmail contacts update-card
MCP
updateContactCard

DELETE/contacts/cards/{id}

Delete a contact card

Scopescontacts:writeDeletes

Removes the card from the address book, and from every phone and computer that syncs it. On a saved contact this is the same as DELETE /contacts/{email}: the contact goes with its notes, photo and audiences, and the address is hidden from the people list and the suggestions.

Requires the contacts:write scope.

Path parameters

idstringRequired

The card id from GET /contacts/cards.

Returns

The card is gone.

Errors

404

contact_card_not_found: no card has that id.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.contacts.deleteCard()
Python
contacts.delete_card()
Ruby
contacts.delete_card
PHP
contacts->deleteCard
Go
Contacts.DeleteCard
Java
contacts().deleteCard
C#
Contacts.DeleteCardAsync
CLI
nextmail contacts delete-card
MCP
deleteContactCard

GET/contacts/cards/duplicates

Find duplicate contact cards

Scopescontacts:readReads

Cards that look like the same person: they share an email address or a phone number, or have the same full name. Each group lists its cards with the most complete one first, the one to keep when you merge them with POST /contacts/cards/{id}/merge. Groups found by a shared address come first, then by phone number, then by name. Groups of cards are never compared.

Requires the contacts:read scope.

Returns

The groups of cards that look like one person.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.findDuplicateCards()
Python
contacts.find_duplicate_cards()
Ruby
contacts.find_duplicate_cards
PHP
contacts->findDuplicateCards
Go
Contacts.FindDuplicateCards
Java
contacts().findDuplicateCards
C#
Contacts.FindDuplicateCardsAsync
CLI
nextmail contacts find-duplicate-cards
MCP
findDuplicateContacts

POST/contacts/cards/{id}/merge

Merge contact cards

Scopescontacts:writeDeletes

Folds the other cards into this one and deletes them. Fields this card leaves empty are filled from the others, and every email address, phone number, postal address and link is kept. Groups that held the others hold this card instead. A saved contact among the others stays known by its address, in the people list and in its audiences, but it leaves the address book. Phones and computers that sync the address book over CardDAV get the change on their next sync.

Requires the contacts:write scope.

Path parameters

idstringRequired

The card id from GET /contacts/cards.

Request body

cardIdsstring[]Required

The cards to fold into this one. They are deleted once their details are kept.

1 to 10 items

Returns

The card that kept everything.

Errors

404

contact_card_not_found: no card has one of those ids.

422

invalid_contact_card: the list names the card itself, or a group.

The errors every operation can return400401403429500Error catalog

Also available in

TypeScript
nextmail.contacts.mergeCards()
Python
contacts.merge_cards()
Ruby
contacts.merge_cards
PHP
contacts->mergeCards
Go
Contacts.MergeCards
Java
contacts().mergeCards
C#
Contacts.MergeCardsAsync
CLI
nextmail contacts merge-cards
MCP
mergeContactCards

GET/contacts/birthdays

List birthdays

Scopescontacts:readReads

The birthdays of the people in the address book that fall between from and to, one entry for each date, with their age when the card holds the year of birth. Someone born on 29 February has their birthday on 28 February in other years. It is the birthdays calendar the Calendar page of the app can show. from and to are ISO 8601 with a zone, at most a year apart, and timezone, UTC unless you say, decides which day the window starts and ends on.

Requires the contacts:read scope.

Query parameters

fromstring

Start of the window.

tostring

End of the window, after from and at most 366 days later.

timezonestring

IANA zone such as Europe/London. Defaults to UTC.

1 to 64 charactersDefault"UTC"

Returns

Every birthday in the window, sorted by date and then by name.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.listBirthdays()
Python
contacts.list_birthdays()
Ruby
contacts.list_birthdays
PHP
contacts->listBirthdays
Go
Contacts.ListBirthdays
Java
contacts().listBirthdays
C#
Contacts.ListBirthdaysAsync
CLI
nextmail contacts list-birthdays
MCP
listBirthdays

GET/contacts/imports

List contacts imports

Scopescontacts:readReads

The contacts files and address books brought in, newest first, each with what it added and what it left out. Paging is keyset: pass nextCursor back as cursor while hasMore is true.

Requires the contacts:read scope.

Query parameters

limitinteger

Rows per page, 1 to 100.

At least 1At most 100Default25
cursorstring

The previous page's nextCursor, passed back as it came. It is opaque: it holds where the last row sat in this list's order, so a row deleted or edited between pages never breaks the walk, and the next page starts at the first row that sorts after it. A value this list did not hand out is a 400 invalid_cursor.

Returns

One page of contacts imports.

Errors

The errors every operation can return400401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.listImports()nextmail.contacts.listAllImports()nextmail.contacts.iterateImports()
Python
contacts.list_imports()contacts.list_all_imports()contacts.iterate_imports()
Ruby
contacts.list_importscontacts.list_all_importscontacts.iterate_imports
PHP
contacts->listImportscontacts->listAllImportscontacts->iterateImports
Go
Contacts.ListImportsContacts.ListAllImportsContacts.IterateImports
Java
contacts().listImportscontacts().listAllImportscontacts().iterateImports
C#
Contacts.ListImportsAsyncContacts.ListAllImportsAsyncContacts.IterateImportsAsync
CLI
nextmail contacts list-imports
MCP
listContactImports

POST/contacts/imports

Import a contacts file

Scopescontacts:writeChanges data

Takes a vCard (.vcf) file as the request body and queues it. Every card in it becomes a contact card, with its phone numbers, addresses and the rest. Poll GET /contacts/imports/{id} until status is completed.

The file may be 20 MB. Imported contacts join no audience, so a broadcast never reaches them because of an import. A card whose address or UID is already in the address book is counted under merged and left as it is, and a card with no address is matched on its phone number. A workspace keeps 20,000 cards, and the cards past that are counted under skipped.

Requires the contacts:write scope.

Query parameters

filenamestring

The name to show for the file in the list of imports.

Up to 255 characters

Request body

Content typetext/vcard, application/octet-stream

binary

Returns

The import, with status queued.

Errors

400

not_a_contacts_file: the body holds no vCard. item_import_empty: the body is empty.

413

item_import_too_large: the file is over 20 MB.

The errors every operation can return401403404422429500Error catalog

Also available in

TypeScript
nextmail.contacts.importVcf()
Python
contacts.import_vcf()
Ruby
contacts.import_vcf
PHP
contacts->importVcf
Go
Contacts.ImportVcf
Java
contacts().importVcf
C#
Contacts.ImportVcfAsync
CLI
nextmail contacts import-vcf

GET/contacts/imports/{id}

Get a contacts import

Scopescontacts:readReads

One contacts import with its counts and its report: the files it read, how many cards it left out and why, and up to 20 of the cards it left out.

Requires the contacts:read scope.

Path parameters

idstringRequired

Contacts import id, iimp_ followed by 24 hex characters.

Returns

The import.

Errors

404

item_import_not_found: no such import.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.contacts.getImport()
Python
contacts.get_import()
Ruby
contacts.get_import
PHP
contacts->getImport
Go
Contacts.GetImport
Java
contacts().getImport
C#
Contacts.GetImportAsync
CLI
nextmail contacts get-import
MCP
getContactImport

POST/contacts/imports/{id}/undo

Remove what a contacts import added

Scopescontacts:writeDeletes

Deletes every contact and card the import added, changed since or not, and marks the import undone. Contacts that were already in the address book are not touched.

Requires the contacts:write scope.

Path parameters

idstringRequired

Contacts import id, iimp_ followed by 24 hex characters.

Returns

The import, with status undone.

Errors

404

item_import_not_found: no such import.

409

item_import_not_undoable: it is still running or was already removed.

The errors every operation can return400401403422429500Error catalog

Also available in

TypeScript
nextmail.contacts.undoImport()
Python
contacts.undo_import()
Ruby
contacts.undo_import
PHP
contacts->undoImport
Go
Contacts.UndoImport
Java
contacts().undoImport
C#
Contacts.UndoImportAsync
CLI
nextmail contacts undo-import
MCP
undoContactImport

Objects

Contactobject

objectstring
One of"contact"
emailstring

Trimmed and lower cased on write. This is the key every contact route takes, because no contact id is exposed.

namestring
Can be null
sourcestring

auto when a send from the app composer recorded the address, manual when somebody saved it here or in the app. A recorded send never downgrades a manual contact to auto.

One of"manual""auto""form"
notesstring
Can be null
attributesRecord<string, string>

The custom fields of the contact, as an object of keys and text values, at most 50 of them. Empty when it has none. An automation reads one as attributes.<key>, in an email value, a branch or a trigger filter, and its update_field step writes one.

photoUrlstring

Where the contact photo is served, or null when the contact has none. Set it with PUT /contacts/{email}/photo. A new upload gets a new URL.

Can be null
lastSeenAtstring

When mail last went to this address from the app composer. Null until it does.

Can be nullFormatdate-time
createdAtstring
Formatdate-time
updatedAtstring
Formatdate-time

ContactActivityobject

objectstring
One of"contact_activity"
emailstring
sincestring

The start of the first bucket, on the boundary grain and offsetMinutes put it.

Formatdate-time
untilstring
Formatdate-time
grainstring
One of"minute""hour""day"
bucketsobject[]

Only the buckets with mail in them, oldest first.

bucketstring

The bucket in the reader's time: 2026-09-23, 2026-09-23T14 or 2026-09-23T14:05.

receivedinteger

Messages from this address.

sentinteger

Messages from the mailbox to this address.

totalsobject
receivedinteger
sentinteger
threadsinteger

Threads with at least one message in the window.

waitinginteger

Threads whose newest message is from this address, so the mailbox owes the reply.

lastReceivedAtstring
Can be nullFormatdate-time
lastSentAtstring
Can be nullFormatdate-time
replyTimeobject
yoursnumber

Median milliseconds the mailbox took to answer, or null without a reply to measure.

Can be null
theirsnumber

Median milliseconds this address took to answer.

Can be null

ContactBatchDeleteobject

objectstring
One of"contact_batch_delete"
deletedinteger

Addresses deleted and hidden, saved or not.

savedinteger

Of those, how many were saved contacts.

invalidstring[]

Entries that are not addresses, lower cased. Nothing happened to them.

ContactBirthdayobject

objectstringRequired
One of"contact_birthday"
cardIdstringRequired

The card the birthday is on.

contactIdstringRequired

The saved contact the card belongs to, or null for a card with no address.

Can be null
emailstringRequired

The address of that saved contact.

Can be null
namestringRequired

The name on the card, or its organisation.

Can be null
birthdaystringRequired

The birthday as the card holds it: YYYY-MM-DD, or --MM-DD when the year is not known.

datestringRequired

The day in the window the birthday falls on.

Formatdate
ageintegerRequired

How old they turn that day, or null when the year of birth is not known.

Can be null
photoUrlstringRequired

Where the contact photo is served, or null when there is none.

Can be null

ContactBlockobject

objectstring
One of"contact_block"
emailstring

The address as the blocklist sees it: lower cased, with any plus tag dropped.

blockedboolean
blockedByobject

On a block, the rule that now blocks the address.

Can be null
rulestring

The entry on the workspace blocklist that matches this address, exactly as it is stored.

liststring

blockedSenders for an address or pattern rule, blockedDomains for a rule that blocks a whole domain and every subdomain under it.

One of"blockedSenders""blockedDomains"
createdboolean

On a block, false when a rule already blocked the address and nothing was added.

removedobject[]

On an unblock, every rule taken off the workspace blocklist. A blockedDomains entry here unblocked the whole domain.

rulestring

The entry on the workspace blocklist that matches this address, exactly as it is stored.

liststring

blockedSenders for an address or pattern rule, blockedDomains for a rule that blocks a whole domain and every subdomain under it.

One of"blockedSenders""blockedDomains"

ContactCardobject

objectstringRequired
One of"contact_card"
idstringRequired
uidstringRequired

The vCard UID that phones and computers know the card by.

kindstringRequired

individual for a person or a company, group for a list of other cards, the groups phones keep.

One of"individual""group"
membersstring[]Required

For a group, the ids of the cards in it. Empty for everyone else.

emailstringRequired

The address of the saved contact this card belongs to, the one /contacts/{email} takes. null for a card with no address.

Can be null
namestringRequired

The full name.

Can be null
namePartsobjectRequired

The name in parts, when somebody set them or a phone sent them.

Can be null
prefixstringRequired

A title before the name, such as Dr.

Can be null
givenstringRequired

The first name.

Can be null
middlestringRequired

Any middle names.

Can be null
familystringRequired

The surname.

Can be null
suffixstringRequired

Anything after the name, such as Jr.

Can be null
nicknamestringRequired

A nickname.

Can be null
organizationstringRequired

The company or organisation.

Can be null
departmentstringRequired

The department within the organisation.

Can be null
titlestringRequired

The job title.

Can be null
birthdaystringRequired

YYYY-MM-DD, or --MM-DD when the year is not known.

Can be null
notesstringRequired

Free-form notes.

Can be null
emailsContactCardValue[]Required

Other email addresses, besides email.

phonesContactCardValue[]Required
addressesContactCardAddress[]Required
urlsContactCardValue[]Required

Websites and profile links.

photoUrlstringRequired

Where the contact photo is served, or null when there is none.

Can be null
createdAtstringRequired
Formatdate-time
updatedAtstringRequired
Formatdate-time

ContactCardAddressobject

labelstringRequired

What the entry is for.

One of"home""work""mobile""main""fax""pager""other"
customLabelstringRequired

A label of your own, such as Assistant, shown instead of label where the address book supports it.

Can be null
streetstringRequired

The street and house number.

Can be null
localitystringRequired

The city or town.

Can be null
regionstringRequired

The state, county or province.

Can be null
postalCodestringRequired

The postal code.

Can be null
countrystringRequired

The country.

Can be null

ContactCardDuplicateGroupobject

objectstringRequired
One of"contact_card_duplicates"
reasonstringRequired

The strongest thing the cards share: an email address, a phone number or the full name.

One of"email""phone""name"
cardsContactCard[]Required

The cards, the most complete one first.

ContactCardDuplicateListobject

objectstring
One of"list"
hasMoreboolean

True when there are more than 100 groups. Merge these and ask again for the rest.

ContactCardListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

The id of the last row on this page, or null on the last page.

Can be null

ContactCardValueobject

valuestringRequired

The address, number or link.

labelstringRequired

What the entry is for.

One of"home""work""mobile""main""fax""pager""other"
customLabelstringRequired

A label of your own, such as Assistant, shown instead of label where the address book supports it.

Can be null

ContactDetailobject

objectstring
One of"contact"
emailstring

Trimmed and lower cased on write. This is the key every contact route takes, because no contact id is exposed.

namestring
Can be null
sourcestring

auto when a send from the app composer recorded the address, manual when somebody saved it here or in the app. A recorded send never downgrades a manual contact to auto.

One of"manual""auto""form"
notesstring
Can be null
attributesRecord<string, string>

The custom fields of the contact, as an object of keys and text values, at most 50 of them. Empty when it has none. An automation reads one as attributes.<key>, in an email value, a branch or a trigger filter, and its update_field step writes one.

photoUrlstring

Where the contact photo is served, or null when the contact has none. Set it with PUT /contacts/{email}/photo. A new upload gets a new URL.

Can be null
lastSeenAtstring

When mail last went to this address from the app composer. Null until it does.

Can be nullFormatdate-time
createdAtstring
Formatdate-time
updatedAtstring
Formatdate-time
audiencesobject[]

Every audience this contact is in, the built-in default one included. Single-contact responses carry it; the list route does not.

idstring

The audience handle, aud_ plus 24 hex.

namestring
builtinstring

default on the one audience every contact joins, null on an audience somebody created.

Can be nullOne of"default"
signUpsContactSignUp[]

What this address sent through the workspace's sign-up forms, newest first and at most 20. Present only when the caller holds forms:read, and an empty list when the address never signed up. The workspace owner sees every form's sign-ups, and anybody else those of the forms they made. Single-contact responses carry it; the list route does not.

ContactImportobject

objectstringRequired
One of"contact_import"
idstringRequired

iimp_ followed by 24 hex characters.

kindstringRequired
One of"contacts"
sourcestringRequired

file is an upload. The others came with a mailbox import: takeout from a Google Takeout archive, caldav and carddav from the old provider, microsoft from an Outlook sign-in.

One of"file""takeout""caldav""carddav""microsoft"
statusstringRequired

undone means what it brought in was removed again.

One of"uploading""queued""running""completed""failed""cancelled""undone"
fileNamestringRequired
Can be null
fileBytesintegerRequired
At least 0
parentImportIdstringRequired

The mailbox import it came with, when there was one.

Can be null
countsobjectRequired
totalintegerRequired

Items found so far.

At least 0
importedintegerRequired

Items added.

At least 0
mergedintegerRequired

Contacts left as they were because the address book already holds them. Always 0 on a calendar import, where an event that is already here is counted under skipped.

At least 0
skippedintegerRequired

Items left out for a reason given in report.

At least 0
failedintegerRequired
At least 0
reportobjectRequired
collectionsobject[]Required

The calendars or address books the items came from, by their original name.

namestringRequired
itemsintegerRequired
At least 0
skippedRecord<string, integer>Required

How many items were left out, by reason.

samplesobject[]Required

Up to 20 of the items left out.

namestringRequired
reasonstringRequired
One of"uid-taken""no-start""duplicate""limit""invalid""empty"
lastErrorstringRequired
Can be null
undoablebooleanRequired

Whether the undo call would remove anything.

createdAtstringRequired
Formatdate-time
startedAtstringRequired
Can be nullFormatdate-time
finishedAtstringRequired
Can be nullFormatdate-time
undoneAtstringRequired
Can be nullFormatdate-time

ContactImportListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

An opaque cursor for the next page, or null on the last page. Pass it back unchanged.

Can be null

ContactListobject

objectstring
One of"list"
hasMoreboolean
nextCursorstring
Can be null

ContactSignUpobject

idstring

The submission id, fsb_ plus 24 hex. GET /forms/{id}/submissions/{submissionId} reads it whole.

formIdstring

The form the person filled in, frm_ plus 24 hex.

formNamestring

What the workspace calls that form.

statusstring

added once the person is a contact in the audiences. pending while a double opt-in form waits for them to confirm.

One of"pending""added"
answersContactSignUpAnswer[]

A snapshot of every answer, kept as it was even after the form changes.

sourceUrlstring

The page the form was filled in on, its origin and path only, when it was known.

Can be null
createdAtstring

When the person sent the form.

Formatdate-time
confirmedAtstring

When the person joined the audiences. Null while pending.

Can be nullFormatdate-time

ContactSignUpAnswerobject

keystring

The field key the value was posted under.

labelstring

The field label when the person signed up.

typestring

The kind of field that was answered.

One of"email""text""textarea""number""phone""url""date""select""radio""checkboxes""checkbox""consent""audiences""hidden""heading""paragraph""divider"
valuestring | string[] | boolean

Text for most fields, a list for multiple choice, true or false for a checkbox.

displaystring

The value as a person reads it, option labels included.

ContactThreadobject

objectstring
One of"thread"
idstring

The id GET /threads/{id} takes.

subjectstring
Can be null
fromobject

Who sent the newest message.

Can be null
namestring
Can be null
emailstring
receivedAtstring

When the newest message arrived or went out.

Can be null
messageCountinteger
hasUnreadboolean
labelsobject[]
idstring
namestring

ContactThreadListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

Opaque. Pass it back as cursor for the next page, and never build one yourself.

Can be null

DeletedContactobject

objectstring
One of"contact"
emailstring
deletedboolean
One oftrue
wasSavedboolean

True when a saved contact was removed, false when the address was only seen in mail and has now been hidden.

DeletedContactCardobject

objectstringRequired
One of"contact_card"
idstringRequired
deletedbooleanRequired
One oftrue

Personobject

objectstring
One of"person"
emailstring

Lower cased. The key every contact route takes.

displayEmailstring

The address as the most recent message wrote it, which may carry capitals.

namestring

The saved name, or else the newest display name seen in mail.

Can be null
savedboolean

True when the address is a saved contact.

sourcestring

As on a contact, or null when the address is only seen in mail.

Can be nullOne of"manual""auto""form"
notesstring
Can be null
attributesRecord<string, string>

The custom fields of the saved contact, as on a contact. Empty when the address is only seen in mail or has none.

photoUrlstring
Can be null
threadsinteger

How many threads have this address as the sender or a recipient of their newest message. Null when the key does not read mail or the address has never been seen in it.

Can be null
lastAtstring

When the newest of those threads last moved. Null for a saved contact never seen in mail.

Can be nullFormatdate-time
createdAtstring
Can be nullFormatdate-time
updatedAtstring
Can be nullFormatdate-time
blockedByobject

The workspace blocklist rule that blocks this address, or null when none does.

Can be null
rulestring

The entry on the workspace blocklist that matches this address, exactly as it is stored.

liststring

blockedSenders for an address or pattern rule, blockedDomains for a rule that blocks a whole domain and every subdomain under it.

One of"blockedSenders""blockedDomains"

PersonListobject

objectstring
One of"list"
hasMoreboolean

True when another page follows. Pass nextCursor back as cursor to read it.

nextCursorstring

Opaque. Pass it back as cursor for the next page, and never build one yourself.

Can be null
seenboolean

True when the addresses seen in mail are included, which needs threads:read. False means the rows are the saved contacts alone.