Skip to the documentation
CLI

nextmail contacts

Every command in this namespace, with its arguments, flags and examples.

Commands

The workspace address book: people it has written to, plus anybody you save yourself.

Every command here also takes the global flags, such as --json, --profile and --dry-run. See the global flags

nextmail contacts list

List the workspace contacts, most recently seen first

Scopescontacts:readNeeds a sign-inAliasesls

Usage

nextmail contacts list [flags]

Returns one page of the workspace address book, ordered by lastSeenAt with the most recent first and contacts that have never been mailed last. source says where a row came from: manual for a contact somebody saved, in the app or through create, and auto for an address recorded when a member sent mail to it from the app composer. A saved contact stays manual when it is mailed later.

--source narrows the page to one origin, so { source: 'manual' } is the contacts somebody saved on purpose and { source: 'auto' } the ones the composer recorded. --q searches the name and the address.

This lists saved contacts only. listPeople lists everyone the Contacts page in the app shows, the addresses seen in mail included, with thread counts.

Paging is keyset. --limit takes 1 to 200 and defaults to 50, and nextCursor goes back as --cursor while hasMore is true. Never build a cursor yourself.

Contacts belong to the whole workspace rather than to any one address, so a key limited to particular addresses or domains reads and writes the same book as every other key. An app connected by a member who reaches only some addresses is refused with 422 capability_unsupported on addressAllowlist, on every contacts, audiences and broadcasts route.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.

Flags

--limit <n>

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

Default50
--cursor <value>

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

--source <value>

manual, auto or form. Leave it out for the whole book.

--q <value>

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

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

nextmail contacts list
With optional flags
nextmail contacts list --limit 200 --source manual
Walk every page and stop after 100 items
nextmail contacts list --all --max 100
One JSON object per line when piped
nextmail contacts list --all > contacts.ndjson

Also available in

API
GET /contacts
TypeScript
nextmail.contacts.list()
Python
contacts.list()
Ruby
contacts.list
PHP
contacts->list
Go
Contacts.List
Java
contacts().list
C#
Contacts.ListAsync

nextmail contacts get

Read one contact by email address

Scopescontacts:readNeeds a sign-inAliasesshowview

Usage

nextmail contacts get <email> [flags]

Looks up a contact by address in the workspace address book. The address is trimmed and lower cased before the lookup, so Grace@Example.com finds grace@example.com, and the SDK URL encodes it for the path.

A 404 means only that the address is not in the book. It says nothing about whether mail has been exchanged with it, since received mail never creates contacts.

Arguments

<email>Required

The contact's address, matched case insensitively.

Examples

nextmail contacts get grace@example.com
Print the raw JSON
nextmail contacts get grace@example.com --json

Also available in

API
GET /contacts/{email}
TypeScript
nextmail.contacts.get()
Python
contacts.get()
Ruby
contacts.get
PHP
contacts->get
Go
Contacts.Get
Java
contacts().get
C#
Contacts.GetAsync

nextmail contacts create

Save a contact in the workspace address book

Scopescontacts:writeNeeds a sign-inAliasesnewadd

Usage

nextmail contacts create --email <value> [flags]
nextmail contacts create --data <json|@file|-> [flags]

Adds one address to the workspace address book and returns the saved row. email is trimmed and lower cased before it is stored, so Grace@Example.com and grace@example.com are the same contact.

The contact is saved with source set to manual, the same value a contact typed into the app carries, and it joins the default audience as it is written. Every contact is in that audience for as long as it exists, so there is nothing to add afterwards. Name audiences of your own in --audience-ids to put it in them in the same call, or add it later with audiences.addContact. Sending --audience-ids also requires the audiences:write scope, since it writes memberships as well as a contact.

An address can be in the book once. A second create for an address that is already there is refused with 409 contact_exists rather than merged, so a retry cannot quietly overwrite a name somebody edited in the app. Read the existing row with get and change it with update.

Flags

--email <value>

The address to save, trimmed and lower cased before it is stored. Required, here or in --data.

--name <value>

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

--notes <value>

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

--attributes <json|@file|->

Custom fields to set, as an object of keys and text values such as { plan: 'team' }. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of up to 500 characters, trimmed before it is stored. Null removes a field, a field you leave out keeps its value, and a contact holds at most 50. JSON shaped as Record<string, string | null>, inline or from a file with @path.

--audience-ids <a,b>Repeatable

Up to 25 audience ids to put the new contact in. The default audience is joined whether or not it is named. When this is present the key also needs audiences:write, or the call is refused with 403 before anything is saved.

--data <json|@file|->

The whole body as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

