Skip to the documentation
Python

nextmail.tools

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

Methods

The free tools on the Nextmail website: checks of the public mail records of any domain, which are its DMARC policy, its BIMI logo and a deliverability report across MX, SPF, DKIM, DMARC and BIMI, a reader for the sign-in code in a message, and the price of every plan for a usage. They need no scope.

tools.check_dmarc()

Check a domain's DMARC policy

No scope
Signature
def check_dmarc(    domain: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DmarcReportResource

Reads the domain's DMARC record from public DNS, or the record of the organisational domain it inherits from, and says how strict it is and what is wrong with it, the DMARC checker on the Nextmail website. stage is missing, invalid, monitor for p=none, quarantine or reject, and issues lists the problems written to be shown to a person.

Parameters

domainstrRequired

The domain to check, such as acme.com. An email address or a URL is read as its domain, and any public domain works, not only the ones in this workspace.

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

DmarcReportResource with domain, record, inheritedFrom, every tag in tags, stage and issues.

Example

from nextmail import nextmail report = nextmail.tools.check_dmarc('acme.com') print(report['stage'], report['tags'].get('p'), report['issues'])

Notes

  • Needs no scope: any key or access token for the workspace may run it.

  • A domain that does not read as one is 422 invalid_parameter on domain, and DNS that did not answer is 503 unreachable, which is worth retrying.

Also available in

API
GET /tools/dmarc
TypeScript
nextmail.tools.checkDmarc()
Ruby
tools.check_dmarc
PHP
tools->checkDmarc
Go
Tools.CheckDmarc
Java
tools().checkDmarc
C#
Tools.CheckDmarcAsync
CLI
nextmail tools check-dmarc

tools.check_bimi()

Check a domain's BIMI logo

No scope
Signature
def check_bimi(    domain: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> BimiReportResource

Reads the domain's BIMI record, fetches the logo it names and checks the DMARC policy beside it, since inboxes draw a logo only at p=quarantine or p=reject, the BIMI checker on the Nextmail website. status is present, partial when the record is there but something stops inboxes showing the logo, absent or invalid, and issues says why.

Parameters

domainstrRequired

The domain to check, such as acme.com. An email address or a URL is read as its domain, and any public domain works, not only the ones in this workspace.

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

BimiReportResource with record, logoUrl, authorityUrl, logoSvg, logoReachable, dmarcPolicy, dmarcEnforced, status and issues.

Example

from nextmail import nextmail report = nextmail.tools.check_bimi('acme.com') if report['status'] != 'present':    for issue in report['issues']:        print(issue)

Notes

  • Needs no scope: any key or access token for the workspace may run it.

  • A domain that does not read as one is 422 invalid_parameter on domain, and DNS that did not answer is 503 unreachable, which is worth retrying.

Also available in

API
GET /tools/bimi
TypeScript
nextmail.tools.checkBimi()
Ruby
tools.check_bimi
PHP
tools->checkBimi
Go
Tools.CheckBimi
Java
tools().checkBimi
C#
Tools.CheckBimiAsync
CLI
nextmail tools check-bimi

tools.check_deliverability()

Check a domain's deliverability

No scope
Signature
def check_deliverability(    domain: str,    *,    api_key: str | None = None,    timeout: float | None = None,) -> DeliverabilityReportResource

Checks the records a receiving mailbox reads before it trusts mail from the domain, the deliverability checker on the Nextmail website: MX, SPF, DKIM at the selectors its mail provider uses, DMARC and BIMI. Each check says pass, warn, fail or absent with a verdict and notes, and score weighs them into 0 to 100, graded A to F.

Parameters

domainstrRequired

The domain to check, such as acme.com. An email address or a URL is read as its domain, and any public domain works, not only the ones in this workspace.

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

DeliverabilityReportResource with score, grade, provider and checks, each with id, label, status, verdict, record and notes.

Example

from nextmail import nextmail report = nextmail.tools.check_deliverability('acme.com') print(report['grade'], report['score']) for check in report['checks']:    print(check['id'], check['status'], check['verdict'])

Notes

  • Needs no scope: any key or access token for the workspace may run it.

  • A domain that does not read as one is 422 invalid_parameter on domain, and DNS that did not answer is 503 unreachable, which is worth retrying.

Also available in

API
GET /tools/deliverability
TypeScript
nextmail.tools.checkDeliverability()
Ruby
tools.check_deliverability
PHP
tools->checkDeliverability
Go
Tools.CheckDeliverability
Java
tools().checkDeliverability
C#
Tools.CheckDeliverabilityAsync
CLI
nextmail tools check-deliverability

tools.read_verification_code()

Read the sign-in code in a message

No scope
Signature
def read_verification_code(    body: VerificationCodeRead,    *,    api_key: str | None = None,    timeout: float | None = None,) -> VerificationCodeResource

Finds the sign-in or verification code in a message you pass in, with the reader that puts a code at the top of a message in Nextmail. Send the whole MIME source as raw, or the subject with html or text.

It answers only when it is sure: the message has to hold exactly one code worded as one, such as a verification code, a one-time code or a security code, in any of the common languages. Two different codes, or a number that could be an order, a booking, a meeting, a phone number or a promotion, answer with code set to None.

It reads only what you send, so it cannot tell whether the sender is who it claims to be. The verificationCode on a message in your mailbox also requires the sender to pass authentication.

Parameters

body['raw']str

The whole message as MIME source, as it was received. Wins over the other keys when it is set.

body['subject']str

Subject line, at most 998 characters.

body['html']str

HTML body. Links are left out before the code is looked for.

body['text']str

Plain text body, used when there is no html.

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

VerificationCodeResource with object set to verification_code and code: the code as you would type it, digits only or capital letters and digits without spaces or dashes, or None when the reader is not sure.

Example

from nextmail import nextmail result = nextmail.tools.read_verification_code(    {        'subject': 'Your verification code',        'html': '<p>Your code is <b>396-696</b>. It expires in 10 minutes.</p>',    }) if result['code']:    print(result['code'])

Notes

  • Needs no scope: any key or access token for the workspace may run it.

  • Nothing is stored and no model is called, so it is safe to run on every message.

  • A body with none of raw, subject, html or text is 422 invalid_parameter.

Also available in

API
POST /tools/verification-code
TypeScript
nextmail.tools.readVerificationCode()
Ruby
tools.read_verification_code
PHP
tools->readVerificationCode
Go
Tools.ReadVerificationCode
Java
tools().readVerificationCode
C#
Tools.ReadVerificationCodeAsync
CLI
nextmail tools read-verification-code

tools.estimate_cost()

Estimate what Nextmail costs for a usage

No scope
Signature
def estimate_cost(    *,    sends: int | None = None,    domains: int | None = None,    people: int | None = None,    ai_actions: int | None = None,    interval: BillingInterval | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> CostEstimateResource

Prices every plan for the usage you describe, as the cost calculator on the Nextmail website does: the plan itself, the extra sends and AI actions it would bill, the monthly total, and whether the plan fits at all. A plan does not fit when the usage needs more domains than it includes, more than one person without team access, or more sends than it allows without billing extra. cheapest names the cheapest plan that fits.

Amounts are in US cents per month. With interval set to 'year', the plan price is the monthly equivalent of paying yearly.

Parameters

sendsint

Emails sent in a month. Defaults to 0.

domainsint

Domains you send from. Defaults to 1.

peopleint

People who use the workspace. Defaults to 1.

ai_actionsint

AI actions in a day, such as drafts, rewrites and summaries. Defaults to 0.

intervalBillingInterval

How you pay: 'month' or 'year'. Defaults to 'month'.

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

CostEstimateResource with the interval, the need that was priced with its defaults filled in, every plan in plans with fits, blockers, baseCents, extraSends, sendsCents, extraAiActions, aiCents, extrasCents and totalCents, and cheapest, the plan id of the cheapest one that fits or None.

Example

from nextmail import nextmail estimate = nextmail.tools.estimate_cost(sends=25000, domains=2, people=4, ai_actions=30) for plan in estimate['plans']:    if plan['plan'] == estimate['cheapest']:        print(plan['name'], plan['totalCents'])

Notes

  • Needs no scope: any key or access token for the workspace may run it.

  • It prices the plans as they are sold today and reads nothing in the workspace.

Also available in

API
GET /tools/cost
TypeScript
nextmail.tools.estimateCost()
Ruby
tools.estimate_cost
PHP
tools->estimateCost
Go
Tools.EstimateCost
Java
tools().estimateCost
C#
Tools.EstimateCostAsync
CLI
nextmail tools estimate-cost

tools.check_address()

Check an email address

No scope
Signature
def check_address(    email: str,    *,    deep: bool | None = None,    api_key: str | None = None,    timeout: float | None = None,) -> AddressCheckResource

Says whether an address is worth sending to, the email checker on the Nextmail website: result is 'valid', 'risky', 'invalid' or 'unknown', and reasons says why. It checks the syntax, whether the domain takes mail at all, whether it is a throwaway domain or a shared address such as info@, and offers a correction in suggestion for a likely typo such as gmial.com. Run it on a sign-up form before the first message, or over a list before a broadcast.

With the emails:read scope, workspace also says what this workspace knows: whether it suppressed the address and when it last delivered to it or saw it bounce. It never shows another workspace's history, and without the scope it is None.

deep also asks whether the mailbox itself exists, in checks['mailbox']. A deep check is billed per address through pay as you go and needs the emails:send scope. Without it the check is free and checks['mailbox'] is None.

Parameters

emailstrRequired

The address to check, such as 'ada@acme.com'.

deepbool

Also ask whether the mailbox exists. Billed per address through pay as you go. Defaults to False.

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

AddressCheckResource with email, normalized, result, reasons, suggestion, checks, workspace and checkedAt.

Example

from nextmail import nextmail check = nextmail.tools.check_address('ada@gmial.com') if check['result'] != 'valid':    print(check['reasons'], check['suggestion'])

Notes

  • Needs no scope without deep: any key or access token for the workspace may run it.

  • An address whose syntax is wrong is not an error: it returns with result 'invalid' and the reason 'invalid_syntax'.

  • With deep, a workspace where pay as you go is off, paused or not part of the plan is 409 deep_check_unavailable, a check that would pass its monthly limit is 409 deep_check_limit_reached, and a mailbox check that did not answer is 503 deep_check_unavailable. Nothing is billed for any of them.

  • 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 /tools/address
TypeScript
nextmail.tools.checkAddress()
Ruby
tools.check_address
PHP
tools->checkAddress
Go
Tools.CheckAddress
Java
tools().checkAddress
C#
Tools.CheckAddressAsync
CLI
nextmail tools check-address

tools.check_addresses()

Check several email addresses

No scope
Signature
def check_addresses(    body: AddressesCheck,    *,    api_key: str | None = None,    timeout: float | None = None,) -> AddressCheckListResource

Checks up to 100 addresses in one call, each as check_address does, and returns them in the order they were sent. Use it to clean a list before importing it or sending a broadcast to it.

deep applies to every address and is billed for each one that reaches the mailbox check, through pay as you go, and needs the emails:send scope.

Parameters

body['emails']list[str]Required

The addresses to check, a list of 1 to 100 strings.

body['deep']bool

Also ask whether each mailbox exists. Billed per address through pay as you go. Defaults to False.

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

AddressCheckListResource, a dict with one AddressCheckResource per address in data, in the order they were sent.

Example

from nextmail import nextmail checks = nextmail.tools.check_addresses({'emails': ['ada@acme.com', 'info@example.org']}) safe = [check['email'] for check in checks['data'] if check['result'] == 'valid'] print(safe)

Notes

  • Needs no scope without deep: any key or access token for the workspace may run it.

  • More than 100 addresses, or none, is 422 invalid_parameter on emails.

  • It changes nothing, so it is safe to run again, but the SDK does not retry a POST.

Also available in

API
POST /tools/addresses
TypeScript
nextmail.tools.checkAddresses()
Ruby
tools.check_addresses
PHP
tools->checkAddresses
Go
Tools.CheckAddresses
Java
tools().checkAddresses
C#
Tools.CheckAddressesAsync
CLI
nextmail tools check-addresses