Skip to the documentation
Python

Changelog

Every release of the package, newest first.

0.0.1

The first release of the Python package. It has a method for every one of the 684 methods of the TypeScript SDK, in 53 namespaces, each under its TypeScript name in snake_case, and a parity check in the package’s own build proves that every one sends the same request as its TypeScript twin.

  • Two clients with the same methods and arguments: Nextmail, which blocks, and AsyncNextmail, which is awaited and runs on asyncio and on trio. Each has an attribute for every namespace, from emails, threads and templates to automations, bookings and connected_mailboxes.
  • A request body is a dict whose keys keep the API’s camelCase names, the options of a call are snake_case keyword arguments such as idempotency_key= and limit=, and a response comes back as a dict. Every body, result and webhook payload has a TypedDict in nextmail.types, so a type checker catches a misspelt key.
  • A client takes an API key or an OAuth access token, or reads NEXTMAIL_API_KEY, NEXTMAIL_ACCESS_TOKEN and NEXTMAIL_BASE_URL. access_token= also takes a function that returns the token, called before every request, which may be async on AsyncNextmail. base_url, timeout, max_retries, headers, user_agent and http_client, your own httpx client, set the rest. Every method also takes timeout= for one call, and api_key=, or inbox_token= on temp_mail, to act with another credential.
  • from nextmail import nextmail is a ready-made client, built from the environment the first time it is touched, and init(...) configures it once at startup. create_temp_mail() and create_async_temp_mail() open disposable inboxes with no credential.
  • Every paginated resource has list for one page, list_all for every item as a list, and iterate, which yields each item and fetches the next page only when it gets there.
  • An API refusal raises NextmailApiError, with status, type, code, param, doc_url, request_id, retry_after_seconds and fields, and checks such as is_validation, is_not_found, is_rate_limited, is_step_up_required and is_retryable. No response at all raises NextmailNetworkError, with is_timeout when the deadline passed. Both derive from NextmailError, and a mistake in the call itself raises ValueError before anything is sent.
  • Reads, sends and every write that is safe to repeat are retried on 408, 500, 502, 503 and 504 with backoff, and on a 429 only when its Retry-After is a minute or less. A send carries an idempotency key that its retries reuse, so a retry never sends a second message. timeout bounds a whole attempt, the response body included, and uploads wait at least ten minutes.
  • verify_webhook_signature checks a delivery in constant time, refuses one more than five minutes old and returns the parsed event, or raises WebhookVerificationError.
  • The helpers of the TypeScript SDK are here too, such as to_base64 and resolve_language, and every value set it exports is a constant in nextmail.constants, such as WEBHOOK_EVENTS and API_SCOPES.
  • client.raw.request() reaches any endpoint with the client’s credential, base URL, timeout and retries, and a credential is never sent over plain HTTP, except to a server on this machine.
  • When a newer version is on PyPI, the client says so once, on a terminal only. disable_update_notice=True or NEXTMAIL_DISABLE_UPDATE_NOTICE=1 turns that off.
  • It needs Python 3.10 or newer and depends only on httpx, anyio and typing-extensions.