The required values only
nextmail contacts create --email grace@example.com
With optional flags
nextmail contacts create --email grace@example.com --name 'Grace Hopper' --notes 'Met at the compiler workshop'
Read the whole body from a JSON file
nextmail contacts create --data @contact.json

Also available in

API
POST /contacts
TypeScript
nextmail.contacts.create()
Python
contacts.create()
Ruby
contacts.create
PHP
contacts->create
Go
Contacts.Create
Java
contacts().create
C#
Contacts.CreateAsync

nextmail contacts update

Change a contact's name, notes or custom fields

Scopescontacts:writeNeeds a sign-inAliasesedit

Usage

nextmail contacts update <email> [flags]

Changes the fields you send and leaves the rest alone. A key you leave out keeps its stored value, and an explicit null clears it, so { notes: null } empties the notes while {} changes nothing. attributes is merged key by key: a string sets a custom field, null removes one and the fields you do not name are kept.

The address cannot be changed. It is the contact's identity, its path segment and the unique key of the book, so moving a contact to a new address is a delete and a create, and that new contact starts with no audience membership beyond the default one.

source and lastSeenAt are the server's to set and are not accepted here. A contact recorded automatically stays auto after you give it a name.

Arguments

<email>Required

The contact's address, matched case insensitively.

Flags

--name <value>

New display name. Null clears it.

--notes <value>

New notes. Null clears them.

--attributes <json|@file|->

Custom fields to set, as an object of keys and text values such as { plan: 'team' }. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of up to 500 characters, trimmed before it is stored. Null removes a field, a field you leave out keeps its value, and a contact holds at most 50. JSON shaped as Record<string, string | null>, inline or from a file with @path.

--data <json|@file|->

The whole patch as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

With optional flags
nextmail contacts update grace@example.com --name 'Grace Hopper'
Print the raw JSON
nextmail contacts update grace@example.com --name 'Grace Hopper' --json

Also available in

API
PATCH /contacts/{email}
TypeScript
nextmail.contacts.update()
Python
contacts.update()
Ruby
contacts.update
PHP
contacts->update
Go
Contacts.Update
Java
contacts().update
C#
Contacts.UpdateAsync

nextmail contacts delete

Delete somebody from the contacts and hide the address

Scopescontacts:writeNeeds a sign-in
Asks you to confirm
Aliasesrmdelremove

Usage

nextmail contacts delete <email> [flags]

Does what Delete does on the Contacts page in the app. A saved contact goes with its notes, its photo and every audience it was in, the default one included. The address is then hidden: listPeople leaves it out, and mail sent to it from the app composer no longer records it as a contact. The address can be one that was only ever seen in mail, which is how you take somebody off the people list, and wasSaved says which it was.

Nothing else moves: the mail exchanged with the address stays in the mailbox, and the address can still be written to. There is no undo. create or save afterwards brings the address back as a new contact with no name, no notes and no membership beyond the default audience.

Arguments

<email>Required

The contact's address, matched case insensitively.

Examples

nextmail contacts delete grace@example.com
Skip the confirmation, for scripts
nextmail contacts delete grace@example.com --yes

Also available in

API
DELETE /contacts/{email}
TypeScript
nextmail.contacts.delete()
Python
contacts.delete()
Ruby
contacts.delete
PHP
contacts->delete
Go
Contacts.Delete
Java
contacts().delete
C#
Contacts.DeleteAsync

nextmail contacts set-audiences

Set exactly which audiences a contact is in

Scopesaudiences:writeNeeds a sign-in

Usage

nextmail contacts set-audiences <email> --audience-ids <a,b> [flags]
nextmail contacts set-audiences <email> --data <json|@file|-> [flags]

Makes the contact's audiences match the list you send, 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, and memberships it keeps keep their addedAt.

The default audience is always kept, whether or not you name it, so { audienceIds: [] } leaves the contact in the default audience alone. To add or remove one audience without restating the rest, use audiences.addContact or audiences.removeContact.

The address is trimmed and lower cased, the SDK URL encodes it for the path, and it has to be a contact already: an address that is not in the book is a 404 contact_not_found on email. Create it with create, which takes --audience-ids too. An id that is not an audience of this workspace is a 404 audience_not_found on --audience-ids, and nothing is changed.

Arguments

<email>Required

The contact's address, matched case insensitively.

Flags

--audience-ids <a,b>Repeatable

Every audience the contact should be in, up to 100 ids. A repeated id counts once. More than 100 is a 422 invalid_parameter on --audience-ids, and an empty id is the same error on that entry, such as audienceIds.0. Required, here or in --data.

--data <json|@file|->

The whole body as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

