Skip to the documentation
Python

nextmail.domains

Every method in this namespace: its signature, its parameters, what it returns and an example.

Methods

Custom domains attached to the workspace: add and remove them, read the DNS records to publish, check whether they can receive and send, manage their addresses and their photos, and set the catch-all, the tracking and files domains, the DMARC policy, the sender name and the brand logo.

domains.list()

List the workspace's domains and their receiving state

Scopesdomains:readPages through results
Signature
def list(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[DomainResource]

Returns one page of the domains added to the workspace, alphabetically by domain. list_all collects every page and iterate walks them lazily. receiving reports the inbound checks: verified is True once verifiedAt is set, catchAll is the domain's catch all setting, lastCheckedAt is the most recent check and error is the last verification failure.

receiving and sending are independent. A verified domain can receive mail, and that says nothing about whether outbound mail from it is signed. sending['status'] is the signing state as the last check saw it, one of verified, pending, failed, no_identity or unknown, sending['canSend'] says whether a send from the domain would be accepted right now, sending['checkedAt'] dates that verdict, and sending['error'] carries the last failure. A negative verdict older than a day is treated as unknown rather than as a refusal, so canSend can be True while status is pending.

tracking reports the domain's custom tracking domain, set with update, and only a tracking['status'] of active means tracked links and the open pixel in new mail from the domain use its host instead of the default Nextmail host. storage reports the domain's custom files domain the same way, and only a storage['status'] of active means the download links for files sent from the domain use its host.

Parameters

limitint

Page size, from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor of the previous page. Leave it out for the first page.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

Page[DomainResource], a dict with items, hasMore and nextCursor. Each item has id, domain, receiving, sending, tracking, storage, logo, dmarcPolicy, senderName and createdAt.

Example

from nextmail import nextmail page = nextmail.domains.list(limit=50) for domain in page['items']:    print(domain['domain'], domain['receiving']['verified'], domain['sending']['canSend']) if page['hasMore']:    following = nextmail.domains.list(limit=50, cursor=page['nextCursor'])    print(len(following['items']), 'more on the next page')

Notes

  • A narrowed key still sees every domain in the workspace, whether it is narrowed by whole domains or by individual addresses.

  • Addresses, DNS records and the DMARC reading are only on get. list_addresses pages through the addresses on one domain.

  • The cursor is opaque and holds where the last row sat in this order, so a row deleted or edited between pages never breaks the walk: the next page starts at the first row that sorts after it. A cursor this list did not hand out is a 400 invalid_cursor.

Also available in

API
GET /domains
TypeScript
nextmail.domains.list()
Ruby
domains.list
PHP
domains->list
Go
Domains.List
Java
domains().list
C#
Domains.ListAsync
CLI
nextmail domains list

domains.list_all()

Collect every domain into one list

Scopesdomains:readPages through results
Signature
def list_all(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[DomainResource]

Walks every page of list and returns all the domains as one list, alphabetically by domain. One request per page.

Parameters

limitint

Page size for each request, from 1 to 100. The server defaults to 25.

cursorstr

Starts the walk after this cursor instead of the first page.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

list[DomainResource] holding every domain.

Example

from nextmail import nextmail domains = nextmail.domains.list_all(limit=100)unverified = [domain for domain in domains if not domain['receiving']['verified']] for domain in unverified:    print(domain['domain'], domain['receiving']['error'] or 'waiting for DNS')

Notes

  • If any page fails, the call raises and the domains already fetched are discarded.

Also available in

API
GET /domains
TypeScript
nextmail.domains.listAll()
Ruby
domains.list_all
PHP
domains->listAll
Go
Domains.ListAll
Java
domains().listAll
C#
Domains.ListAllAsync

domains.iterate()

Stream the domains one at a time

Scopesdomains:readPages through results
Signature
def iterate(    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[DomainResource]

Returns a generator that yields the domains one at a time, alphabetically by domain, and requests the next page only once the current one is used up. Nothing is fetched until you start iterating, and breaking out of the loop stops the requests.

Parameters

limitint

Page size for each request, from 1 to 100. The server defaults to 25.

cursorstr

Starts the walk after this cursor instead of the first page.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

Iterator[DomainResource], a generator yielding one domain per step.

Example

from nextmail import nextmail for domain in nextmail.domains.iterate():    print(domain['domain'], domain['sending']['status'], domain['tracking']['status'])

Notes

  • The generator is lazy, so an abandoned loop costs only the pages you consumed.

Also available in

API
GET /domains
TypeScript
nextmail.domains.iterate()
Ruby
domains.iterate
PHP
domains->iterate
Go
Domains.Iterate
Java
domains().iterate
C#
Domains.IterateAsync

domains.get()

Read one domain with its addresses, DNS records and DMARC reading

Scopesdomains:read
Signature
def get(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDetailResource

Returns the same receiving and sending blocks as list, plus addresses: every address on the domain as a full lower cased address with its enabled flag. Disabled addresses are listed too. list_addresses returns the same addresses with their ids and labels. It also carries the tracking and storage blocks described on list, whose record is the CNAME record to add at your DNS provider for the tracking domain and for the files domain.

records is every DNS record the domain uses, each with type, name, value, priority on an MX record, a purpose written to be shown to a person, and status: found when the last check saw it in public DNS, missing when it did not, and None when it has not been checked yet. Publish each one exactly as given, since the values are specific to this domain. dmarc is the domain's DMARC record as public DNS has it, with its stage, any issues, and whether a policy stricter than p=none is safe yet. It is None until the domain is verified.

Reading an unverified domain checks its DNS again when the last check is more than 20 seconds old, so polling get is one way to wait for verification. verify checks straight away.

The id must belong to the calling workspace. Another workspace's domain id is a 404, the same as an id that does not exist, and the domain name is not accepted in its place.

Parameters

idstrRequired

Domain id from list, a UUID.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDetailResource, a DomainResource plus addresses, each a dict with address and enabled, records as a list of DomainRecordResource, and dmarc as a DomainDmarcResource or None.

Example

from nextmail import nextmail domain = nextmail.domains.get('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f')live = [entry['address'] for entry in domain['addresses'] if entry['enabled']] print(domain['domain'], domain['receiving']['verified'], live)

Notes

  • sending['canSend'] is the value to branch on before a send: when it is False, emails.send from this domain is refused with 409 domain_not_sendable.

  • A narrowed key still sees every address on the domain, whether it is narrowed by whole domains or by individual addresses.

Also available in

API
GET /domains/{id}
TypeScript
nextmail.domains.get()
Ruby
domains.get
PHP
domains->get
Go
Domains.Get
Java
domains().get
C#
Domains.GetAsync
CLI
nextmail domains get

domains.create()

Add a domain to the workspace

Scopesdomains:write
Signature
def create(    body: DomainCreate,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDetailResource

Adds a domain and returns it with every DNS record to publish, in the same shape as get. The first DNS check runs during the call, so the status of each entry in records already says what public DNS answers with.

The domain receives mail once public DNS answers with its MX records and its _openemail-challenge TXT record, and it can send once its signing records are in place. Publish every entry in records exactly as given, since the values are specific to this domain, then call verify or poll get until receiving['verified'] is True.

A new domain starts with its catch-all on and no addresses. Create addresses with create_address, or turn the catch-all off with update.

Parameters

body['domain']strRequired

A bare domain such as example.com. It is trimmed, lower cased and converted to its ASCII form, so an internationalised name is stored as punycode.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDetailResource: the new domain with addresses empty, records holding every DNS record to publish, and dmarc set to None until the domain is verified.

Example

from nextmail import nextmail domain = nextmail.domains.create({'domain': 'example.com'}) for record in domain['records']:    print(record['type'], record['name'], record['value'], record['priority'] or '')

Notes

  • How many domains you can add is set by the plan of the workspace, counted within that workspace. Past it the call is refused with 403 domain_allowance_reached, and the message says which plan includes more.

  • A domain you already added is 409 domain_already_added, one somebody else added is 409 domain_claimed, one whose parent or subdomain belongs to somebody else is 409 related_domain_owned, and one that belongs to Nextmail is 409 operator_domain. Anything that is not a hostname is 422 invalid_parameter on domain.

  • Adding a domain reaches the whole workspace, so a key or app limited to particular addresses or domains is refused with 422 capability_unsupported on domainAllowlist. Use a key with no address or domain restriction.

  • The SDK does not retry a create after a network failure. A second attempt after a lost response is refused with 409 domain_already_added, which means the first one worked: read the domain with list.

Also available in

API
POST /domains
TypeScript
nextmail.domains.create()
Ruby
domains.create
PHP
domains->create
Go
Domains.Create
Java
domains().create
C#
Domains.CreateAsync
CLI
nextmail domains create

domains.verify()

Check a domain's DNS now

Scopesdomains:write
Signature
def verify(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDetailResource

Checks the DNS of the domain straight away and returns it in the same shape as get. On an unverified domain it looks for the records that verify it, and receiving['verified'] comes back True when they are found. On a verified domain it checks the signing and return path records again and asks whether mail from the domain can be sent, so sending is fresh.

When the last check ran less than 10 seconds ago, nothing new is checked and the domain comes back as it stands, so calling it faster than that gains nothing. A record published a moment ago can take a few minutes to show up in public DNS.

Parameters

idstrRequired

Domain id from list or create, a UUID.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDetailResource as the check left it.

Example

import time from nextmail import nextmail domain = nextmail.domains.verify('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f') for _ in range(20):    if domain['receiving']['verified']:        break    waiting = [record['name'] for record in domain['records'] if record['status'] != 'found']    print(domain['receiving']['error'], waiting)    time.sleep(30)    domain = nextmail.domains.verify(domain['id'])

Notes

  • Reading an unverified domain with get also checks it again when its last check is more than 20 seconds old, so either call works for polling. verify needs domains:write and get needs only domains:read.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • A domain id from another workspace is a 404, the same as an id that does not exist.

  • Retried automatically on network failure and retryable statuses, since a repeated check changes nothing but the time of the check.

Also available in

API
POST /domains/{id}/verify
TypeScript
nextmail.domains.verify()
Ruby
domains.verify
PHP
domains->verify
Go
Domains.Verify
Java
domains().verify
C#
Domains.VerifyAsync
CLI
nextmail domains verify

domains.update()

Turn the catch-all on or off, set or remove the tracking and files domains, and set the DMARC policy and the sender name

Scopesdomains:write
Signature
def update(    id: str,    patch: DomainPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDetailResource

catchAll set to True accepts mail to any address on the domain that nobody created, and the address shows up in list_addresses from its first message on. False refuses mail to every address that was not created by hand, including the ones the catch-all picked up before. It applies to the whole domain, so only a key that holds the whole domain may change it.

trackingHost and storageHost set the two custom names a domain can carry once it is verified or its _openemail-challenge TXT record is published, each of them a subdomain of it. trackingHost, such as links.example.com, is the name tracked links and the open pixel use. storageHost, such as files.example.com, is the name the download links for files sent from the domain use. All five keys are optional and independent: a key left out is left alone, and for either host None or an empty string removes that name and a string sets it. A patch carrying none of them changes nothing and answers with the domain as it stands. Each value is trimmed and lower cased, and a leading https:// or http://, any path, query or fragment and any trailing dots are stripped.

A new host is validated, saved and checked in the same call, so the response already carries the result of that first check. trackingHost reports into the tracking block and storageHost into storage, and the two blocks carry the same fields. The check asks the host over HTTPS for an answer signed by Nextmail, on /t/v/<nonce> for a tracking domain and /f/v/<nonce> for a files domain, so the host needs a CNAME record named record['name'] with the value record['value'], with any proxying turned off. That value, also reported as target, is an address prepared for this host alone. When it could not be prepared during the call, record is None, target is an empty string and error says so, and it is finished within a few minutes without another call. Until a check passes, status is pending and new mail keeps using the default Nextmail host. Once one passes, status is active and new mail from the domain uses the host.

Sending a host the domain already has runs the check again, unless the last check was less than 30 seconds ago, in which case the stored state comes back unchanged. A different host replaces the current one at once, so new mail uses the default host until the new one passes a check. None or an empty string removes that name, and its block then reports status as none with host and record set to None.

dmarcPolicy is what the domain's DMARC record tells receivers to do with mail that fails its checks: none only monitors, quarantine sends it to spam and reject refuses it. Inboxes show the domain logo only at quarantine or reject, and where Nextmail writes the DNS for the domain the record is updated during the call, keeping its other tags such as rua, while elsewhere you publish the DMARC record records lists.

senderName is the name recipients see beside every address on the domain that has no name of its own, such as Acme Support. Mail sent without a name in from goes out under the name of the address, then this one, then the name of the workspace. It is trimmed, and None or a string that is empty once trimmed removes it.

Parameters

idstrRequired

Domain id from list, a UUID.

patch['catchAll']bool

True accepts mail to any address on the domain that nobody created, False refuses it. Leaving the key out leaves the catch-all alone.

patch['trackingHost']str | None

A subdomain of the domain of at most 512 characters, such as links.example.com. None or an empty string removes the tracking domain, and leaving the key out leaves it alone.

patch['storageHost']str | None

A subdomain of the domain of at most 512 characters, such as files.example.com. None or an empty string removes the files domain, and leaving the key out leaves it alone.

patch['dmarcPolicy']DomainDmarcPolicy

none, quarantine or reject. A policy stricter than none needs mail from the domain to be signed first. Leaving the key out leaves the policy alone.

patch['senderName']str | None

The name mail from the domain goes out under when the address has no name of its own, at most 120 characters once trimmed, such as Acme Support. None or an empty string removes it, and leaving the key out leaves it alone.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDetailResource, the same body as get, with receiving['catchAll'], tracking, storage, dmarcPolicy and senderName as they stand after the call.

Example

from nextmail import nextmail domain = nextmail.domains.update(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    {'trackingHost': 'links.example.com', 'storageHost': 'files.example.com'},) print(domain['tracking']['status'], domain['tracking']['record'], domain['tracking']['error'])print(domain['storage']['status'], domain['storage']['record'])

Notes

  • The host is refused with 422 invalid_tracking_host, or invalid_storage_host for the files domain, when it is not a hostname, is not a strict subdomain of the domain, is the return path host bounce.<domain>, belongs to Nextmail or is a domain set up to receive mail. A new host on a domain whose receiving['verified'] is False and whose _openemail-challenge TXT record is not published yet gets 409 domain_not_verified. The domain does not have to be receiving mail for a host to be accepted. A host another domain already uses gets 409 tracking_host_in_use or storage_host_in_use, and so does a host already in use for the other feature, since one name cannot be both. A dmarcPolicy stricter than none while sending['status'] is not verified gets 409 domain_not_sendable, since unsigned mail from the domain would then go to spam. Every refusal names the field it came from in the error's param, and a refused field changes nothing. The fields are applied in order, catchAll first, then trackingHost, then storageHost, then dmarcPolicy, then senderName, so a patch carrying more than one can have an earlier change saved before a later field is refused. Send them in separate calls when any of them has to stand on its own.

  • Every call on a domain whose tracking domain is managed by a different Nextmail server, removal included, gets 409 tracking_host_in_use until it is removed on that server. A files domain behaves the same way under storage_host_in_use.

  • A tracking domain and a files domain each apply to every address on the domain, so only a key that holds the whole domain may set one. A key whose domainAllowlist contains this domain is allowed through, and any other narrowed key gets 422 capability_unsupported on domainAllowlist. The catch-all, the DMARC policy and the sender name need the whole domain the same way. A body key other than catchAll, trackingHost, storageHost, dmarcPolicy and senderName is a 422 unknown_parameter, and a catchAll that is not a bool, a dmarcPolicy that is not one of the three policies, a senderName that is neither a str nor None or runs past 120 characters once trimmed, or a host key that is present but is neither a str nor None, or runs past 512 characters, is a 422 invalid_parameter. A body carrying none of the keys is not an error: it changes nothing and comes back 200.

  • Nextmail keeps checking on its own. A host that has not passed a check yet is checked every 2 minutes in its first hour, every 10 minutes in its first day, hourly in its first week and every 6 hours after that. An active host is checked every 10 minutes, and a failed check on it is retried after 1 minute and then 2. From the third failure in a row the wait starts at 4 minutes and doubles each time, up to an hour.

  • An active host that fails one or two checks in a row still reads active, with the reason in error. It stops being used after the third, or once its last successful check is 2 hours old. New mail then goes back to the default host, and status reads failed until a check passes again.

  • A tracking domain serves only tracking paths and a files domain serves only download paths, and each answers only for mail sent by the workspace that owns it.

  • Links in mail already sent keep the host they were sent with, and that covers the download link on a file as much as a tracked link. After removing or changing a name, those links work only for as long as the old CNAME record stays in place. Setting a host up again can give it a different record['value'], so publish the one the response reports.

  • Retried automatically on network failure and retryable statuses, since repeating a call that already went through finds the catch-all, the DMARC policy, the sender name and the hosts already set, or already removed, and at most checks a host again.

Also available in

API
PATCH /domains/{id}
TypeScript
nextmail.domains.update()
Ruby
domains.update
PHP
domains->update
Go
Domains.Update
Java
domains().update
C#
Domains.UpdateAsync
CLI
nextmail domains update

domains.delete()

Remove a domain from the workspace

Scopesdomains:write
Signature
def delete(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedDomainResource

Removes the domain. Mail to it stops being accepted and nothing can be sent from it. Every address on it goes with it, their password sign-ins are revoked, its signing key is released, its tracking and files domains are retired, and the domain.deleted webhook fires. Mail already received stays in the mailbox.

Where Nextmail wrote the DNS for this domain itself, it takes those records back, and any it could not take back are listed in leftBehind for you to remove at your DNS provider. Records you published yourself are never touched, so remove them too once the domain is gone.

There is no undo. Adding the domain again starts it from scratch.

Parameters

idstrRequired

Domain id from list or create, a UUID.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedDomainResource with object set to 'domain', id, domain, deleted set to True, and leftBehind, the DNS records that have to be removed by hand, one line each.

Example

from nextmail import nextmail removed = nextmail.domains.delete('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f') for line in removed['leftBehind']:    print('Remove by hand:', line)

Notes

  • The last domain in a workspace cannot be removed here, because in the app removing it deletes the whole mailbox with it. The call is refused with 409 last_domain. Remove it in the app, where that is confirmed first.

  • A domain that holds reserved account addresses is refused with 409 domain_holds_reserved_addresses.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • An access token acting for a member also needs workspace:manage in that member's role, as removing one in the app does. It is console-only, so no approval can give it to an app, and without it the call is refused with 403 insufficient_authority.

  • The SDK does not retry a delete. A 404 on your own second attempt after a lost response means the first one worked.

Also available in

API
DELETE /domains/{id}
TypeScript
nextmail.domains.delete()
Ruby
domains.delete
PHP
domains->delete
Go
Domains.Delete
Java
domains().delete
C#
Domains.DeleteAsync
CLI
nextmail domains delete

domains.set_logo_certificate()

Upload the mark certificate for a domain logo

Scopesdomains:write
Signature
def set_logo_certificate(    id: str,    body: DomainLogoCertificateSet,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainLogoChangeResource

Stores the Verified Mark Certificate (VMC) or Common Mark Certificate (CMC) a certificate authority issued for the domain, replacing any there was, and points the BIMI record at it. Gmail shows the logo only with one and Apple Mail only with a VMC, and when the logo inside the certificate differs from the published one, it becomes the published one and logoFromCertificate is True.

Parameters

idstrRequired

Domain id from list or create, a UUID.

body['certificate']strRequired

The file the certificate authority sent as a str, up to 128 KB: PEM text as it came, which can hold the whole chain, or a DER or PKCS #7 file encoded as base64, which to_base64 does for bytes.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainLogoChangeResource with certificate, a dict with url, mark, expiresAt, domains and issuer, plus matchesCertificate, records and logoFromCertificate.

Example

from nextmail import nextmail pem = (    '-----BEGIN CERTIFICATE-----\n'    'MIIIGDCCBgCgAwIBAgIQC0lDqKvKoTW8AHbyHU0ASTANBgkqhkiG9w0BAQsFADBN\n'    '-----END CERTIFICATE-----\n') logo = nextmail.domains.set_logo_certificate(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', {'certificate': pem})certificate = logo['certificate'] if certificate is not None:    print(certificate['mark'], certificate['expiresAt'], logo['logoFromCertificate'])

Notes

  • A domain that is not verified is refused with 409 domain_not_verified. A file that cannot be read, is over 128 KB, holds no VMC or CMC, was issued for a different domain or has expired is a 422 invalid_parameter on certificate whose message says which.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist. Safe to replay, so the SDK retries it after a network failure.

Also available in

API
PUT /domains/{id}/logo/certificate
TypeScript
nextmail.domains.setLogoCertificate()
Ruby
domains.set_logo_certificate
PHP
domains->setLogoCertificate
Go
Domains.SetLogoCertificate
Java
domains().setLogoCertificate
C#
Domains.SetLogoCertificateAsync
CLI
nextmail domains set-logo-certificate

domains.remove_logo_certificate()

Remove the mark certificate of a domain logo

Scopesdomains:write
Signature
def remove_logo_certificate(    id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainLogoChangeResource

Removes the mark certificate and deletes the stored file, while the logo stays. The BIMI record no longer points at a certificate, so Gmail and Apple Mail stop showing the logo.

Parameters

idstrRequired

Domain id from list or create, a UUID.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainLogoChangeResource with certificate and matchesCertificate set to None.

Example

from nextmail import nextmail logo = nextmail.domains.remove_logo_certificate('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f') print(logo['url'], logo['certificate'])

Notes

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • Removing a certificate from a domain that has none changes nothing, so the SDK retries it after a network failure.

Also available in

API
DELETE /domains/{id}/logo/certificate
TypeScript
nextmail.domains.removeLogoCertificate()
Ruby
domains.remove_logo_certificate
PHP
domains->removeLogoCertificate
Go
Domains.RemoveLogoCertificate
Java
domains().removeLogoCertificate
C#
Domains.RemoveLogoCertificateAsync
CLI
nextmail domains remove-logo-certificate

domains.list_addresses()

List one page of the addresses on a domain

Scopesdomains:readPages through results
Signature
def list_addresses(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Page[DomainAddressResource]

Returns one page of the addresses on the domain, alphabetically by address, with each one's id, label, enabled and lastReceivedAt. That covers the addresses created by hand or through the API and the ones the catch-all picked up when mail first arrived for them. Disabled addresses are listed. Removed addresses and the catch-all itself are not: the catch-all is receiving['catchAll'] on the domain.

list_all_addresses collects every page and iterate_addresses walks them lazily.

Parameters

idstrRequired

Domain id from list or create, a UUID.

limitint

Page size, from 1 to 100. The server defaults to 25.

cursorstr

The nextCursor of the previous page. Leave it out for the first page.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

Page[DomainAddressResource], a dict with items, hasMore and nextCursor.

Example

from nextmail import nextmail page = nextmail.domains.list_addresses('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', limit=100) for address in page['items']:    print(address['address'], address['enabled'], address['label'] or '')

Notes

  • A narrowed key still sees every address on the domain, the same as get.

  • A domain id from another workspace is a 404, the same as an id that does not exist.

  • The cursor is opaque. A cursor this list did not hand out is a 400 invalid_cursor.

Also available in

API
GET /domains/{id}/addresses
TypeScript
nextmail.domains.listAddresses()
Ruby
domains.list_addresses
PHP
domains->listAddresses
Go
Domains.ListAddresses
Java
domains().listAddresses
C#
Domains.ListAddressesAsync
CLI
nextmail domains list-addresses

domains.list_all_addresses()

Collect every address on a domain into one list

Scopesdomains:readPages through results
Signature
def list_all_addresses(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> builtins.list[DomainAddressResource]

Walks every page of list_addresses and returns all the addresses on the domain as one list, alphabetically by address. One request per page.

Parameters

idstrRequired

Domain id from list or create, a UUID.

limitint

Page size for each request, from 1 to 100. The server defaults to 25.

cursorstr

Starts the walk after this cursor instead of the first page.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

list[DomainAddressResource] holding every address on the domain.

Example

from nextmail import nextmail addresses = nextmail.domains.list_all_addresses('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f')disabled = [address['address'] for address in addresses if not address['enabled']] print(len(addresses), 'addresses, switched off:', disabled)

Notes

  • If any page fails, the call raises and the addresses already fetched are discarded.

Also available in

API
GET /domains/{id}/addresses
TypeScript
nextmail.domains.listAllAddresses()
Ruby
domains.list_all_addresses
PHP
domains->listAllAddresses
Go
Domains.ListAllAddresses
Java
domains().listAllAddresses
C#
Domains.ListAllAddressesAsync

domains.iterate_addresses()

Stream the addresses on a domain one at a time

Scopesdomains:readPages through results
Signature
def iterate_addresses(    id: str,    *,    limit: int | None = None,    cursor: str | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> Iterator[DomainAddressResource]

Returns a generator that yields the addresses on the domain one at a time, alphabetically by address, and requests the next page only once the current one is used up. Nothing is fetched until you start iterating, and breaking out of the loop stops the requests.

Parameters

idstrRequired

Domain id from list or create, a UUID.

limitint

Page size for each request, from 1 to 100. The server defaults to 25.

cursorstr

Starts the walk after this cursor instead of the first page.

api_keystr

Overrides the client's API key for every page of this walk.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

Iterator[DomainAddressResource], a generator yielding one address per step.

Example

from nextmail import nextmail for address in nextmail.domains.iterate_addresses('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f'):    print(address['address'], address['lastReceivedAt'])

Notes

  • The generator is lazy, so an abandoned loop costs only the pages you consumed.

Also available in

API
GET /domains/{id}/addresses
TypeScript
nextmail.domains.iterateAddresses()
Ruby
domains.iterate_addresses
PHP
domains->iterateAddresses
Go
Domains.IterateAddresses
Java
domains().iterateAddresses
C#
Domains.IterateAddressesAsync

domains.create_address()

Create an address on a domain

Scopesdomains:write
Signature
def create_address(    id: str,    body: DomainAddressCreate,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainAddressResource

Creates an address on the domain, enabled, and returns it. The domain does not have to be verified yet, but the address receives nothing until it is.

When the domain has its catch-all on, the new address starts with the per-address settings of the catch-all, such as its signature and tracking, apart from the privacy settings. They are copied once, not kept in step.

Creating an address that already exists, or one that was removed, is not an error: it comes back enabled, with the label you sent or none, and keeps its id. An address the catch-all picked up becomes one created by hand, so it keeps receiving when the catch-all is turned off.

Parameters

idstrRequired

Domain id from list or create, a UUID.

body['localPart']strRequired

The part in front of the @, 1 to 64 characters once trimmed, lower cased. Letters, digits, the backtick and ! # $ % & ' * + / = ? ^ _ { | } ~ - are allowed, and so are dots between them. * on its own is how the catch-all is written and is refused.

body['label']str | None

A name for the address shown in the app, trimmed, up to 120 characters. Leave it out, or send None or an empty string, for none.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainAddressResource with its id, address, label and enabled set to True.

Example

from nextmail import nextmail address = nextmail.domains.create_address(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', {'localPart': 'support', 'label': 'Support'}) print(address['id'], address['address'])

Notes

  • An address reserved as somebody's account address is refused with 409 address_reserved on localPart. Past the workspace limit on addresses the call is refused with 422 workspace_limit_reached.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • A domain id from another workspace is a 404, the same as an id that does not exist.

  • Retried automatically on network failure and retryable statuses, since creating the same address twice leaves one address with the same id.

Also available in

API
POST /domains/{id}/addresses
TypeScript
nextmail.domains.createAddress()
Ruby
domains.create_address
PHP
domains->createAddress
Go
Domains.CreateAddress
Java
domains().createAddress
C#
Domains.CreateAddressAsync
CLI
nextmail domains create-address

domains.get_address()

Read one address on a domain

Scopesdomains:read
Signature
def get_address(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainAddressResource

Returns one address on the domain with its label, enabled, lastReceivedAt and timestamps.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainAddressResource.

Example

from nextmail import NextmailApiError, nextmail try:    address = nextmail.domains.get_address(        'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70'    )except NextmailApiError as error:    if error.is_not_found:        print('No such address on this domain')    else:        raiseelse:    print(address['address'], address['enabled'], address['lastReceivedAt'])

Notes

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace.

Also available in

API
GET /domains/{id}/addresses/{addressId}
TypeScript
nextmail.domains.getAddress()
Ruby
domains.get_address
PHP
domains->getAddress
Go
Domains.GetAddress
Java
domains().getAddress
C#
Domains.GetAddressAsync
CLI
nextmail domains get-address

domains.update_address()

Rename an address, turn it off and on, or choose where its mail goes

Scopesdomains:write
Signature
def update_address(    id: str,    address_id: str,    patch: DomainAddressPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainAddressResource

Changes the keys you send and leaves the rest alone. label renames the address, and None or an empty string removes the name. enabled set to False stops the address taking mail: mail to it is refused while the sending server is still connected, so the sender gets a bounce, and nothing can be sent from it. It keeps its mail, its settings and the people who can reach it, so enabled set to True picks up where it left off. That is the difference from delete_address.

destination chooses where the mail of the address goes: mailbox keeps a copy here, as an address does by default, and forward only sends it on to the destinations from add_address_forwards, keeping nothing here. forward needs at least one destination that is switched on.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

patch['label']str | None

A new name, trimmed, up to 120 characters. None or an empty string removes it.

patch['enabled']bool

False stops the address taking mail, True takes mail again.

patch['destination']DomainAddressDestination

mailbox keeps a copy of the mail here, forward only forwards it.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainAddressResource as it stands after the change.

Example

from nextmail import nextmail address = nextmail.domains.update_address(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'enabled': False},) print(address['address'], address['enabled'])

Notes

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • A body key other than label, enabled and destination is a 422 unknown_parameter.

  • {'destination': 'forward'} on an address with no destination switched on is refused with 409 forward_required on destination.

  • Sending destination with an OAuth access token needs a verification code, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An access token acting for a member can only change where the mail of an address goes when that member reaches it, or it is refused with 403 insufficient_authority. An API key is never asked for a code.

  • Retried automatically on network failure and retryable statuses, since the same patch sent twice leaves the same address.

Also available in

API
PATCH /domains/{id}/addresses/{addressId}
TypeScript
nextmail.domains.updateAddress()
Ruby
domains.update_address
PHP
domains->updateAddress
Go
Domains.UpdateAddress
Java
domains().updateAddress
C#
Domains.UpdateAddressAsync
CLI
nextmail domains update-address

domains.set_address_photo()

Upload the photo shown for an address

Scopesdomains:write
Signature
def set_address_photo(    id: str,    address_id: str,    data: RawBody,    *,    content_type: ContactPhotoType | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> DomainAddressResource

Sends the image bytes as the request body, replacing any photo the address had: PNG, JPEG, WebP or GIF up to 5 MB, cropped to a 512 pixel square, stored as JPEG or PNG and shown for the address in Nextmail in place of the domain logo. Name the type in content_type=: without it the bytes go as application/octet-stream, which the server refuses with 422 invalid_image.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

dataRawBodyRequired

The image as bytes, bytearray or memoryview.

content_typeContactPhotoType

image/png, image/jpeg, image/webp or image/gif, the type of data. Leaving it out gets the bytes refused with 422 invalid_image.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainAddressResource with the new photoUrl.

Example

from pathlib import Path from nextmail import nextmail address = nextmail.domains.set_address_photo(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    Path('photo.jpg').read_bytes(),    content_type='image/jpeg',) print(address['photoUrl'])

Notes

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • A busy image service answers 503 image_busy and a failed save 502 image_not_stored, which the SDK retries like any other retryable status.

Also available in

API
PUT /domains/{id}/addresses/{addressId}/photo
TypeScript
nextmail.domains.setAddressPhoto()
Ruby
domains.set_address_photo
PHP
domains->setAddressPhoto
Go
Domains.SetAddressPhoto
Java
domains().setAddressPhoto
C#
Domains.SetAddressPhotoAsync
CLI
nextmail domains set-address-photo

domains.remove_address_photo()

Remove the photo of an address

Scopesdomains:write
Signature
def remove_address_photo(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainAddressResource

Removes the photo of the address and deletes the stored image, so the domain logo is shown for it again.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainAddressResource with photoUrl set to None.

Example

from nextmail import nextmail address = nextmail.domains.remove_address_photo(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') print(address['address'], address['photoUrl'])

Notes

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • Removing a photo from an address that has none changes nothing, so the SDK retries it after a network failure.

Also available in

API
DELETE /domains/{id}/addresses/{addressId}/photo
TypeScript
nextmail.domains.removeAddressPhoto()
Ruby
domains.remove_address_photo
PHP
domains->removeAddressPhoto
Go
Domains.RemoveAddressPhoto
Java
domains().removeAddressPhoto
C#
Domains.RemoveAddressPhotoAsync
CLI
nextmail domains remove-address-photo

domains.delete_address()

Remove an address from a domain

Scopesdomains:write
Signature
def delete_address(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedDomainAddressResource

Removes the address. Mail to it is refused from then on, even when the catch-all on the domain is on. Its forwarding stops, its settings are deleted, the people who were given access to it lose that access, and its password sign-in is revoked. Mail it already received stays in the mailbox.

Creating the same address again with create_address brings it back with the same id, enabled, but without its old settings or access.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedDomainAddressResource with object set to 'address', id, address and deleted set to True.

Example

from nextmail import nextmail removed = nextmail.domains.delete_address(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') print(removed['address'], removed['deleted'])

Notes

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • An access token acting for a member also needs workspace:manage in that member's role, as removing one in the app does. It is console-only, so no approval can give it to an app, and without it the call is refused with 403 insufficient_authority.

  • The SDK does not retry a delete. A 404 on your own second attempt after a lost response means the first one worked.

Also available in

API
DELETE /domains/{id}/addresses/{addressId}
TypeScript
nextmail.domains.deleteAddress()
Ruby
domains.delete_address
PHP
domains->deleteAddress
Go
Domains.DeleteAddress
Java
domains().deleteAddress
C#
Domains.DeleteAddressAsync
CLI
nextmail domains delete-address

domains.list_address_forwards()

List where the mail of an address is forwarded

Scopesdomains:read
Signature
def list_address_forwards(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressForwardListResource

Returns every place the mail of the address is forwarded to, oldest first, as the Forwarding section of the address in the app lists them. Each destination says whether it is switched on (enabled) and where it stands (status): only a live destination, one that confirmed by email that it wants this mail, receives anything.

destination on the list says whether the address also keeps a copy of its mail here (mailbox) or only forwards it (forward), and max is how many destinations one address may have.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressForwardListResource: address, destination, max and the destinations in data.

Example

from nextmail import nextmail forwards = nextmail.domains.list_address_forwards(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') print(forwards['address'], forwards['destination']) for forward in forwards['data']:    print(forward['email'], forward['status'], forward['enabled'])

Notes

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/addresses/{addressId}/forwards
TypeScript
nextmail.domains.listAddressForwards()
Ruby
domains.list_address_forwards
PHP
domains->listAddressForwards
Go
Domains.ListAddressForwards
Java
domains().listAddressForwards
C#
Domains.ListAddressForwardsAsync
CLI
nextmail domains list-address-forwards

domains.add_address_forwards()

Forward the mail of an address to more places

Scopesdomains:write
Signature
def add_address_forwards(    id: str,    address_id: str,    body: AddressForwardsAdd,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressForwardsAddedResource

Adds places the mail of the address goes to, as adding a destination in the app does. Each new destination is sent an email asking it to confirm, and receives nothing until it does, so it comes back pending and turns live once its owner confirms.

An address hosted here, one already on the list, one that would make a loop, one past the limit of 10 and one that refused mail from this workspace before are not added. Each is named in skipped with the reason, and the rest are still added.

The address keeps a copy of its mail here as before. To stop keeping one, set destination to forward with update_address once a destination is switched on.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

body['emails']list[str]Required

The addresses to forward to, 1 to 10 of them. Each is trimmed and lowercased.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressForwardsAddedResource: the destinations added in added, and every address that was not, with the reason, in skipped.

Example

from nextmail import nextmail result = nextmail.domains.add_address_forwards(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'emails': ['ops@partner.example', 'ada@example.com']},) for forward in result['added']:    print('Asked to confirm:', forward['email'], forward['status']) for skipped in result['skipped']:    print('Not added:', skipped['email'], skipped['reason'])

Notes

  • An address that is switched off is refused with 409 address_disabled. Switch it on with update_address first.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist. An access token acting for a member can only change the forwarding of an address that member reaches, or it is refused with 403 insufficient_authority.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried automatically by the SDK, since a lost attempt may already have asked a destination to confirm.

Also available in

API
POST /domains/{id}/addresses/{addressId}/forwards
TypeScript
nextmail.domains.addAddressForwards()
Ruby
domains.add_address_forwards
PHP
domains->addAddressForwards
Go
Domains.AddAddressForwards
Java
domains().addAddressForwards
C#
Domains.AddAddressForwardsAsync
CLI
nextmail domains add-address-forwards

domains.update_address_forward()

Pause a forwarding destination or switch it back on

Scopesdomains:write
Signature
def update_address_forward(    id: str,    address_id: str,    forward_id: str,    patch: AddressForwardPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressForwardChangeResource

enabled set to False pauses the destination: nothing is forwarded to it until it is switched on again. It keeps its confirmation, so switching it back on needs no new one, and switching it on clears the failures recorded against it.

When the last destination that is on is paused, the address goes back to keeping its mail here. destination in the result says where the mail of the address goes now.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

forward_idstrRequired

A destination id from list_address_forwards or add_address_forwards. It has to be a destination of the address named by address_id.

patch['enabled']boolRequired

False pauses the destination, True switches it back on.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressForwardChangeResource: the destination as it is now, with destination for the address.

Example

from nextmail import nextmail forward = nextmail.domains.update_address_forward(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    '5e8f1a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b',    {'enabled': False},) print(forward['status'], forward['destination'])

Notes

  • A destination id that is not on this address is a 404 resource_not_found.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist. An access token acting for a member can only change the forwarding of an address that member reaches, or it is refused with 403 insufficient_authority.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Retried automatically on network failure, since the same patch sent twice leaves the same destination.

Also available in

API
PATCH /domains/{id}/addresses/{addressId}/forwards/{forwardId}
TypeScript
nextmail.domains.updateAddressForward()
Ruby
domains.update_address_forward
PHP
domains->updateAddressForward
Go
Domains.UpdateAddressForward
Java
domains().updateAddressForward
C#
Domains.UpdateAddressForwardAsync
CLI
nextmail domains update-address-forward

domains.delete_address_forward()

Stop forwarding to a destination

Scopesdomains:write
Signature
def delete_address_forward(    id: str,    address_id: str,    forward_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedAddressForwardResource

Removes the destination, so nothing more is forwarded to it. When it was the last destination that was on, the address goes back to keeping its mail here, and destination in the result says where the mail of the address goes now.

To stop forwarding for a while instead, pause the destination with update_address_forward, which keeps its confirmation.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

forward_idstrRequired

A destination id from list_address_forwards or add_address_forwards. It has to be a destination of the address named by address_id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedAddressForwardResource with object set to 'address_forward', id, addressId, email, deleted set to True, and destination.

Example

from nextmail import nextmail removed = nextmail.domains.delete_address_forward(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    '5e8f1a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b',) print(removed['email'], removed['destination'])

Notes

  • A destination id that is not on this address is a 404 resource_not_found.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist. An access token acting for a member can only change the forwarding of an address that member reaches, or it is refused with 403 insufficient_authority.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried by the SDK. Repeating a delete that succeeded is a 404.

Also available in

API
DELETE /domains/{id}/addresses/{addressId}/forwards/{forwardId}
TypeScript
nextmail.domains.deleteAddressForward()
Ruby
domains.delete_address_forward
PHP
domains->deleteAddressForward
Go
Domains.DeleteAddressForward
Java
domains().deleteAddressForward
C#
Domains.DeleteAddressForwardAsync
CLI
nextmail domains delete-address-forward

domains.resend_address_forward_consent()

Ask a forwarding destination to confirm again

Scopesdomains:write
Signature
def resend_address_forward_consent(    id: str,    address_id: str,    forward_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressForwardConsentResource

Sends the confirmation email to the destination once more, for when the first one was lost or ignored. status says what became of the request: sent, already-confirmed when the destination has confirmed and needs nothing, too-soon when the last email went out moments ago, revoked when the destination refused mail from this workspace, and send-failed when the email could not be sent.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

forward_idstrRequired

A destination id from list_address_forwards or add_address_forwards. It has to be a destination of the address named by address_id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressForwardConsentResource with the status of the request.

Example

from nextmail import nextmail asked = nextmail.domains.resend_address_forward_consent(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    '5e8f1a2b-3c4d-4e5f-8a9b-0c1d2e3f4a5b',) if asked['status'] == 'too-soon':    print('Wait a moment before asking again.')else:    print(asked['email'], asked['status'])

Notes

  • A destination id that is not on this address is a 404 resource_not_found.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist. An access token acting for a member can only change the forwarding of an address that member reaches, or it is refused with 403 insufficient_authority.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried automatically by the SDK, since every attempt can send an email.

Also available in

API
POST /domains/{id}/addresses/{addressId}/forwards/{forwardId}/resend
TypeScript
nextmail.domains.resendAddressForwardConsent()
Ruby
domains.resend_address_forward_consent
PHP
domains->resendAddressForwardConsent
Go
Domains.ResendAddressForwardConsent
Java
domains().resendAddressForwardConsent
C#
Domains.ResendAddressForwardConsentAsync
CLI
nextmail domains resend-address-forward-consent

domains.list_address_members()

List who can reach an address

Scopesmembers:read
Signature
def list_address_members(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressMemberListResource

Returns everybody who can read the mail of the address and how each one reaches it, in via: owner for the owner of the workspace, every-address for a role that reaches every address, whole-domain for a grant of the whole domain named in viaDomain, and direct for a grant of the address itself. Each person appears once.

access is member for somebody who reads and sends from the address and viewer for somebody who only reads it. removable is True for a grant of the address itself, which members.revoke_address takes back. The others come from the role or a domain grant, and change there.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressMemberListResource, with the people in data.

Example

from nextmail import nextmail reach = nextmail.domains.list_address_members(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') for person in reach['data']:    print(person['email'], person['access'], person['via'])

Notes

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/addresses/{addressId}/members
TypeScript
nextmail.domains.listAddressMembers()
Ruby
domains.list_address_members
PHP
domains->listAddressMembers
Go
Domains.ListAddressMembers
Java
domains().listAddressMembers
C#
Domains.ListAddressMembersAsync
CLI
nextmail domains list-address-members

domains.get_address_login()

Read the password sign-in of an address

Scopesmembers:write
Signature
def get_address_login(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressLoginResource

Says whether the address has a password of its own, which lets somebody sign in to Nextmail as that address alone and read and send only its mail. login is None when it has none, and otherwise says who set the password and when, and when it was last used to sign in.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressLoginResource, with login set to None when the address has no password.

Example

from nextmail import nextmail login = nextmail.domains.get_address_login(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70')['login'] print(login['lastSignedInAt'] if login else 'no password')

Notes

  • It needs members:write, the scope that sets a password, as the app does, rather than a read scope.

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace.

  • A key limited to particular addresses or domains is refused with 422 capability_unsupported. An access token acting for a member can only reach the sign-in of an address that member reaches, or it is refused with 403 insufficient_authority.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/addresses/{addressId}/login
TypeScript
nextmail.domains.getAddressLogin()
Ruby
domains.get_address_login
PHP
domains->getAddressLogin
Go
Domains.GetAddressLogin
Java
domains().getAddressLogin
C#
Domains.GetAddressLoginAsync
CLI
nextmail domains get-address-login

domains.set_address_login()

Give an address a password, or replace it

Scopesmembers:write
Signature
def set_address_login(    id: str,    address_id: str,    body: AddressLoginSet,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressLoginResource

Sets the password somebody uses to sign in to Nextmail as this address alone. Whoever holds it reads and sends only the mail of the address and reaches nothing else in the workspace. Nextmail sends the password to nobody, so hand it over yourself.

Calling it again replaces the password, signs out everybody who signed in with the old one and removes the forwarding destinations they added. created says whether the sign-in is new.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

body['password']strRequired

At least 8 characters, with a lowercase letter, an uppercase letter, a number and a special character.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AddressLoginResource as it stands after the change, with created.

Example

import os from nextmail import nextmail result = nextmail.domains.set_address_login(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'password': os.environ.get('SUPPORT_INBOX_PASSWORD', '')},) print('Sign-in created' if result.get('created') else 'Password replaced')

Notes

  • A password that misses a rule is a 422 invalid_parameter on password. An address that an account on Nextmail already signs in as is refused with 409 account_exists, so invite that account to the workspace instead, and an address that is switched off is refused with 409 address_unavailable.

  • The first password on a workspace whose plan has no team access is refused with 403 plan_required.

  • A key or an access token has to hold every scope a sign-in for one address may use, or it is refused with 403 insufficient_authority. A key limited to particular addresses or domains is refused with 422 capability_unsupported, and an access token acting for a member can only set the password of an address that member reaches with member access.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried automatically by the SDK.

Also available in

API
PUT /domains/{id}/addresses/{addressId}/login
TypeScript
nextmail.domains.setAddressLogin()
Ruby
domains.set_address_login
PHP
domains->setAddressLogin
Go
Domains.SetAddressLogin
Java
domains().setAddressLogin
C#
Domains.SetAddressLoginAsync
CLI
nextmail domains set-address-login

domains.delete_address_login()

Remove the password sign-in of an address

Scopesmembers:write
Signature
def delete_address_login(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedAddressLoginResource

Takes the password away and signs out everybody who signed in with it. The address, its mail and the people who reach it otherwise stay as they are, and the forwarding destinations added by whoever signed in as the address are removed with it.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedAddressLoginResource with object set to 'address_login', addressId, address and deleted set to True.

Example

from nextmail import NextmailApiError, nextmail try:    removed = nextmail.domains.delete_address_login(        'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70'    )except NextmailApiError as error:    if error.is_not_found:        print('This address has no password')    else:        raiseelse:    print(removed['address'], removed['deleted'])

Notes

  • An address with no password is a 404.

  • A key limited to particular addresses or domains is refused with 422 capability_unsupported. An access token acting for a member can only reach the sign-in of an address that member reaches, or it is refused with 403 insufficient_authority.

  • Not retried by the SDK. Repeating a delete that succeeded is a 404.

Also available in

API
DELETE /domains/{id}/addresses/{addressId}/login
TypeScript
nextmail.domains.deleteAddressLogin()
Ruby
domains.delete_address_login
PHP
domains->deleteAddressLogin
Go
Domains.DeleteAddressLogin
Java
domains().deleteAddressLogin
C#
Domains.DeleteAddressLoginAsync
CLI
nextmail domains delete-address-login

domains.get_mail_app_settings()

Read the mail app settings of an address

Scopesdomains:read
Signature
def get_mail_app_settings(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> MailAppSettingsResource

Returns what to enter in Apple Mail, Gmail, Outlook, Thunderbird or any other mail app to add the address to it: the IMAP, SMTP and POP3 servers, each with its host, port and security, and the username to sign in with, which is the address itself. Each of those three encrypts the connection from the first byte, so its security is 'ssl-tls'. smtpSubmission is the same SMTP server on port 587 for apps, devices and libraries that only offer STARTTLS: its security is 'starttls', the connection is upgraded before the sign-in, and it takes the same username and password.

caldav is the server that puts the calendar of the address into Apple Calendar, Thunderbird, DAVx5 on Android or any other CalDAV app, and carddav the one that puts the contacts of the workspace into Apple Contacts or any other CardDAV app. Each has a url to enter, with the same username and password, a principalUrl for apps that ask for the account address on the server, and host, port and security like the others.

protocols says which of these connections the address accepts, as True or False for imap, smtp, pop3, caldav and carddav. update_mail_app_settings changes them.

The password is an app password of the address, such as one create_app_password makes, or the password set_address_login set when the address has a sign-in of its own without two-factor.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

MailAppSettingsResource: address, username, imap, smtp, smtpSubmission and pop3, each with host, port and security, caldav and carddav with the same three, their url and principalUrl, and protocols.

Example

from nextmail import nextmail settings = nextmail.domains.get_mail_app_settings(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') print('Sign in as', settings['username'])print('IMAP', settings['imap']['host'], settings['imap']['port'])print('SMTP', settings['smtp']['host'], settings['smtp']['port'])

Notes

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace. An access token acting for a member gets the same 404 for an address that member cannot read.

  • A key or an access token limited to particular addresses or domains reads only the addresses it is limited to, and any other address is a 404 resource_not_found.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/addresses/{addressId}/mail-apps
TypeScript
nextmail.domains.getMailAppSettings()
Ruby
domains.get_mail_app_settings
PHP
domains->getMailAppSettings
Go
Domains.GetMailAppSettings
Java
domains().getMailAppSettings
C#
Domains.GetMailAppSettingsAsync
CLI
nextmail domains get-mail-app-settings

domains.update_mail_app_settings()

Turn mail app connections on or off for an address

Scopesdomains:write
Signature
def update_mail_app_settings(    id: str,    address_id: str,    patch: MailAppSettingsPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> MailAppSettingsResource

Switches each kind of connection the address accepts on or off: imap, smtp and pop3 for mail, caldav for its calendar and carddav for contacts. Send only the ones to change, and the rest stay as they are. Every kind is on until it is switched off.

A switched-off kind refuses every sign-in to it, whatever the password, with a message that says it is turned off. Mail apps and calendar or contacts apps that are already connected over it are signed out within minutes. App passwords stay as they are, so switching a kind back on lets them in again.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

patch['imap']bool

IMAP, which keeps folders and read state in step with Nextmail.

patch['smtp']bool

SMTP, for sending from a mail app, on port 465 and on port 587 alike.

patch['pop3']bool

POP3, for apps that only download the inbox.

patch['caldav']bool

CalDAV, which puts the calendar of the address into calendar apps.

patch['carddav']bool

CardDAV, which puts the contacts of the workspace into contacts apps.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

MailAppSettingsResource: the settings as get_mail_app_settings returns them, with protocols as the switches now stand.

Example

from nextmail import nextmail settings = nextmail.domains.update_mail_app_settings(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'pop3': False},) print(settings['protocols'])

Notes

  • Only the workspace owner, or someone whose role manages domains, may change the switches. An access token acting for anyone else is refused with 403 insufficient_authority. An API key acts for the workspace owner.

  • An address id that is not on this domain is a 404 resource_not_found. A key or an access token limited to particular addresses or domains changes only the addresses it is limited to, and any other address is a 404 resource_not_found.

  • An unknown key is refused with 422 unknown_parameter, and a value that is not a bool with 422 invalid_parameter.

  • Retried automatically on network failure, since the same patch sent twice leaves the same switches.

Also available in

API
PATCH /domains/{id}/addresses/{addressId}/mail-apps
TypeScript
nextmail.domains.updateMailAppSettings()
Ruby
domains.update_mail_app_settings
PHP
domains->updateMailAppSettings
Go
Domains.UpdateMailAppSettings
Java
domains().updateMailAppSettings
C#
Domains.UpdateMailAppSettingsAsync
CLI
nextmail domains update-mail-app-settings

domains.list_app_passwords()

List the app passwords of an address

Scopesmembers:write
Signature
def list_app_passwords(    id: str,    address_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AppPasswordListResource

Returns every app password a mail app can sign in to the address with, newest first. Each one has the name it was given, last4, the last four letters of the password, to tell them apart, owner, the person it signs in as, and origin, which says where it was made: 'settings' in the app, 'api' through create_app_password, and 'setup-link' by opening an emailed setup link, such as one send_mail_app_setup sends.

lastUsedAt and lastUsedProtocol say when an app last signed in with it and over which of 'imap', 'smtp', 'pop3', 'caldav' and 'carddav', and lastUsedClient names the mail app when it named itself. The passwords themselves are shown only when they are made, and revoked ones are left out.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AppPasswordListResource, with the app passwords in data, newest first.

Example

from nextmail import nextmail passwords = nextmail.domains.list_app_passwords(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70') for password in passwords['data']:    last_used = password['lastUsedAt'] or 'never used'    print(password['name'], password['last4'], password['owner']['email'], last_used)

Notes

  • It needs members:write, the scope that makes and revokes app passwords, as the app does, rather than a read scope.

  • An address id that is not on this domain, or an address that was removed, is a 404 resource_not_found, and so is a domain from another workspace.

  • A key or an access token limited to particular addresses or domains is refused with 422 capability_unsupported, and so is an app a member connected, because its access token is always limited to the addresses that member reaches.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/addresses/{addressId}/app-passwords
TypeScript
nextmail.domains.listAppPasswords()
Ruby
domains.list_app_passwords
PHP
domains->listAppPasswords
Go
Domains.ListAppPasswords
Java
domains().listAppPasswords
C#
Domains.ListAppPasswordsAsync
CLI
nextmail domains list-app-passwords

domains.create_app_password()

Create an app password for an address

Scopesmembers:write
Signature
def create_app_password(    id: str,    address_id: str,    body: AppPasswordCreate,    *,    api_key: str | None = None,    timeout: float | None = None,) -> CreatedAppPasswordResource

Makes a password a mail app signs in to the address with, using the address as the username, and returns it in password with the server settings in servers. That is the only time the password is shown, so hand it over or store it then.

The password signs in as the caller for this address alone: an API key makes it for the workspace owner, and an access token for the person who connected the app. A mail app using it reaches the mail of the address with what that person may do there, and nothing else in the workspace. It is 16 letters in four groups joined by dashes, and the dashes, or spaces in their place, can be left out when it is typed.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

body['name']strRequired

What to call the password, such as the device it is for, 1 to 64 characters. It is trimmed.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

CreatedAppPasswordResource: the app password as list_app_passwords returns it, with origin set to 'api', plus password, shown this once, servers, the settings get_mail_app_settings returns, and appleProfile, an Apple configuration profile with the password inside. Saved as a .mobileconfig file and opened on an iPhone, iPad or Mac, the profile adds the address to Mail and its calendar and contacts to Calendar and Contacts in one step, for the connections the address accepts. It holds the password, so keep it like one.

Example

from nextmail import nextmail created = nextmail.domains.create_app_password(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'name': 'Front desk iPad'},)servers = created['servers'] print('Sign in as', servers['username'], 'with', created['password'])print('IMAP', servers['imap']['host'], servers['imap']['port'])print('SMTP', servers['smtp']['host'], servers['smtp']['port'])

Notes

  • One person can hold 20 app passwords for one address, and the 21st is refused with 422 app_password_limit_reached, so revoke one with delete_app_password first. An address that only forwards its mail, or is switched off, has no mailbox for a mail app to open and is refused with 422 address_has_no_mailbox.

  • A key or an access token limited to particular addresses or domains is refused with 422 capability_unsupported, and so is an app a member connected, because its access token is always limited to the addresses that member reaches.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried automatically by the SDK, since a lost attempt may already have made a password. The success status is 201.

Also available in

API
POST /domains/{id}/addresses/{addressId}/app-passwords
TypeScript
nextmail.domains.createAppPassword()
Ruby
domains.create_app_password
PHP
domains->createAppPassword
Go
Domains.CreateAppPassword
Java
domains().createAppPassword
C#
Domains.CreateAppPasswordAsync
CLI
nextmail domains create-app-password

domains.update_app_password()

Rename an app password

Scopesmembers:write
Signature
def update_app_password(    id: str,    address_id: str,    password_id: str,    patch: AppPasswordPatch,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AppPasswordResource

Changes the name shown for the app password, such as when the device it is for changes hands. The password itself stays the same, and a mail app signed in with it stays signed in.

A person renames the app passwords they hold. The workspace owner, and someone whose role manages members, rename anyone's.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

password_idstrRequired

An app password id from list_app_passwords or create_app_password. It has to be an app password of the address named by address_id.

patch['name']strRequired

The new name, 1 to 64 characters. It is trimmed.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

AppPasswordResource: the app password as list_app_passwords returns it, with its new name.

Example

from nextmail import nextmail password = nextmail.domains.update_app_password(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    'map_3f9a1c7e5b2d4f6a8c0e1b3d',    {'name': 'Reception iPad'},) print(password['name'], password['last4'])

Notes

  • An app password id that is not on this address, one already revoked, or one held by someone else when the caller cannot manage members, is a 404 resource_not_found.

  • A key or an access token limited to particular addresses or domains is refused with 422 capability_unsupported, and so is an app a member connected, because its access token is always limited to the addresses that member reaches.

  • Retried automatically on network failure, since the same name sent twice leaves the same password.

Also available in

API
PATCH /domains/{id}/addresses/{addressId}/app-passwords/{passwordId}
TypeScript
nextmail.domains.updateAppPassword()
Ruby
domains.update_app_password
PHP
domains->updateAppPassword
Go
Domains.UpdateAppPassword
Java
domains().updateAppPassword
C#
Domains.UpdateAppPasswordAsync
CLI
nextmail domains update-app-password

domains.delete_app_password()

Revoke an app password

Scopesmembers:write
Signature
def delete_app_password(    id: str,    address_id: str,    password_id: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeletedAppPasswordResource

Revokes the app password, so no mail app can sign in with it again, and a mail app that is signed in with it is signed out within minutes. The address, its mail and its other app passwords stay as they are.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

password_idstrRequired

An app password id from list_app_passwords or create_app_password. It has to be an app password of the address named by address_id.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DeletedAppPasswordResource with object set to 'app_password', id and deleted set to True.

Example

from nextmail import NextmailApiError, nextmail try:    revoked = nextmail.domains.delete_app_password(        'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',        '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',        'map_3f9a1c7e5b2d4f6a8c0e1b3d',    )except NextmailApiError as error:    if error.is_not_found:        print('This app password was already revoked')    else:        raiseelse:    print('Revoked', revoked['id'])

Notes

  • An app password id that is not on this address, or one already revoked, is a 404 resource_not_found.

  • A key or an access token limited to particular addresses or domains is refused with 422 capability_unsupported, and so is an app a member connected, because its access token is always limited to the addresses that member reaches.

  • Not retried by the SDK. Repeating a delete that succeeded is a 404.

Also available in

API
DELETE /domains/{id}/addresses/{addressId}/app-passwords/{passwordId}
TypeScript
nextmail.domains.deleteAppPassword()
Ruby
domains.delete_app_password
PHP
domains->deleteAppPassword
Go
Domains.DeleteAppPassword
Java
domains().deleteAppPassword
C#
Domains.DeleteAppPasswordAsync
CLI
nextmail domains delete-app-password

domains.send_mail_app_setup()

Email a mail app setup link for an address

Scopesmembers:write
Signature
def send_mail_app_setup(    id: str,    address_id: str,    body: MailAppSetupSend,    *,    api_key: str | None = None,    timeout: float | None = None,) -> MailAppSetupResource

Emails the recipient a link that sets the address up in a mail app. Opening it makes an app password named after the recipient, shows it once with the server settings, and offers a profile that sets up an Apple device in one step. The link works once and expires in three days, at expiresAt.

The app password it makes signs in as the caller, as one from create_app_password does: an API key makes it for the workspace owner, and an access token for the person who connected the app. It then appears in list_app_passwords with origin set to 'setup-link'.

Parameters

idstrRequired

Domain id from list or create, a UUID.

address_idstrRequired

Address id from list_addresses or create_address, a UUID. It has to be an address on the domain named by id.

body['recipient']strRequired

The email address to send the link to, such as the person who will use the mail app. It is trimmed and lowercased.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

MailAppSetupResource: address, recipient and expiresAt, when the link stops working.

Example

from nextmail import nextmail setup = nextmail.domains.send_mail_app_setup(    'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f',    '7c9d2e41-0b8f-4a63-9e25-1f4d6a8b3c70',    {'recipient': 'ada@example.com'},) print('Sent', setup['recipient'], 'a link for', setup['address'])print('It works once, until', setup['expiresAt'])

Notes

  • When the email cannot be sent the call is a 503 setup_email_not_sent and nothing is made, so it is safe to call again. An address that only forwards its mail, or is switched off, has no mailbox for a mail app to open and is refused with 422 address_has_no_mailbox. A workspace can email 50 setup links a day, and past that the call is a 429 setup_email_rate_limited.

  • A key or an access token limited to particular addresses or domains is refused with 422 capability_unsupported, and so is an app a member connected, because its access token is always limited to the addresses that member reaches. Only the workspace owner, or someone whose role holds members:write, can send a link, and anyone else is refused with 403 insufficient_authority.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried automatically by the SDK, since every attempt can send an email.

Also available in

API
POST /domains/{id}/addresses/{addressId}/mail-app-setup
TypeScript
nextmail.domains.sendMailAppSetup()
Ruby
domains.send_mail_app_setup
PHP
domains->sendMailAppSetup
Go
Domains.SendMailAppSetup
Java
domains().sendMailAppSetup
C#
Domains.SendMailAppSetupAsync
CLI
nextmail domains send-mail-app-setup

domains.get_dns()

Read how the DNS of a domain is set up

Scopesdomains:read
Signature
def get_dns(    id: str,    *,    refresh: bool | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDnsResource

Returns whether Nextmail writes the records of the domain itself (managing), through which connection and zone, where each kind of record stands in steps, and the records left behind to delete by hand.

zone says which connected zone answers for the domain: one is resolved, several are ambiguous and need set_dns_zone, none holds it, with the reason, or the connections could not be asked (unusable). The answer is kept for a few minutes, and refresh=True asks the providers again.

Parameters

idstrRequired

Domain id from list or create, a UUID.

refreshbool

True asks the providers again which zone answers for the domain.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDnsResource.

Example

from nextmail import nextmail dns = nextmail.domains.get_dns('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f', refresh=True) print(dns['managing'], dns['state'], dns['zone']['kind']) for step in dns['steps']:    print(step['purpose'], step['ok'], step['detail'])

Notes

  • A domain id that is not in this workspace is a 404 resource_not_found.

  • A GET is retried automatically on network failure and on 408, 500, 502, 503 and 504 responses, up to the client's max_retries, and on a 429 only when it carries a Retry-After of a minute or less.

Also available in

API
GET /domains/{id}/dns
TypeScript
nextmail.domains.getDns()
Ruby
domains.get_dns
PHP
domains->getDns
Go
Domains.GetDNS
Java
domains().getDns
C#
Domains.GetDnsAsync
CLI
nextmail domains get-dns

domains.set_dns_zone()

Choose the zone a domain is set up through

Scopesdomains:write
Signature
def set_dns_zone(    id: str,    body: DomainDnsZoneSet,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDnsResource

Attaches the domain to a zone of a connection, when several connected zones could answer for it. The zone has to cover the domain, be active at the provider and take a test record. Nothing is written yet: call sync_dns to write the records.

Parameters

idstrRequired

Domain id from list or create, a UUID.

body['connectionId']strRequired

The connection that holds the zone, from dns_connections.list.

body['zoneId']strRequired

The zone, as the candidates in the zone of get_dns list it: a candidate's candidate['zone']['id'].

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDnsResource as it stands after the change.

Example

from nextmail import nextmail domain_id = 'b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f'candidates = nextmail.domains.get_dns(domain_id)['zone']['candidates'] if candidates:    choice = candidates[0]    dns = nextmail.domains.set_dns_zone(        domain_id, {'connectionId': choice['connectionId'], 'zoneId': choice['zone']['id']}    )    print(dns['zoneName'], dns['state'])

Notes

  • A zone that does not cover the domain is a 422 invalid_parameter on zoneId. A domain already set up through another zone is refused with 409 dns_zone_conflict, a zone that is not active or refuses the test record with 409 dns_zone_unusable, and a connection that was disconnected with 409 dns_connection_unusable.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried by the SDK.

Also available in

API
PUT /domains/{id}/dns
TypeScript
nextmail.domains.setDnsZone()
Ruby
domains.set_dns_zone
PHP
domains->setDnsZone
Go
Domains.SetDNSZone
Java
domains().setDnsZone
C#
Domains.SetDnsZoneAsync
CLI
nextmail domains set-dns-zone

domains.sync_dns()

Write the DNS records of a domain

Scopesdomains:write
Signature
def sync_dns(    id: str,    body: DomainDnsSync | None = None,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DomainDnsSyncResource

Writes or repairs every record the domain needs through the connected zone that answers for it, as Sync does in the app. When exactly one zone answers it is attached first, and attached says so. With purpose, only that kind of record is written. A domain that was waiting for its records is verified once they are in place.

When no single zone answers, nothing is written: outcome is refused, message says why and zone shows the zones to choose from with set_dns_zone.

Parameters

idstrRequired

Domain id from list or create, a UUID.

body['purpose']DnsSyncPurpose

Only this kind of record: dmarc, tracking, storage, bimi or app-host.

api_keystr

Overrides the client's API key for this call only.

timeoutfloat

Seconds this call may take, the response included, before it raises NextmailNetworkError with is_timeout. It overrides the client's timeout for this call, and 0 turns the limit off.

Returns

DomainDnsSyncResource with outcome, the provision that ran and the DNS setup as it is now in dns.

Example

from nextmail import nextmail sync = nextmail.domains.sync_dns('b3e1f0a4-6c2d-4e8a-9f17-2d5c8a0b4e6f')provision = sync['provision'] if sync['outcome'] == 'refused':    print(sync['message'])elif provision is not None:    for record in provision['written']:        print(record['type'], record['name'], record['mode'])

Notes

  • A sync already running on the domain is refused with 409 dns_busy. A provider that refuses the request is a 502 dns_provider_error.

  • A key limited to particular addresses or domains has to hold this whole domain in its domainAllowlist, or the call is refused with 422 capability_unsupported on domainAllowlist.

  • An OAuth access token needs a verification code for this call, and is refused with 403 step_up_required until the app has verified one in the last 60 minutes. is_step_up_required on the error says so. An API key is never asked for a code.

  • Not retried by the SDK.

Also available in

API
POST /domains/{id}/dns/sync
TypeScript
nextmail.domains.syncDns()
Ruby
domains.sync_dns
PHP
domains->syncDns
Go
Domains.SyncDNS
Java
domains().syncDns
C#
Domains.SyncDnsAsync
CLI
nextmail domains sync-dns