Documentation
API reference.
Pagination, rate limits, every endpoint, and every error.
Pagination and rate limits
Every list returns { "object": "list", "data": [...], "has_more": boolean }. Short collections (domains, API keys, templates, topics, segments, webhooks, broadcasts) return everything and has_more is always false. Long ones are paged: GET /emails and GET /logs take limit (1 to 100) and after, the id of the last item you received, and you continue while has_more is true; GET /contacts and GET /suppressions take page and limit and also return page and total.
import { MailClient } from "mailtruss";
const mail = new MailClient({ apiKey: process.env.MAILTRUSS_API_KEY! });
let after: string | undefined;
do {
const page = await mail.emails.list({ limit: 100, after });
for (const email of page.data) console.log(email.id, email.last_event);
after = page.has_more ? page.data.at(-1)!.id : undefined;
} while (after);
Requests are limited per organization to a number per second (5 by default). Every response, including errors, carries ratelimit-limit, ratelimit-remaining and ratelimit-reset (seconds until the one-second window resets) and an x-request-id. A request over the limit returns 429 with a retry-after header. Separately, your plan sets how many emails you can send per day and per month; hitting that returns 429 daily_quota_exceeded or monthly_quota_exceeded.
Endpoint reference
Sending endpoints work with both key types; everything else needs a full-access key. The same list is available as an OpenAPI 3.1 document you can load into any client generator.
| Method | Path | Does |
|---|---|---|
| POST | /api/v1/emails | Send an email |
| POST | /api/v1/emails/batch | Send up to 100 emails in one request |
| GET | /api/v1/emails | List emails |
| GET | /api/v1/emails/:id | Retrieve an email |
| PATCH | /api/v1/emails/:id | Reschedule a scheduled email |
| POST | /api/v1/emails/:id/cancel | Cancel a scheduled email |
| GET | /api/v1/emails/:id/events | Delivery timeline and diagnosis for an email |
| GET | /api/v1/domains | List domains |
| POST | /api/v1/domains | Add a domain |
| GET | /api/v1/domains/:id | Retrieve a domain and its DNS records |
| PATCH | /api/v1/domains/:id | Turn click and open tracking on or off (both off by default) |
| DELETE | /api/v1/domains/:id | Delete a domain |
| POST | /api/v1/domains/:id/verify | Check the domain's DNS now |
| GET | /api/v1/api-keys | List API keys |
| POST | /api/v1/api-keys | Create an API key (the token is shown once) |
| DELETE | /api/v1/api-keys/:id | Revoke an API key |
| GET | /api/v1/contacts | List contacts |
| POST | /api/v1/contacts | Create or update a contact by email |
| GET | /api/v1/contacts/:id | Retrieve a contact by id or email |
| PATCH | /api/v1/contacts/:id | Update a contact |
| DELETE | /api/v1/contacts/:id | Delete a contact |
| GET | /api/v1/segments | List segments |
| POST | /api/v1/segments | Create a segment |
| GET | /api/v1/segments/:id | Retrieve a segment |
| DELETE | /api/v1/segments/:id | Delete a segment |
| GET | /api/v1/topics | List topics |
| POST | /api/v1/topics | Create a topic |
| GET | /api/v1/templates | List templates |
| POST | /api/v1/templates | Create a template |
| GET | /api/v1/templates/:id | Retrieve a template |
| PATCH | /api/v1/templates/:id | Save a new (unpublished) version |
| DELETE | /api/v1/templates/:id | Delete a template |
| POST | /api/v1/templates/:id/publish | Publish a version |
| GET | /api/v1/broadcasts | List broadcasts |
| POST | /api/v1/broadcasts | Create a draft broadcast |
| GET | /api/v1/broadcasts/:id | Retrieve a broadcast with delivery stats |
| DELETE | /api/v1/broadcasts/:id | Delete a draft broadcast |
| POST | /api/v1/broadcasts/:id/send | Send now or schedule |
| POST | /api/v1/broadcasts/:id/cancel | Cancel a scheduled or sending broadcast |
| GET | /api/v1/suppressions | List suppressed addresses |
| POST | /api/v1/suppressions | Suppress an address |
| DELETE | /api/v1/suppressions/:id | Remove a bounce or manual entry (complaints and unsubscribes are permanent) |
| GET | /api/v1/webhooks | List webhook endpoints |
| POST | /api/v1/webhooks | Create an endpoint (the signing secret is shown once) |
| GET | /api/v1/webhooks/:id | Retrieve an endpoint |
| PATCH | /api/v1/webhooks/:id | Update an endpoint |
| DELETE | /api/v1/webhooks/:id | Delete an endpoint |
| POST | /api/v1/webhooks/:id/rotate-secret | Rotate the signing secret (the old one works for 24 hours) |
| GET | /api/v1/logs | List API request logs |
Errors
Every error has the same shape, and every response has an x-request-id header you can search in API logs.
{ "name": "validation_error", "message": "subject: Missing `subject` field.", "statusCode": 422 }- 403invalid_api_key
- The key does not exist, was revoked, or has expired. Create a new one under API keys.
- 401missing_api_key
- Send the key as Authorization: Bearer <key>.
- 401restricted_api_key
- This key is sending-only. Use a full-access key for this endpoint.
- 403domain_not_verified
- The from domain is not verified. Open Domains, publish the DNS records and re-check.
- 422validation_error
- Fix the field named in the message. The request was rejected before processing; no quota was used.
- 429rate_limit_exceeded
- Back off and retry after the Retry-After header. Use /emails/batch to send many messages in one request.
- 429daily_quota_exceeded
- The daily cap was reached. It resets at 00:00 UTC.
- 429monthly_quota_exceeded
- The plan's monthly limit was reached.
- 409invalid_idempotent_request
- That Idempotency-Key was already used with a different body. Use a new key for a new request.
- 409concurrent_idempotent_requests
- Another request with this key is still processing. Wait a moment and retry with the same key.
- 422invalid_scheduled_at
- Use an ISO 8601 date-time in the future, at most 30 days ahead.
- 404not_found
- No such resource in this organization.
- 403account_suspended
- This organization is suspended. Contact support.