nextmail contacts set-audiences grace@example.com --audience-ids aud_9f2c4b7e1a0d63d84c5f2e7b,aud_1c4e7a9b2d0f36e85a7c1b4d
Read the whole body from a JSON file
nextmail contacts set-audiences grace@example.com --data @contact.json

Also available in

API
PUT /contacts/{email}/audiences
TypeScript
nextmail.contacts.setAudiences()
Python
contacts.set_audiences()
Ruby
contacts.set_audiences
PHP
contacts->setAudiences
Go
Contacts.SetAudiences
Java
contacts().setAudiences
C#
Contacts.SetAudiencesAsync

nextmail contacts list-people

List everyone on the Contacts page, saved or seen in mail

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts list-people [flags]

Returns one page of the people the Contacts page in the app lists: the saved contacts, and every address seen in mail as the sender or a recipient of a thread's newest message. Each row says whether it is saved, how many threads it shares with the mailbox and when mail last moved (lastAt). A person seen in mail and saved is one row. list is the saved contacts alone.

The addresses seen in mail are included only when the key also holds threads:read, because they are read out of the mail. Without it the page holds the saved contacts and seen is false. Deleted addresses and the mailbox's own addresses are never listed.

sort is recent, newest mail first and saved contacts never seen in mail after them, name, by name or else by address, ignoring case, or threads, most threads first. blockedBy on each row names the workspace blocklist rule that blocks it, and blocked: true narrows the page to those rows.

Paging is keyset. --limit takes 1 to 100 and defaults to 25, and nextCursor goes back as --cursor, with the same sort, q and blocked, while hasMore is true.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one JSON document with --json, shaped as Returns describes. --max <n> stops after that many items.

Flags

--q <value>

Searches names, addresses and notes, up to 200 characters. When nothing matches exactly on the first page, close spellings are returned instead.

--email <value>

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

--sort <value>

recent (the default), name or threads.

Default"recent"
--blocked

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

--limit <n>

Rows per page, 1 to 100. The server defaults to 25.

Default25
--cursor <value>

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

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

nextmail contacts list-people
With optional flags
nextmail contacts list-people --sort threads --limit 50
Walk every page and stop after 100 items
nextmail contacts list-people --all --max 100
One JSON object per line when piped
nextmail contacts list-people --all > contacts.ndjson

Also available in

API
GET /contacts/people
TypeScript
nextmail.contacts.listPeople()
Python
contacts.list_people()
Ruby
contacts.list_people
PHP
contacts->listPeople
Go
Contacts.ListPeople
Java
contacts().listPeople
C#
Contacts.ListPeopleAsync

nextmail contacts save

Save an address as a contact, or keep one that was recorded

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts save <email> [flags]

Does what Add to contacts and Keep in contacts do in the app, and is safe to call whatever state the address is in. An address that is not a contact yet becomes one with source manual. A contact recorded from a send becomes manual. A contact already saved keeps what it has. A deleted address is brought back.

--name replaces the stored name and leaving it out keeps it. --notes replaces the stored notes and null clears them. --attributes sets the custom fields it names and keeps the rest. Unlike create, an address already in the book is not an error, and unlike update, an address not in the book is not one either.

Arguments

<email>Required

The address, trimmed and lower cased on the server.

Flags

--name <value>

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

--notes <value>

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

--attributes <json|@file|->

Custom fields to set, as an object of keys and text values such as { plan: 'team' }. A key starts with a letter and holds up to 64 letters, digits and underscores, and a value is text of up to 500 characters, trimmed before it is stored. Null removes a field, a field you leave out keeps its value, and a contact holds at most 50. JSON shaped as Record<string, string | null>, inline or from a file with @path.

--data <json|@file|->

The whole body as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

The required values only
nextmail contacts save grace@example.com
With optional flags
nextmail contacts save grace@example.com --name 'Grace Hopper'

Also available in

API
PUT /contacts/{email}
TypeScript
nextmail.contacts.save()
Python
contacts.save()
Ruby
contacts.save
PHP
contacts->save
Go
Contacts.Save
Java
contacts().save
C#
Contacts.SaveAsync

nextmail contacts delete-many

Delete up to 200 contacts in one call

Scopescontacts:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail contacts delete-many <emails...> [flags]

Deletes every address in emails the way delete deletes one: a saved contact goes with its notes, its photo and every audience membership, and every address is hidden, so mail sent to it from the app composer 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. A repeated address counts once. There is no undo.

Arguments

<emails...>RequiredOne or more

1 to 200 addresses, matched case insensitively. More than 200, or none, is a 422 on emails.

Examples

nextmail contacts delete-many ada@example.com grace@example.com
Skip the confirmation, for scripts
nextmail contacts delete-many ada@example.com grace@example.com --yes

