Skip to content
Skip to main content

Idempotent send requests

Nylas’s send endpoints accept an Idempotency-Key header so you can safely retry a send without delivering the same message twice. This is the cornerstone for any send pipeline that retries automatically: workflow engines, background queues that redeliver on worker crash, or client code that retries after a network blip.

Both send endpoints accept the same Idempotency-Key header with the same semantics:

  • Grant-based send: POST /v3/grants/{grant_id}/messages/send (API reference)
  • Transactional send (Beta): POST /v3/domains/{domain_name}/messages/send (API reference)

Generate a unique key per logical send (a UUID v4 is a safe choice) and pass it in the Idempotency-Key header:

  • Max length: 256 characters.
  • Uniqueness: a key represents one logical send. Generate a fresh key for each new message.
  • Format: any string up to 256 characters.

When Nylas returns a cached response, the body and status code are identical to the original response, and the Idempotent-Response header is set to true. Check this header to tell whether the provider was actually contacted on this request:

HTTP/1.1 200 OK
Idempotent-Response: true
Content-Type: application/json
{ "data": { ... }, "request_id": "..." }

The first request through a key never has this header set; only retries that hit the cache do.

  • TTL: keys are valid for 1 hour after the first request. Once the TTL elapses, the key can be reused freely.
  • Grant-based send is scoped per grant. The same key under two different grants creates two independent cache entries.
  • Transactional send is scoped per Nylas application.
StatusError typeWhen it happens
400api.invalid_idempotency_keyThe Idempotency-Key header is longer than 256 characters.
409api.invalid_idempotent_requestA previous request used the same key with a different payload.
409api.concurrent_idempotent_requestA request with the same key is currently in flight.

Error response bodies follow the standard Nylas error shape (request_id, error.type, error.message). For the full error schema, see Sending errors.

Use this table to decide whether to reuse the original key or generate a new one:

ResponseRetry withNotes
Network failure (no response received)Same keyThe cornerstone use case. The first request may or may not have reached Nylas. Retrying with the same key is safe.
409 api.concurrent_idempotent_requestSame keyWait a few seconds and try again. Another caller is processing the same logical send.
4xx other than api.concurrent_idempotent_requestDifferent keyThe request was rejected (bad payload, auth failure, validation error). Fix the underlying issue, then retry with a fresh key.
5xx from Nylas (not a provider error)Usually same keyRetry behavior here isn’t as well-defined — it depends on the error and when it happened (e.g. an uncaught exception, or upstream timeout can each leave the send in different states). It is recommended to evaluate the error type/message to determine retry behavior. As a general rule, retry with the same key. Example: Nylas returns a 504 Gateway Timeout however the provider completed the send but was delayed. Keep retrying with the same key until the real send response is echoed back. While the original request is still in flight you may see 409 api.concurrent_idempotent_request; once it settles, the cached response (success or error) is returned.
5xx provider errorDifferent keyThe provider rejected the message. Address the cause, then retry with a fresh key. Reusing the original key would just return the same error.
  • Idempotency is enforced at the Nylas layer only. Nylas does not propagate the key to downstream providers (Google, Microsoft, Yahoo, IMAP, EWS).
  • TTL is fixed at 1 hour so you should implement retries within this time period.