EterMail API (v1)
Sync users and events from your server into an EterMail project. Fields follow the Segment spec; SaaS products and mobile apps both connect through this API.
OpenAPI spec, SDK and MCP server on GitHub ↗github.com/EterMail/etermail-api: the full API as OpenAPI 3.1, a zero-dependency JavaScript/TypeScript SDK, an MCP server for Claude and Cursor, and examples. Install the SDK with npm install @etermail/sdk; run the MCP server with npx -y @etermail/mcp.Authentication
Create a server-side (sk_) key under Project settings → API keys. It is shown once and must only be used on your server, never in a browser or app. The key determines which project receives the data. Segment-style Basic auth also works (the key as username, empty password).
Authorization: Bearer sk_…
General rules
- messageId is required and unique per project; a repeat returns {"ok":true,"duplicate":true}, so retries are safe.
- timestamp is optional (ISO 8601), for backfilling history.
- Provide userId (your user ID), email, or both; userId takes precedence as the identity.
- 600 requests per minute per key; beyond that you get 429 with Retry-After. Request bodies up to 1 MB.
POST /api/v1/identify
Creates or updates a contact. firstName, lastName, locale and timezone in traits map to fixed fields (language or lang also set locale when locale is absent; tags like de or pt-BR); everything else becomes a custom attribute. consent is optional: subscribing requires evidence of when and how the person agreed, and the API cannot resubscribe someone who unsubscribed.
curl https://etermail.ai/api/v1/identify \
-H "Authorization: Bearer sk_…" \
-H "Content-Type: application/json" \
-d '{
"userId": "u_123",
"messageId": "4f9c…",
"traits": { "email": "[email protected]", "firstName": "Ann", "plan": "pro" },
"consent": { "topic": "marketing", "status": "subscribed",
"evidence": { "form": "signup", "checkbox": true } }
}'POST /api/v1/track
Records an event for segmentation and attribution, and to trigger custom-event flows (for example, onboarding emails after a trial starts).
{ "userId": "u_123", "event": "Trial Started",
"properties": { "plan": "pro" }, "messageId": "9a1e…" }POST /api/v1/batch
Up to 500 identify / track calls at once, processed one by one with a results array; a failed item does not affect the others.
{ "batch": [
{ "type": "identify", "userId": "u_123", "messageId": "…" },
{ "type": "track", "userId": "u_123", "event": "Logged In", "messageId": "…" }
] }Signup form submissions (public)
POST /api/forms/{publicId}/submit needs no key and lets your own website form submit directly; the request origin must be listed under the form's allowed websites. With double opt-in it returns check_email.