Also available in

API
POST /contacts/batch-delete
TypeScript
nextmail.contacts.deleteMany()
Python
contacts.delete_many()
Ruby
contacts.delete_many
PHP
contacts->deleteMany
Go
Contacts.DeleteMany
Java
contacts().deleteMany
C#
Contacts.DeleteManyAsync

nextmail contacts set-photo

Upload the photo shown for a contact

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts set-photo <email> <data> [flags]

Sends the image bytes as the request body, replacing any photo the contact had. PNG, JPEG, WebP and GIF are accepted, up to 5 MB. The server fits the image into a 512 pixel square, stores it as WebP, keeps the first frame of an animation, and answers with the contact and its new photoUrl.

data is a Blob, an ArrayBuffer or a Uint8Array. The type is read from --content-type, or from a Blob's own type when that is left out. Without either the bytes go as application/octet-stream and the server refuses them with 422 invalid_image.

The address has to be a saved contact already: save it first.

Arguments

<email>Required

The contact's address, matched case insensitively.

<data>Required

The image: a Blob, ArrayBuffer or Uint8Array.

Flags

--content-type <value>

image/png, image/jpeg, image/webp or image/gif. Required unless data is a Blob with a type.

Examples

The required values only
nextmail contacts set-photo grace@example.com ./photo.jpg
With optional flags
nextmail contacts set-photo grace@example.com ./photo.jpg --content-type image/jpeg

Also available in

API
PUT /contacts/{email}/photo
TypeScript
nextmail.contacts.setPhoto()
Python
contacts.set_photo()
Ruby
contacts.set_photo
PHP
contacts->setPhoto
Go
Contacts.SetPhoto
Java
contacts().setPhoto
C#
Contacts.SetPhotoAsync

nextmail contacts remove-photo

Remove a contact photo

Scopescontacts:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail contacts remove-photo <email> [flags]

Takes the photo off the contact and deletes the stored image, the way Remove does on a contact in the app. The contact answers with photoUrl null. Removing a photo from a contact that has none changes nothing.

Arguments

<email>Required

The contact's address, matched case insensitively.

Examples

nextmail contacts remove-photo grace@example.com
Skip the confirmation, for scripts
nextmail contacts remove-photo grace@example.com --yes

Also available in

API
DELETE /contacts/{email}/photo
TypeScript
nextmail.contacts.removePhoto()
Python
contacts.remove_photo()
Ruby
contacts.remove_photo
PHP
contacts->removePhoto
Go
Contacts.RemovePhoto
Java
contacts().removePhoto
C#
Contacts.RemovePhotoAsync

nextmail contacts block

Block an address

Scopessettings:writeNeeds a sign-in

Usage

nextmail contacts block <email> [flags]

Puts the address on the workspace blocklist, the same list settings.update edits as blockedSenders, so mail from it is refused from then on. This is Block on a contact in the app. A plus tag is dropped: blocking ada+news@example.com blocks ada@example.com, and every tag of it.

When a rule already blocks the address, a whole-domain rule included, nothing is added: created is false and blockedBy names that rule. The address does not have to be a contact.

Arguments

<email>Required

The address to block.

Examples

nextmail contacts block spammer@example.com
Print the raw JSON
nextmail contacts block spammer@example.com --json

Also available in

API
POST /contacts/{email}/block
TypeScript
nextmail.contacts.block()
Python
contacts.block()
Ruby
contacts.block
PHP
contacts->block
Go
Contacts.Block
Java
contacts().block
C#
Contacts.BlockAsync

nextmail contacts unblock

Unblock an address

Scopessettings:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail contacts unblock <email> [flags]

Takes every workspace blocklist rule that blocks the address off the list and lists them in removed. This is Unblock on a contact in the app.

When one of them is a whole-domain rule, in blockedDomains, everybody at that domain is unblocked with it, so check removed when that matters. Rules set for one address or one domain in the settings are not touched. An address that no rule blocks answers with removed empty.

Arguments

<email>Required

The address to unblock.

Examples

nextmail contacts unblock friend@example.com
Skip the confirmation, for scripts
nextmail contacts unblock friend@example.com --yes

Also available in

API
DELETE /contacts/{email}/block
TypeScript
nextmail.contacts.unblock()
Python
contacts.unblock()
Ruby
contacts.unblock
PHP
contacts->unblock
Go
Contacts.Unblock
Java
contacts().unblock
C#
Contacts.UnblockAsync

nextmail contacts list-threads

List the conversations with one person

Scopesthreads:readNeeds a sign-in

Usage

nextmail contacts list-threads <email> [flags]

