Errors
Envelope
Failures return a non-2xx status and a JSON body:
{
"error": "invalid_body",
"message": "human-readable explanation",
"details": { "...": "optional, e.g. a Zod flatten of field issues" },
"requestId": "..."
}
The requestId also comes back as the x-request-id response header. Quote it when
reporting an issue — it matches the API server's logs.
SDK: TmmError
The SDK throws TmmError for every failure (including transport errors), so you
catch one type:
import { TmmError } from "@thatsmymail/sdk";
try {
await tmm.v1.services.sendEmail({ /* … */ });
} catch (err) {
if (err instanceof TmmError) {
console.error(err.code, err.status, err.message, err.details, err.requestId);
} else {
throw err;
}
}
Codes
code |
status |
Meaning |
|---|---|---|
network_error |
0 | Request never reached the server (DNS, connection refused, timeout). SDK-only. |
unauthorized |
401 | Bad/missing keyId/secret, or the timestamp is outside the ±5-minute window. |
forbidden |
403 | The key lacks the required scope, or the recipient is suppressed. |
invalid_body |
400 | Validation failed; details carries the field issues. |
sender_domain_not_verified |
400 | The from domain isn't a verified sender domain for the project. |
not_found |
404 | The resource doesn't exist, or belongs to another organization. |
rate_limited |
429 | Per-key request rate exceeded (default 100 req/min). retryAt says when to retry. |
quota_exceeded |
429 | The project's organization hit its free daily allowance (500 accepted messages/day, shared across the org's projects). Upgrade the org to pay-as-you-go to keep sending. |
http_error |
5xx | Unexpected server error — check the platform logs with the requestId. |
Behavior notes
v1.services.sendEmail()is fire-and-forget at the SMTP layer: a200means queued, not delivered. Pollv1.messages.get(id)untilstatusis terminal (delivered/bounced/failed/suppressed).- The SDK does not retry. On
network_error, wrap calls in your own retry-with-backoff and reuse the sameidempotencyKeyso a retried send doesn't double-deliver (24h dedupe window).