Overview
Developer overview
Base URL, authentication, object IDs, errors, pagination, rate limits, SDKs, webhooks and MCP. The conventions every Emailit integration shares.
This page collects the conventions you need before you write code against Emailit: where the API lives, how requests are authenticated, how objects are identified, and how errors, pagination and rate limits work. Each section links to the detailed reference.
Ways to integrate
| Interface | Endpoint | Use it for |
|---|---|---|
| REST API | https://api.emailit.com/v2 |
Sending email and managing every resource from code. |
| SMTP relay | smtp.emailit.com |
Apps, frameworks and CMSs that already speak SMTP. See SMTP settings. |
| Webhooks | Your HTTPS endpoint | Real-time delivery, engagement and resource events. |
| MCP server | https://api.emailit.com/mcp |
Letting AI assistants such as Claude, ChatGPT and Cursor work with your workspace. |
| OAuth 2.1 | https://api.emailit.com/oauth/* |
Integrations that act on behalf of Emailit users without handling their API keys. |
Not sure whether to use the API or SMTP? Read API or SMTP.
Base URL and versioning
All REST endpoints live under one base URL:
https://api.emailit.com/v2v2 is the current and only documented version. The legacy v1 API is deprecated; see Versioning.
Authentication
Send an API key as a bearer token in the Authorization header of every request:
curl https://api.emailit.com/v2/domains \
-H "Authorization: Bearer $EMAILIT_API_KEY"- API keys start with
secret_. Older keys without the prefix keep working. - Each key belongs to one workspace and has a scope: Full Access (
full) can call every endpoint, Sending Only (sending) can only send and manage sends. See API keys. - OAuth access tokens issued to OAuth apps are accepted in the same header.
- A missing key returns
401withAPI key required, an unknown key returns401withInvalid API key, and a suspended workspace returns403withWorkspace is suspended.
Never call the API from a browser or mobile app with your key. Keep it on your server. Details: Authentication.
IDs and prefixes
Every object has a string ID with a type prefix, so you can tell what an ID refers to at a glance.
| Object | Prefix | Example |
|---|---|---|
em_ |
em_4K6oASS7KP9ztzWmSN9ndEu13HW |
|
| Sending domain | dom_ |
dom_3xQ7mLp2RkT9vB4nHs8YcWd1Ze6 |
| API key | key_ |
key_4F2kN8sQwE1rT6yU3iO9pA7sD5f |
| Audience | aud_ |
aud_3zR8tY2uI6oP4aS1dF9gH7jK5lM |
| Subscriber | sub_ |
sub_4K6oASS7KP9ztzWnqS4svxApJzO |
| Contact | con_ |
con_4A9sD2fG6hJ1kL8zX3cV7bN5mQw |
| Template | tem_ |
tem_3wE8rT1yU5iO9pA2sD6fG4hJ7kL |
| Suppression | sup_ |
sup_4K6oASS7KP9ztzWol5ElicOeKFE |
| Webhook | wh_ |
wh_3mN7bV2cX6zL9kJ4hG1fD8sA5pO |
| Webhook request | whr_ |
whr_4K6oASS7KP9ztzWpVUIec9Jneax |
| Event | evt_ |
evt_4K6oASS7KP9ztzWpqId2iIptac5 |
| Campaign | cmp_ |
cmp_4B1nM5qW9eR3tY7uI2oP6aS8dF4 |
| Form | frm_ |
frm_4C3vB7nM1qW5eR9tY2uI6oP8aS4 |
| Form submission | fsub_ |
fsub_4K6oASS7KP9ztzWqvxLV3IsFRs8 |
| Automation | aut_ |
aut_4D5fG9hJ3kL7zX1cV6bN2mQ8wE4 |
| Automation run | aur_ |
aur_4K6oASS7KP9ztzWrWOjGgqompRo |
| Email verification | ev_ |
ev_4E7gH1jK5lZ9xC3vB8nM2qW6eR4 |
| Verification list | evl_ |
evl_4F9hJ3kL7zX1cV5bN9mQ2wE6rT8 |
| DMARC report | dmr_ |
dmr_4K6oASS7KP9ztzWsW7e5qkOYHO6 |
Domains created before the switch to dom_ IDs can still have sd_ or sed_ IDs.
Some endpoints also accept a human-readable identifier in place of the ID: a name for API keys, domains, webhooks, campaigns and audiences, and an email address for contacts and suppressions. Emails, templates and events are looked up by ID only.
Requests and responses
- JSON in, JSON out. Send request bodies as JSON with
Content-Type: application/json. Malformed JSON returns400withInvalid JSON in request body. A request body can be up to 50 MB; an email’s final MIME message can be up to 40 MB. - Errors. Most errors return
{"statusCode", "error", "message"}. Validation errors add adetailsarray, and sending errors returnvalidation_errors. Plan-gated features return403with"error": "plan_required". See Errors. - Pagination. List endpoints take
pageandlimit(1 to 100) and returndata,next_page_urlandprevious_page_url. Templates and automations usepageandper_page. See Pagination. - Filtering and sorting. Filter with
field.condition=value, combine filters withmatch=allormatch=or, and sort withorderanddirection. For example,GET /v2/emails?status.exact=bounced&order=created_at&direction=desc. See Filtering. - Idempotency. Send an
Idempotency-Keyheader onPOST /emailsandPOST /emails/:id/forwardto make retries safe. Emailit replays the first response for 24 hours. See Idempotency. - Rate limits. Sending is limited per workspace, by default to 2 emails per second and 5,000 emails per day, shared between the API and SMTP. Responses include
ratelimit-*headers, and a429includesretry-after. See Rate limits and Limits.
SDKs
Official libraries wrap the REST API for Node.js, PHP, Laravel, Python, Ruby, Go, Java, .NET and Rust. They all live on GitHub. See SDKs and libraries for install commands, and the framework guides for complete examples, starting with Node.js.
Webhooks
Webhooks push events to your endpoint as they happen: deliveries, bounces, opens, clicks, inbound mail, and changes to domains, contacts and other resources. Each request carries a JSON array of up to 100 events and is signed with HMAC-SHA256 in the X-Emailit-Signature header. Failed requests are retried for up to 11 attempts. Start with Set up a webhook and Request signature.
MCP server and AI tools
The hosted MCP server at https://api.emailit.com/mcp gives AI assistants 109 tools covering the full API v2, from sending email to campaigns and automations. Assistants sign in with OAuth or an API key, and the Emailit plugins add skills for ChatGPT, Codex, Claude Code, Cursor and Grok.
The docs are also published for AI: every page has a Markdown version, and /docs/llms.txt indexes them all.