Returns one page of the threads the address wrote or was written to, in every folder: the Mail tab on a contact in the app. Each row is a summary, subject, from, receivedAt, messageCount, hasUnread and labels, and threads.get reads the messages behind its id.

--limit takes 1 to 100 and defaults to 25. Pass nextCursor back as --cursor, with the same q and sort, while hasMore is true.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.

Arguments

<email>Required

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

Flags

--q <value>

Searches inside those threads, with the mailbox search syntax, up to 200 characters.

--sort <value>

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

Default"newest"
--limit <n>

Threads per page, 1 to 100. The server defaults to 25.

Default25
--cursor <value>

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

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

The required values only
nextmail contacts list-threads ada@example.com
With optional flags
nextmail contacts list-threads ada@example.com --q invoice
Walk every page and stop after 100 items
nextmail contacts list-threads ada@example.com --all --max 100
One JSON object per line when piped
nextmail contacts list-threads ada@example.com --all > contacts.ndjson

Also available in

API
GET /contacts/{email}/threads
TypeScript
nextmail.contacts.listThreads()
Python
contacts.list_threads()
Ruby
contacts.list_threads
PHP
contacts->listThreads
Go
Contacts.ListThreads
Java
contacts().listThreads
C#
Contacts.ListThreadsAsync

nextmail contacts activity

Read how mail with one person has gone over a window

Scopesthreads:readNeeds a sign-in

Usage

nextmail contacts activity <email> [flags]

Returns the numbers behind the Activity tab on a contact in the app, over a window that ends now: messages received from the address and sent to it per bucket, the threads that moved, the threads whose newest message is theirs and so waits on a reply from the mailbox, when each side last wrote, and the median time each side takes to answer, in milliseconds.

--minutes sets how far back the window reaches, 90 days by default. grain sets the bucket width and the key shape, YYYY-MM-DD, YYYY-MM-DDTHH or YYYY-MM-DDTHH:MM, and --offset-minutes shifts the boundaries so days break where the reader's day does. buckets is sparse and oldest first. Mail in the bin or in spam is left out.

Arguments

<email>Required

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

Flags

--minutes <n>

Window length in minutes, from 1 to about 20 years. The server defaults to 90 days.

Default129600
--grain <value>

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

Default"day"
--offset-minutes <n>

Minutes east of UTC to cut the buckets in, from -840 to 840, defaulting to 0. Pass -new Date().getTimezoneOffset() for the local zone.

Default0

Examples

nextmail contacts activity ada@example.com
Print the raw JSON
nextmail contacts activity ada@example.com --json

Also available in

API
GET /contacts/{email}/activity
TypeScript
nextmail.contacts.activity()
Python
contacts.activity()
Ruby
contacts.activity
PHP
contacts->activity
Go
Contacts.Activity
Java
contacts().activity
C#
Contacts.ActivityAsync

nextmail contacts list-events

List the events recorded for one contact

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts list-events <email> [flags]

Returns one page of the events events.send recorded for a contact in the last 90 days, the most recent first by when they happened. Each has its name, properties, occurredAt and mode, which is test for an event a test key sent.

--limit takes 1 to 200 and defaults to 50. Pass nextCursor back as --cursor, with the same name, while hasMore is true.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.

Arguments

<email>Required

The contact, by email address, compared without case. The contactId an event or an enrollment carries works here too.

Flags

--name <value>

Only events with exactly this name.

--limit <n>

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

Default50
--cursor <value>

The nextCursor from the previous page, passed back exactly as it came. One that names no event of this contact is a 400 invalid_cursor.

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

The required values only
nextmail contacts list-events ada@example.com
With optional flags
nextmail contacts list-events ada@example.com --name order.placed
Walk every page and stop after 100 items
nextmail contacts list-events ada@example.com --all --max 100
One JSON object per line when piped
nextmail contacts list-events ada@example.com --all > contacts.ndjson

Also available in

API
GET /contacts/{email}/events
TypeScript
nextmail.contacts.listEvents()
Python
contacts.list_events()
Ruby
contacts.list_events
PHP
contacts->listEvents
Go
Contacts.ListEvents
Java
contacts().listEvents
C#
Contacts.ListEventsAsync

nextmail contacts list-cards

List the address book as contact cards

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts list-cards [flags]

Returns one page of contact cards, newest first. A card is a saved contact with everything an address book keeps for it: phone numbers, other email addresses, postal addresses, websites, organisation, job title and birthday. Cards with no email address, such as a plumber saved on a phone, are listed too. It is the address book phones and computers sync over CardDAV.

--email finds the card of one saved contact, and --without-email lists only the cards with no address. An address that was only ever mailed, and never saved, has no card.

