Skip to content

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.

Walking every email
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.

API endpoints
MethodPathDoes
POST/api/v1/emailsSend an email
POST/api/v1/emails/batchSend up to 100 emails in one request
GET/api/v1/emailsList emails
GET/api/v1/emails/:idRetrieve an email
PATCH/api/v1/emails/:idReschedule a scheduled email
POST/api/v1/emails/:id/cancelCancel a scheduled email
GET/api/v1/emails/:id/eventsDelivery timeline and diagnosis for an email
GET/api/v1/domainsList domains
POST/api/v1/domainsAdd a domain
GET/api/v1/domains/:idRetrieve a domain and its DNS records
PATCH/api/v1/domains/:idTurn click and open tracking on or off (both off by default)
DELETE/api/v1/domains/:idDelete a domain
POST/api/v1/domains/:id/verifyCheck the domain's DNS now
GET/api/v1/api-keysList API keys
POST/api/v1/api-keysCreate an API key (the token is shown once)
DELETE/api/v1/api-keys/:idRevoke an API key
GET/api/v1/contactsList contacts
POST/api/v1/contactsCreate or update a contact by email
GET/api/v1/contacts/:idRetrieve a contact by id or email
PATCH/api/v1/contacts/:idUpdate a contact
DELETE/api/v1/contacts/:idDelete a contact
GET/api/v1/segmentsList segments
POST/api/v1/segmentsCreate a segment
GET/api/v1/segments/:idRetrieve a segment
DELETE/api/v1/segments/:idDelete a segment
GET/api/v1/topicsList topics
POST/api/v1/topicsCreate a topic
GET/api/v1/templatesList templates
POST/api/v1/templatesCreate a template
GET/api/v1/templates/:idRetrieve a template
PATCH/api/v1/templates/:idSave a new (unpublished) version
DELETE/api/v1/templates/:idDelete a template
POST/api/v1/templates/:id/publishPublish a version
GET/api/v1/broadcastsList broadcasts
POST/api/v1/broadcastsCreate a draft broadcast
GET/api/v1/broadcasts/:idRetrieve a broadcast with delivery stats
DELETE/api/v1/broadcasts/:idDelete a draft broadcast
POST/api/v1/broadcasts/:id/sendSend now or schedule
POST/api/v1/broadcasts/:id/cancelCancel a scheduled or sending broadcast
GET/api/v1/suppressionsList suppressed addresses
POST/api/v1/suppressionsSuppress an address
DELETE/api/v1/suppressions/:idRemove a bounce or manual entry (complaints and unsubscribes are permanent)
GET/api/v1/webhooksList webhook endpoints
POST/api/v1/webhooksCreate an endpoint (the signing secret is shown once)
GET/api/v1/webhooks/:idRetrieve an endpoint
PATCH/api/v1/webhooks/:idUpdate an endpoint
DELETE/api/v1/webhooks/:idDelete an endpoint
POST/api/v1/webhooks/:id/rotate-secretRotate the signing secret (the old one works for 24 hours)
GET/api/v1/logsList 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.

422
{ "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.