API Overview
What the TrekMail API does, how authentication works, and which plans include API access.
Article details
Type, difficulty, plans, and last updated info.
▼
Article details
Type, difficulty, plans, and last updated info.
- Type
- Reference
- Difficulty
- Intermediate
- Plans
- Starter · Pro · Agency
- Last updated
- Apr 29, 2026
The TrekMail API lets you manage domains, mailboxes, forwarding, DNS, email migrations, and full webmail operations — read, send, draft, schedule, folder management, contacts, calendar, identities, templates, and blocked senders — from any HTTP client or AI agent. Every request uses a bearer token, every response is JSON, and every action is audited.
What you get
- REST API v1 with JSON request/response format.
- Bearer token authentication — no cookies, no sessions.
- Idempotency keys on mutating requests to prevent duplicate operations.
- Per-token rate limiting with
Retry-Afterheaders. - Audit log visible in your dashboard under AI Agents & API → Audit Log.
- MCP server with 181 tools, including 38 Drive tools for files, folders, uploads, share links, bulk operations, and read-only Drive Add-on status.
- Dual-token architecture — separate ops tokens for infrastructure and message tokens for full email operations (read, send, draft, schedule, contacts, calendar, identities, templates, folders, and more).
Drive API and file automation
Drive is now part of the public API surface. The Drive API adds 39 REST endpoints for Account Drive and mailbox Drive: spaces, usage, folder browsing, uploads, file and folder management, Trash, bulk actions, public share links, and read-only Drive Storage Add-on status.
Drive uses nine ops-token scopes: drive:account:read, drive:account:write, drive:account:share, drive:account:purge, drive:mailbox:read, drive:mailbox:write, drive:mailbox:share, drive:mailbox:purge, and drive:addon:read. Billing actions for the Drive Add-on — purchase, resize, and cancel — remain dashboard-only and are not exposed as API or MCP write operations.
Start with Drive API Overview or the Drive API Quickstart.
Dual-token architecture
The API uses two independent token types. You can use one or both depending on your needs:
| Token type | Prefix | What it unlocks |
|---|---|---|
| Ops token | tm_live_ |
Infrastructure tools — domains, DNS, mailboxes, invites, forwarding, delete intents, migrations, SMTP, tickets, account, billing, Cloudflare |
| Message token | tm_msg_ |
Full webmail API — messages, folders, attachments, drafts, scheduled send, spam/ham reporting, bulk actions, contacts, contact groups, calendar, compose helpers (reply/forward), identities, templates, blocked senders |
Ops tokens and message tokens have separate scopes and separate rate limits. A single agent can use both tokens simultaneously by configuring them in the MCP server environment.
Message tokens are available on Pro and Agency plans.
Before you start
- All plans have API access. Nano plans can use the Email Verifier API (
verify:read,verify:write). Starter plans add read-only infrastructure scopes plus verifier. Pro and Agency plans get full read/write access. - Create a token in AI Agents & API → Tokens → Create token.
- New to the API? Click the Guide button at the top of the AI Agents & API page for an interactive walkthrough of the dashboard — it covers connection methods, token management, and the audit log in about 60 seconds.
How authentication works
Every request must include your token in the Authorization header:
Authorization: Bearer tm_live_abc123...
Ops tokens start with tm_live_ and message tokens start with tm_msg_. Both are shown once at creation. TrekMail stores only the SHA-256 hash — the plaintext cannot be recovered.
If the token is missing, revoked, or expired, the API returns 401 with an unauthenticated error code.
Base URL and versioning
All endpoints live under:
https://trekmail.net/api/v1
The base URL is shown on your AI Agents & API dashboard under Quick Reference. The version is in the URL path. When a v2 is introduced (if ever), v1 will continue to work.
Response format
Successful responses return JSON with a data key for single resources or a paginated list:
{
"data": [
{ "id": 1, "domain": "example.com", "status": "active" }
],
"links": { "next": "...", "prev": null },
"meta": { "current_page": 1, "last_page": 1, "total": 1 }
}
Error responses follow a consistent structure:
{
"error": {
"code": "unauthenticated",
"message": "Invalid or expired API token",
"hint": "Check that your token is correct and has not been revoked.",
"request_id": "req_abc123",
"retryable": false
}
}
Request IDs
Every response includes an X-Request-Id header. You can also pass your own via X-Request-Id in the request — it will be echoed back and logged in the audit trail.
Rate limits
Each token is rate-limited per minute. When you hit the limit, the API returns 429 with a Retry-After header indicating when you can retry.
Destructive operations (delete intents) have an additional daily limit per token and a cooldown between consecutive deletes.
Migration write operations (start, cancel, retry) have a dedicated rate limit of 10 requests per minute per token, plus a server-wide concurrency cap that returns 503 when too many migrations are running globally.
Idempotency
All POST and PUT requests require an Idempotency-Key header. If you send the same key with the same body, the API replays the original response without creating duplicates.
Idempotency-Key: create-mailbox-alice-2024
If you send the same key with a different body, the API returns 409 Conflict.
Mailbox storage allocation
Every endpoint that creates a mailbox or invite — POST /api/v1/mailboxes, /api/v1/mailboxes:bulk, /api/v1/mailboxes/invites, /api/v1/mailboxes/invites:bulk — accepts an optional storage_allocation_mb integer.
| Value | Meaning |
|---|---|
Omitted (or null) |
Mailbox uses the shared account pool (default). |
| Positive integer (MB) | Mailbox is dedicated — that exact amount is carved out of the account pool just for this mailbox. |
Allocations are validated against the live pool minus existing dedicated mailboxes and pending dedicated invites. Bulk endpoints additionally validate the sum of allocations across the batch and reject the entire batch with 422 storage_pool_exceeded if it would over-commit. The pool refreshes when a dedicated mailbox is deleted, when an invite is redeemed (allocation moves to the new mailbox), and when a pending invite expires.
For invites the allocation is recorded on the access code and copied onto the new mailbox at redeem time. If the pool no longer fits the requested allocation at redeem time (e.g. another admin grew their dedicated allocation in the interim), the redeem gracefully downgrades the new mailbox to shared rather than failing — the recipient sees a notice on the success page.
Available endpoints
| Endpoint | Method | Scope Required |
|---|---|---|
/api/v1/domains |
GET | domains:read |
/api/v1/domains/{id} |
GET | domains:read |
/api/v1/domains/{id}/dns-requirements |
GET | domains:dns:read |
/api/v1/domains/{id}/dns-recheck |
POST | domains:dns:recheck |
/api/v1/domains/{id}/spam-metrics |
GET | domains:read |
/api/v1/domains/{id}/spam-metrics/summary |
GET | domains:read |
/api/v1/dns-checks/{id} |
GET | domains:dns:read |
/api/v1/mailboxes |
GET | mailboxes:read |
/api/v1/mailboxes |
POST | mailboxes:create |
/api/v1/mailboxes/invites |
POST | mailboxes:invites:create |
/api/v1/mailboxes/invites:bulk |
POST | mailboxes:invites:create |
/api/v1/mailboxes:bulk |
POST | mailboxes:create |
/api/v1/mailboxes/{id}/forwarding |
GET | mailboxes:forwarding:read |
/api/v1/mailboxes/{id}/forwarding |
PUT | mailboxes:forwarding:write |
/api/v1/mailboxes/{id}/rules |
GET | mailboxes:rules:read |
/api/v1/mailboxes/{id}/rules |
POST | mailboxes:rules:write |
/api/v1/mailboxes/{id}/rules/{ruleId} |
GET | mailboxes:rules:read |
/api/v1/mailboxes/{id}/rules/{ruleId} |
PUT | mailboxes:rules:write |
/api/v1/mailboxes/{id}/rules/{ruleId} |
DELETE | mailboxes:rules:write |
/api/v1/mailboxes/{id}/rules/reorder |
PATCH | mailboxes:rules:write |
/api/v1/mailboxes/{id}/auto-reply |
GET | mailboxes:auto-reply:read |
/api/v1/mailboxes/{id}/auto-reply |
PUT | mailboxes:auto-reply:write |
/api/v1/mailboxes/{id}/sieve |
GET | mailboxes:rules:read |
/api/v1/mailboxes/{id}/sieve |
PUT | mailboxes:rules:write |
/api/v1/mailboxes/{id}:delete-intent |
POST | mailboxes:delete |
/api/v1/delete-intents/{id}:confirm |
POST | mailboxes:delete |
/api/v1/me |
GET | (any valid ops token) |
/api/v1/mailboxes/{id}/message-tokens |
POST | mailboxes:message-tokens:manage |
/api/v1/mailboxes/{id}/message-tokens |
GET | mailboxes:message-tokens:manage |
/api/v1/message-tokens/{id} |
DELETE | mailboxes:message-tokens:manage |
/api/v1/messages |
GET | messages:read (message token) |
/api/v1/messages/{uid} |
GET | messages:read (message token) |
/api/v1/messages/{uid} |
PATCH | messages:write (message token) |
/api/v1/messages/send |
POST | messages:send (message token) |
/api/v1/messages/_ping |
GET | messages:read (message token, diagnostic) |
/api/v1/messages/{uid}/attachments/{index} |
GET | messages:read (message token) |
/api/v1/messages/{uid}/attachments |
GET | messages:read (message token) |
/api/v1/messages/{uid}/raw |
GET | messages:read (message token) |
/api/v1/messages/folders |
POST | messages:write (message token) |
/api/v1/messages/folders/{path} |
PATCH | messages:write (message token) |
/api/v1/messages/folders/{path} |
DELETE | messages:write (message token) |
/api/v1/messages/{uid}:spam |
POST | messages:write (message token) |
/api/v1/messages/{uid}:ham |
POST | messages:write (message token) |
/api/v1/messages:bulk |
POST | messages:write (message token) |
/api/v1/messages/folders:empty |
POST | messages:write (message token) |
/api/v1/messages/drafts |
POST | messages:write (message token) |
/api/v1/messages/drafts/{uid} |
PUT | messages:write (message token) |
/api/v1/messages/scheduled |
POST | messages:send (message token) |
/api/v1/messages/scheduled |
GET | messages:read (message token) |
/api/v1/messages/scheduled/{id} |
DELETE | messages:send (message token) |
/api/v1/messages/contacts |
GET | messages:read (message token) |
/api/v1/messages/contacts |
POST | messages:write (message token) |
/api/v1/messages/contacts/{id} |
PATCH | messages:write (message token) |
/api/v1/messages/contacts/{id} |
DELETE | messages:write (message token) |
/api/v1/messages/contacts:import |
POST | messages:write (message token) |
/api/v1/messages/contacts:export |
GET | messages:read (message token) |
/api/v1/messages/calendar/events |
GET | messages:read (message token) |
/api/v1/messages/calendar/events |
POST | messages:write (message token) |
/api/v1/messages/calendar/events/{id} |
PATCH | messages:write (message token) |
/api/v1/messages/calendar/events/{id} |
DELETE | messages:write (message token) |
/api/v1/messages/{uid}/reply |
GET | messages:read (message token) |
/api/v1/messages/{uid}/reply-all |
GET | messages:read (message token) |
/api/v1/messages/{uid}/forward |
GET | messages:read (message token) |
/api/v1/messages/contact-groups |
POST | messages:write (message token) |
/api/v1/messages/contact-groups/{id} |
PATCH | messages:write (message token) |
/api/v1/messages/contact-groups/{id} |
DELETE | messages:write (message token) |
/api/v1/messages/contact-groups/{id}/members |
POST | messages:write (message token) |
/api/v1/messages/contact-groups/{id}/members |
DELETE | messages:write (message token) |
/api/v1/messages/identities |
GET | messages:read (message token) |
/api/v1/messages/identities |
POST | messages:write (message token) |
/api/v1/messages/identities/{id} |
PATCH | messages:write (message token) |
/api/v1/messages/identities/{id} |
DELETE | messages:write (message token) |
/api/v1/messages/templates |
GET | messages:read (message token) |
/api/v1/messages/templates |
POST | messages:write (message token) |
/api/v1/messages/templates/{id} |
PATCH | messages:write (message token) |
/api/v1/messages/templates/{id} |
DELETE | messages:write (message token) |
/api/v1/messages/blocked-senders |
GET | messages:read (message token) |
/api/v1/messages/blocked-senders |
POST | messages:write (message token) |
/api/v1/messages/blocked-senders/{id} |
DELETE | messages:write (message token) |
/api/v1/mailboxes/{id}/enable-imap |
POST | mailboxes:write (ops token) |
/api/v1/migrations/test-connection |
POST | migrations:write |
/api/v1/migrations |
GET | migrations:read |
/api/v1/migrations/{id} |
GET | migrations:read |
/api/v1/migrations |
POST | migrations:write |
/api/v1/migrations/{id}:cancel |
POST | migrations:write |
/api/v1/migrations/{id}:retry |
POST | migrations:write |
/api/v1/migrations/{id} |
DELETE | migrations:write |
/api/v1/migrations/bulk/preview |
POST | migrations:write |
/api/v1/migrations/bulk |
POST | migrations:write |
/api/v1/migrations/bulk |
GET | migrations:read |
/api/v1/migrations/bulk/{batch} |
GET | migrations:read |
/api/v1/migrations/bulk/{batch}:cancel |
POST | migrations:write |
/api/v1/migrations/bulk/{batch}:retry |
POST | migrations:write |
/api/v1/migrations/bulk/{batch}:resume |
POST | migrations:write |
/api/v1/migrations/bulk/{batch} |
DELETE | migrations:write |
/api/v1/migrations/bulk/{batch}/jobs/{job}/password |
PATCH | migrations:write |
/api/v1/account |
GET | account:read |
/api/v1/billing/status |
GET | billing:read |
/api/v1/billing/invoices |
GET | billing:read |
/api/v1/domains |
POST | domains:create |
/api/v1/domains/{id} |
DELETE | domains:delete |
/api/v1/domains/{id}/catch-all |
PATCH | domains:write |
/api/v1/domains/{id}/dkim:retry |
POST | domains:write |
/api/v1/domains/{id}/note |
PATCH | domains:write |
/api/v1/domains:bulk-add |
POST | domains:create |
/api/v1/mailboxes/{id} |
GET | mailboxes:read |
/api/v1/mailboxes/{id}/password |
POST | mailboxes:write |
/api/v1/mailboxes/{id}/note |
PATCH | mailboxes:write |
/api/v1/mailboxes/{id}:pause |
POST | mailboxes:write |
/api/v1/mailboxes/{id}:resume |
POST | mailboxes:write |
/api/v1/tickets |
GET | tickets:read |
/api/v1/tickets/{id} |
GET | tickets:read |
/api/v1/tickets/{id}/messages |
GET | tickets:read |
/api/v1/tickets |
POST | tickets:write |
/api/v1/tickets/{id}/reply |
POST | tickets:write |
/api/v1/tickets/{id}:close |
POST | tickets:write |
/api/v1/smtp |
GET | smtp:read |
/api/v1/smtp |
PUT | smtp:write |
/api/v1/smtp/{id} |
DELETE | smtp:write |
/api/v1/smtp:test |
POST | smtp:write |
/api/v1/smtp:test-status/{jobId} |
GET | smtp:read |
/api/v1/messages/{uid} |
DELETE | messages:write (message token) |
/api/v1/messages/{uid}:move |
POST | messages:write (message token) |
/api/v1/messages/folders |
GET | messages:read (message token) |
/api/v1/aliases |
GET | mailboxes:read |
/api/v1/aliases |
POST | mailboxes:write |
/api/v1/aliases/{id} |
PATCH | mailboxes:write |
/api/v1/aliases/{id} |
DELETE | mailboxes:write |
/api/v1/verify |
POST | verify:write |
/api/v1/verify/bulk |
POST | verify:write |
/api/v1/verify/bulk/{jobId} |
GET | verify:read |
/api/v1/verify/bulk/{jobId}/download |
GET | verify:read |
/api/v1/verify/credits |
GET | verify:read |
/api/v1/verify/bulk |
GET | verify:read |
/api/v1/verify/bulk/{jobId}/cancel |
POST | verify:write |
/api/v1/verify/bulk/{jobId} |
DELETE | verify:write |
/api/v1/cloudflare/validate-token |
POST | cloudflare:read |
/api/v1/cloudflare/zones |
POST | cloudflare:read |
/api/v1/cloudflare/connect |
POST | cloudflare:write |
/api/v1/cloudflare/preview |
POST | cloudflare:read |
/api/v1/cloudflare/apply |
POST | cloudflare:write |
/api/v1/cloudflare/tokens |
GET | cloudflare:read |
/api/v1/cloudflare/tokens/{id} |
DELETE | cloudflare:delete |
Internal support endpoints (HMAC auth)
These endpoints use HMAC-SHA256 authentication (not bearer tokens) and are used by the AI support pipeline:
| Endpoint | Method | Auth |
|---|---|---|
/api/v1/support/reply |
POST | HMAC |
/api/v1/support/messages/{id} |
PUT | HMAC |
/api/v1/support/messages/{id} |
DELETE | HMAC |
The OpenAPI specification is available at /api/openapi.json for import into Postman, Insomnia, or code generators.
Quick fixes
- 401 "unauthenticated": Check that the
Authorization: Bearer <token>header is present and the token has not been revoked or expired. - 403 "plan_api_disabled": The requested scope is not available on your plan. Nano plans can only access Email Verifier endpoints. Upgrade for broader access.
- 403 "token_scope_blocked_by_plan": Your token has scopes that are not available on your current plan. Revoke the token and create a new one with allowed scopes.
- 422 "missing_idempotency_key": Add an
Idempotency-Keyheader to POST and PUT requests. - 429 rate limited: Wait for the duration in the
Retry-Afterheader before retrying.
Related articles
Jump to nearby guides that continue the workflow.