Paging is keyset. --limit takes 1 to 200 and defaults to 50, and nextCursor goes back as --cursor while hasMore is true.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.

Flags

--limit <n>

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

--cursor <value>

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

--email <value>

Only the card of the saved contact with this address.

--without-email

True lists only the cards that have no email address.

--kind <value>

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

--group-id <value>

Only the cards in the group with this id.

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

nextmail contacts list-cards
With optional flags
nextmail contacts list-cards --without-email
Walk every page and stop after 100 items
nextmail contacts list-cards --all --max 100
One JSON object per line when piped
nextmail contacts list-cards --all > contacts.ndjson

Also available in

API
GET /contacts/cards
TypeScript
nextmail.contacts.listCards()
Python
contacts.list_cards()
Ruby
contacts.list_cards
PHP
contacts->listCards
Go
Contacts.ListCards
Java
contacts().listCards
C#
Contacts.ListCardsAsync

nextmail contacts get-card

Get one contact card

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts get-card <id> [flags]

Resolves one card with everything it holds. To find the card of a saved contact by its address, list the cards with email.

Arguments

<id>Required

The card id, ccd_ and 24 characters, from listCards or getCard.

Examples

nextmail contacts get-card ccd_0123456789abcdef01234567
Print the raw JSON
nextmail contacts get-card ccd_0123456789abcdef01234567 --json

Also available in

API
GET /contacts/cards/{id}
TypeScript
nextmail.contacts.getCard()
Python
contacts.get_card()
Ruby
contacts.get_card
PHP
contacts->getCard
Go
Contacts.GetCard
Java
contacts().getCard
C#
Contacts.GetCardAsync

nextmail contacts create-card

Add a card to the address book

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts create-card [flags]

Adds a contact card. With email the card is a saved contact as well, the same one create 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.

Phones and computers that sync the address book over CardDAV get the new card on their next sync.

Flags

--email <value>

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

--name <value>

The full name the address book shows, up to 200 characters.

--name-parts <json|@file|->

The name in parts, { prefix, given, middle, family, suffix }, the way phones keep it. JSON shaped as ContactCardNameInput | null, inline or from a file with @path.

--nickname <value>

A nickname.

--organization <value>

The company or organisation.

--department <value>

The department within the organisation.

--title <value>

The job title.

--birthday <value>

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

--notes <value>

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

--emails <json|@file|->

Other email addresses besides email, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--phones <json|@file|->

Phone numbers, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--addresses <json|@file|->

Postal addresses, each { label?, customLabel?, street?, locality?, region?, postalCode?, country? }. JSON shaped as Array<ContactCardAddressInput>, inline or from a file with @path.

--urls <json|@file|->

Websites and profile links, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--kind <value>

group makes a group, the kind phones keep, which needs name and takes members instead of an address. individual when left out.

--members <a,b>Repeatable

For a group, the ids of the cards in it, up to 2,000. Groups cannot hold other groups.

--data <json|@file|->

The whole body as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

nextmail contacts create-card
With optional flags
nextmail contacts create-card --email ada@example.com --name 'Ada Lovelace' --organization 'Analytical Engines'

Also available in

API
POST /contacts/cards
TypeScript
nextmail.contacts.createCard()
Python
contacts.create_card()
Ruby
contacts.create_card
PHP
contacts->createCard
Go
Contacts.CreateCard
Java
contacts().createCard
C#
Contacts.CreateCardAsync

nextmail contacts update-card

Change a contact card

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts update-card <id> [flags]

Changes the fields you send and leaves the rest alone. null clears a field, and a list you send (emails, phones, addresses, urls) replaces the whole list, so read the card first when you mean to add one entry.

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: add another address to emails instead.

Arguments

<id>Required

The card id, ccd_ and 24 characters, from listCards or getCard.

Flags

--email <value>

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

--name <value>

The full name the address book shows, up to 200 characters.

--name-parts <json|@file|->

The name in parts, { prefix, given, middle, family, suffix }, the way phones keep it. JSON shaped as ContactCardNameInput | null, inline or from a file with @path.

--nickname <value>

A nickname.

--organization <value>

The company or organisation.

--department <value>

The department within the organisation.

--title <value>

The job title.

--birthday <value>

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

--notes <value>

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

--emails <json|@file|->

Other email addresses besides email, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--phones <json|@file|->

Phone numbers, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--addresses <json|@file|->

Postal addresses, each { label?, customLabel?, street?, locality?, region?, postalCode?, country? }. JSON shaped as Array<ContactCardAddressInput>, inline or from a file with @path.

--urls <json|@file|->

Websites and profile links, each { value, label?, customLabel? }. JSON shaped as Array<ContactCardValueInput>, inline or from a file with @path.

--kind <value>

What the card already is. A person cannot become a group or a group a person, so any other value is a 422 invalid_contact_card.

--members <a,b>Repeatable

For a group, the ids of the cards in it. Given, it replaces the whole list, so send the ids already in it with the ones you add.

--data <json|@file|->

The whole patch as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

nextmail contacts update-card ccd_0123456789abcdef01234567
Print the raw JSON
nextmail contacts update-card ccd_0123456789abcdef01234567 --json

Also available in

API
PATCH /contacts/cards/{id}
TypeScript
nextmail.contacts.updateCard()
Python
contacts.update_card()
Ruby
contacts.update_card
PHP
contacts->updateCard
Go
Contacts.UpdateCard
Java
contacts().updateCard
C#
Contacts.UpdateCardAsync

nextmail contacts delete-card

Delete a contact card

Scopescontacts:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail contacts delete-card <id> [flags]

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

Arguments

<id>Required

The card id, ccd_ and 24 characters, from listCards or getCard.

Examples

nextmail contacts delete-card ccd_0123456789abcdef01234567
Skip the confirmation, for scripts
nextmail contacts delete-card ccd_0123456789abcdef01234567 --yes

Also available in

API
DELETE /contacts/cards/{id}
TypeScript
nextmail.contacts.deleteCard()
Python
contacts.delete_card()
Ruby
contacts.delete_card
PHP
contacts->deleteCard
Go
Contacts.DeleteCard
Java
contacts().deleteCard
C#
Contacts.DeleteCardAsync

nextmail contacts find-duplicate-cards

Find duplicate contact cards

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts find-duplicate-cards [flags]

Finds the cards in the address book that look like the same person, as Find duplicates on the Contacts page of the app does: cards that share an email address or a phone number, or that have the same full name. Each group in data lists its cards with the most complete one first, which is the card to keep when you pass the rest to mergeCards.

Groups found by a shared address come first, then by phone number, then by name. Phone numbers match on their last nine digits, so +44 20 7946 0000 and 020 7946 0000 are the same number. Group cards are never compared.

Examples

nextmail contacts find-duplicate-cards
Print the raw JSON
nextmail contacts find-duplicate-cards --json

Also available in

API
GET /contacts/cards/duplicates
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

nextmail contacts merge-cards

Merge contact cards

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts merge-cards <id> --card-ids <a,b> [flags]
nextmail contacts merge-cards <id> --data <json|@file|-> [flags]

Folds other cards into the card id names and deletes them, as Merge does in Find duplicates on the Contacts page of the app. Fields the kept card leaves empty are filled from the others, notes are joined, and every email address, phone number, postal address and website is kept. Groups that held the other cards hold the kept one 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. When the kept card has no address of its own, it becomes the saved contact of the first address the others had. Phones and computers that sync the address book over CardDAV get the change on their next sync.

Arguments

<id>Required

The card to keep, from listCards, getCard or findDuplicateCards.

Flags

--card-ids <a,b>Repeatable

The cards to fold into it, 1 to 10 of them. They are deleted once their details are kept. Required, here or in --data.

--data <json|@file|->

The whole body as JSON, inline, from a file with @path, or - for standard input. Flags override its keys.

Examples

nextmail contacts merge-cards ccd_0123456789abcdef01234567 --card-ids first,second
Read the whole body from a JSON file
nextmail contacts merge-cards ccd_0123456789abcdef01234567 --data @contact.json

Also available in

API
POST /contacts/cards/{id}/merge
TypeScript
nextmail.contacts.mergeCards()
Python
contacts.merge_cards()
Ruby
contacts.merge_cards
PHP
contacts->mergeCards
Go
Contacts.MergeCards
Java
contacts().mergeCards
C#
Contacts.MergeCardsAsync

nextmail contacts list-birthdays

List birthdays

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts list-birthdays --from <when> --to <when> [flags]

Resolves the birthdays of the people in the address book that fall between from and to, the birthdays calendar the Calendar page of the app can show. There is one entry for each date, so a window of a whole year can hold somebody twice, and age is how old they turn that day when the card holds the year of birth. Somebody born on 29 February has their birthday on 28 February in other years.

from and to take a Date or an ISO 8601 string and may be at most 366 days apart. timezone, UTC unless you say, decides which day the window starts and ends on.

Flags

--from <when>

The start of the window. Required.

--to <when>

The end of the window, after from and at most 366 days later. Required.

--timezone <value>

IANA zone such as Europe/London, at most 64 characters. Defaults to UTC.

Default"UTC"

Examples

The required values only
nextmail contacts list-birthdays --from 2026-10-01T00:00:00Z --to 2026-10-31T23:59:59Z
With optional flags
nextmail contacts list-birthdays --from 2026-10-01T00:00:00Z --to 2026-10-31T23:59:59Z --timezone Europe/London

Also available in

API
GET /contacts/birthdays
TypeScript
nextmail.contacts.listBirthdays()
Python
contacts.list_birthdays()
Ruby
contacts.list_birthdays
PHP
contacts->listBirthdays
Go
Contacts.ListBirthdays
Java
contacts().listBirthdays
C#
Contacts.ListBirthdaysAsync

nextmail contacts import-vcf

Import a contacts file

Scopescontacts:writeNeeds a sign-in

Usage

nextmail contacts import-vcf <data> [flags]

Sends 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 getImport 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.

data is a Blob, an ArrayBuffer or a Uint8Array, and it goes out as text/vcard.

Arguments

<data>Required

The .vcf file: a Blob, ArrayBuffer or Uint8Array.

Flags

--filename <value>

The name to show for the file in the list of imports, at most 255 characters.

Examples

The required values only
nextmail contacts import-vcf ./contacts.vcf
With optional flags
nextmail contacts import-vcf ./contacts.vcf --filename contacts.vcf

Also available in

API
POST /contacts/imports
TypeScript
nextmail.contacts.importVcf()
Python
contacts.import_vcf()
Ruby
contacts.import_vcf
PHP
contacts->importVcf
Go
Contacts.ImportVcf
Java
contacts().importVcf
C#
Contacts.ImportVcfAsync

nextmail contacts list-imports

List contacts imports

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts list-imports [flags]

Returns one page of the contacts files and address books brought in, newest first, each with what it added and what it left out. Beside the files sent with importVcf it lists the address books that came with a mailbox import, and those carry the id of that import in parentImportId.

Paging is keyset. --limit takes 1 to 100 and defaults to 25, and nextCursor goes back as --cursor while hasMore is true.

Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.

Flags

--limit <n>

Imports per page, a whole number from 1 to 100. The server defaults to 25.

Default25
--cursor <value>

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

--all

Fetch every page and stream the items as they arrive.

--max <n>

Stop after this many items. Implies --all.

--ndjson

Print every item as one JSON object per line. Implies --all

Examples

nextmail contacts list-imports
With optional flags
nextmail contacts list-imports --limit 50
Walk every page and stop after 100 items
nextmail contacts list-imports --all --max 100
One JSON object per line when piped
nextmail contacts list-imports --all > contacts.ndjson

Also available in

API
GET /contacts/imports
TypeScript
nextmail.contacts.listImports()
Python
contacts.list_imports()
Ruby
contacts.list_imports
PHP
contacts->listImports
Go
Contacts.ListImports
Java
contacts().listImports
C#
Contacts.ListImportsAsync

nextmail contacts get-import

Get a contacts import

Scopescontacts:readNeeds a sign-in

Usage

nextmail contacts get-import <id> [flags]

Resolves 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. Poll it after importVcf until status is completed or failed.

counts.imported is what was added, counts.merged the cards left as they were because they were already in the address book, and counts.skipped what was left out, which report.skipped breaks down by reason: limit for a card past the 20,000 a workspace keeps, invalid for one that could not be read and empty for one that held nothing.

Arguments

<id>Required

Contacts import id, iimp_ followed by 24 hex characters.

Examples

nextmail contacts get-import iimp_7b1e4d8f60a5c7b92d3f9c2a
Print the raw JSON
nextmail contacts get-import iimp_7b1e4d8f60a5c7b92d3f9c2a --json

Also available in

API
GET /contacts/imports/{id}
TypeScript
nextmail.contacts.getImport()
Python
contacts.get_import()
Ruby
contacts.get_import
PHP
contacts->getImport
Go
Contacts.GetImport
Java
contacts().getImport
C#
Contacts.GetImportAsync

nextmail contacts undo-import

Remove what a contacts import added

Scopescontacts:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail contacts undo-import <id> [flags]

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.

Arguments

<id>Required

Contacts import id, iimp_ followed by 24 hex characters.

Examples

nextmail contacts undo-import iimp_7b1e4d8f60a5c7b92d3f9c2a
Skip the confirmation, for scripts
nextmail contacts undo-import iimp_7b1e4d8f60a5c7b92d3f9c2a --yes

Also available in

API
POST /contacts/imports/{id}/undo
TypeScript
nextmail.contacts.undoImport()
Python
contacts.undo_import()
Ruby
contacts.undo_import
PHP
contacts->undoImport
Go
Contacts.UndoImport
Java
contacts().undoImport
C#
Contacts.UndoImportAsync