API reference
Transactional email and marketing campaigns for your workspace. Authenticated requests use a Bearer API key from Developer → API keys. Base URL: https://api.eimailar.com
Getting started
- Claim your invitation, set your password, verify your email, and sign in to your customer workspace.
- Add a transactional sending domain. Publish the DNS records shown for that domain and wait for both DNS and the sending provider to confirm it.
- Open Settings, choose Plan & usage, and submit your sending review with your website and use case.
- In Developer → API keys, create a key with the
sendscope. Copy the secret when it appears and store it in your server's secret manager; it cannot be viewed again. - Send from your server using an address on the exact verified transactional domain. Use a distinct idempotency key for each business event. A
201 queuedresponse means the message entered the queue; check Emails for its delivery outcome.
Authentication
Authenticated API requests need a Bearer API key. Store it in your service as EIMAILAR_API_KEY and send it in theAuthorization header:
This endpoint is for transactional email only. Use Campaigns for marketing email so consent, suppression, sender identity, and unsubscribe controls are applied automatically.
curl https://api.eimailar.com/v1/emails \
-H "Authorization: Bearer $EIMAILAR_API_KEY" \
-H "Idempotency-Key: signup-<your-event-id>" \
-H "Content-Type: application/json" \
-d '{"from":"you@send.yourdomain.com","to":"user@example.com",
"subject":"Hello","html":"<p>It works.</p>",
"transactional":{"category":"account","trigger_id":"signup-<your-event-id>",
"recipient_relationship":"account_holder"}}'Replace the sender domain, recipient, and event ID with your own values. Use the same event ID on retries.
Emails
Send transactional email and read its delivery timeline.
/v1/emailsSend a transactional emailQueues a transactional email. Production requests must attest the business trigger and recipient relationship in `transactional`. Marketing email must use the campaign API so audience consent, suppression, sender identity, and unsubscribe controls are enforced. The `from` domain must be a verified transactional sending domain. Pass an `Idempotency-Key` header to make retries safe: the same key and body replays the original message (200, `idempotent_replay: true`, also under concurrent retries); the same key with a different body is refused with 409 `idempotency_key_reused`. Keys do not expire. Set `expires_at` or `ttl_seconds` so mail that cannot be handed to the provider in time fails with reason `expired` instead of arriving late.
Request body
{
"from": "Meetumo <hello@send.meetumo.ai>",
"to": "user@example.com",
"subject": "Welcome to Meetumo",
"html": "<p>Thanks for signing up.</p>",
"transactional": {
"category": "account",
"trigger_id": "signup_01j...",
"recipient_relationship": "account_holder"
}
}Response
{
"id": "msg_01j…",
"status": "queued"
}/v1/emails/batchSend up to 100 transactional emailsResend-compatible batch. The body is a JSON array of 1-100 objects, each exactly the `POST /v1/emails` body and validated by the same rules. Validation is all-or-nothing: an invalid item rejects the whole batch with its `index` and nothing is queued. With an `Idempotency-Key` header (max 250 characters) item i uses the key `<key>:<i>`, so retrying the whole batch replays every item; a retried batch whose item i changed is refused with 409 and that `index`.
Response
{
"data": [
{
"id": "msg_01j…",
"status": "queued"
},
{
"id": "msg_01k…",
"status": "queued"
}
]
}/v1/emails/healthCheck transactional sending readinessRead-only, send-scoped check of workspace approval and an active verified transactional identity. Does not send an email or expose message content. Returns 503 when sending is unavailable.
/v1/emails/{id}Get an email and its event timelineParameters
- id (path, required)
Response
{
"id": "msg_01j…",
"to": "user@example.com",
"status": "delivered",
"events": [
{
"type": "queued",
"at": "2026-07-18T07:48:16Z"
},
{
"type": "sent",
"at": "2026-07-18T07:48:16Z"
},
{
"type": "delivered",
"at": "2026-07-18T07:48:19Z"
}
]
}Domains
Register sending domains, prove DNS ownership, and inspect activation state.
/v1/domainsList sending domains/v1/domainsAdd a sending domainReturns the DNS records (DKIM, SPF, DMARC, MAIL FROM) to publish. eimailar re-checks them automatically. Follow the dashboard setup guide to complete domain activation.
Request body
{
"domain": "send.meetumo.ai",
"stream": "transactional"
}/v1/domains/{id}/verifyRe-check DNS nowParameters
- id (path, required)
Contacts
Manage contacts, consent, and CSV imports.
/v1/conversionsRecord a business conversionRequires contacts scope. Identify the person by contactId or email. Omit goalId to record against every objective with this event type. Exact duplicate externalEventId is idempotent; changed identity, time or value is refused. Times before objective creation, older than 90 days or more than five minutes ahead are refused. No sending authority is created.
/v1/contactsList contactsParameters
- status (query)
- list_id (query)
- q (query)
/v1/contactsCreate a contactEvery contact carries a consent basis. `double_opt_in` creates a pending contact and sends a confirmation email. Direct single opt-in and customer soft opt-in require a bounded attestation, source, and capture time before marketing eligibility is recorded.
Request body
{
"email": "user@example.com",
"attributes": {
"name": "Ada",
"company": "Acme"
},
"list_ids": [
"lst_01j…"
],
"consent": {
"method": "single_opt_in",
"evidence": {
"attested": true,
"source": "Product signup form",
"captured_at": "2026-08-06T12:00:00Z",
"policy_version": "2026-08"
}
}
}/v1/contacts/importBulk import contactsRequires explicit consent attestation. Reuses existing active contacts without changing attributes, records consent and joins the selected list. Inactive contacts remain unchanged. Skips suppressed, invalid and repeated addresses. Returns counts and a durable import report ID in the X-Eimailar-Import-Id header.
Request body
{
"contacts": [
{
"email": "a@example.com",
"attributes": {
"name": "A"
}
}
],
"list_id": "lst_01j…",
"consent": {
"attested": true,
"evidence": {
"source": "Event registration export",
"captured_at": "2026-08-06T12:00:00Z",
"policy_version": "2026-08"
}
}
}Response
{
"created": 2,
"existing": 0,
"suppressed": 1,
"invalid": 0,
"duplicates": 1
}/v1/contacts/upsertCreate or update a contactRetry-safe contact ingestion by normalized email. Merges attributes and list memberships, but never reactivates unsubscribed, bounced, complained, or suppressed contacts.
Request body
{
"email": "user@example.com",
"attributes": {
"name": "Ada",
"plan": "pro"
},
"source": "product-signup",
"list_ids": [
"lst_01j…"
],
"consent": {
"method": "single_opt_in",
"evidence": {
"attested": true,
"source": "Product signup form",
"captured_at": "2026-08-06T12:00:00Z",
"policy_version": "2026-08"
}
}
}Connections
Receive signups and signed lifecycle streams from forms, products, stores, Zapier, Make, and custom platforms.
/v1/connectionsList inbound signup connections/v1/connectionsCreate an inbound signup connectionReturns a connection-scoped secret exactly once. It cannot send email or access any other API resource.
Request body
{
"name": "Website signups",
"source": "website-signup",
"list_id": "lst_01j…",
"consent": {
"method": "double_opt_in",
"scope": "marketing"
},
"mapping": {
"email": "data.customer.email",
"event_id": "event.id",
"attributes": {
"first_name": "data.customer.first_name",
"plan": "data.plan"
}
}
}/v1/connections/{id}Get a connection and recent processing eventsParameters
- id (path, required)
/v1/connections/{id}Update or pause a connectionParameters
- id (path, required)
/v1/connections/{id}Delete a connectionParameters
- id (path, required)
/v1/connections/lifecycleList lifecycle source connections/v1/connections/lifecycleCreate a lifecycle source connectionReturns a source-scoped HMAC signing secret exactly once. Identity is scoped by tenant, source, and external user ID.
Request body
{
"name": "Partner product",
"source": "partner_product",
"feedback_url": "https://partner.example/hooks/eimailar"
}/hooks/lifecycle/v1/{connectionId}Receive a signed lifecycle eventSource-neutral HMAC receiver. Sign `<unix-seconds>.<raw-body>` and keep event IDs stable for safe retries.
Parameters
- connectionId (path, required)
- X-Eimailar-Signature (header, required)
- X-Eimailar-Key-Id (header, required)
Request body
{
"version": "1.0",
"event_id": "evt_01",
"event_type": "user.registered",
"occurred_at": "2026-08-01T12:00:00.000Z",
"source": "partner_product",
"external_user_id": "user_123",
"subject": {
"type": "user"
},
"roles": [
"registered_user"
],
"data": {
"email": "person@example.com"
},
"trace_id": "trace_01",
"suppress_automation": false,
"allow_send": true
}/hooks/contacts/{id}Receive an external signupPublic ingestion endpoint for one connection. Send its one-time secret as `X-Eimailar-Secret` (or a Bearer token). `X-Eimailar-Event-Id` can override the mapped event ID for replay protection.
Parameters
- id (path, required)
- X-Eimailar-Secret (header, required)
- X-Eimailar-Event-Id (header)
Request body
{
"event": {
"id": "signup_123"
},
"data": {
"customer": {
"email": "user@example.com",
"first_name": "Ada"
}
}
}Lists
Group contacts into lists.
/v1/listsList lists/v1/listsCreate a listRequest body
{
"name": "Newsletter",
"double_opt_in": true
}/v1/lists/{id}Edit list metadataPreserves contacts, membership, double opt-in and campaign references. Requires name; an omitted description is preserved and null clears it. Conflicting list names return 409.
Request body
{
"name": "Product updates",
"description": "Subscribers to product news"
}/v1/lists/{id}Delete an unused listPreserves contacts. Refuses deletion while a campaign, segment rule or automation trigger/action references the list, with workspace-scoped dependencies in the response.
Segments
Rule-based dynamic audiences.
/v1/segmentsList segments/v1/segmentsCreate a segmentRequest body
{
"name": "Engaged pros",
"rules": {
"match": "all",
"conditions": [
{
"kind": "attribute",
"field": "plan",
"op": "eq",
"value": "pro"
},
{
"kind": "activity",
"op": "opened",
"days": 30
}
]
}
}/v1/segments/previewPreview a rule setReturns the matching count and a sample without saving.
Response
{
"count": 128,
"sample": [
{
"email": "a@x.com",
"status": "active"
}
]
}Campaigns
One-off marketing sends to lists/segments.
/v1/conversion-goalsCreate a conversion objectiveRequires campaigns scope. Sources must belong to the workspace. Attribution configuration is fixed after creation.
/v1/conversion-goals/{id}Read objective and conversion totalsParameters
- id (path, required)
/v1/campaignsList campaigns/v1/campaignsCreate a campaign (draft)Audience is one or more lists and/or a segment. Content is inline html/text.
Request body
{
"name": "July update",
"subject": "Hi {{name}} — what's new",
"from": "Meetumo <news@mail.meetumo.ai>",
"audience": {
"list_ids": [
"lst_01j…"
],
"segment_id": "seg_01j…"
},
"html": "<p>Big news, {{name}}!</p>"
}/v1/campaigns/{id}/sendSend nowMaterializes the audience and starts the resumable send.
Parameters
- id (path, required)
/v1/campaigns/{id}/scheduleSchedule a sendPreflight-validates the campaign and schedules it for a future instant. Re-scheduling an already-scheduled campaign replaces the time.
Parameters
- id (path, required)
Request body
{
"send_at": "2026-09-01T14:00:00Z"
}/v1/campaigns/{id}/unscheduleCancel a scheduled sendReturns the campaign to draft and drops the pending start. 409 unless the campaign is scheduled.
Parameters
- id (path, required)
/v1/campaigns/{id}/pausePause a sending campaignParameters
- id (path, required)
Automations
Linear journeys triggered by contact events.
/v1/automationsList automations/v1/automationsCreate an automation (draft)A trigger plus linear steps (wait / send). Activate it to enroll matching contacts.
Request body
{
"name": "Welcome series",
"trigger": {
"kind": "list_joined",
"listId": "lst_01j…"
},
"steps": [
{
"kind": "send",
"from": "hello@mail.meetumo.ai",
"subject": "Welcome {{name}}",
"html": "<p>Hi {{name}}</p>"
},
{
"kind": "wait",
"minutes": 1440
},
{
"kind": "send",
"from": "hello@mail.meetumo.ai",
"subject": "Getting started",
"html": "<p>…</p>"
}
]
}/v1/automations/{id}/activateActivateParameters
- id (path, required)
Templates
Reusable visual email templates.
/v1/templatesList templates/v1/templatesCreate a templateProvide a block `design`; eimailar renders it to html and text.
Webhooks
Receive signed delivery/engagement events.
/v1/webhooksList webhook endpoints/v1/webhooksRegister a webhook endpointReturns a signing secret once. Each delivery is signed with `eimailar-signature: t=<unix>,v1=<hmac-sha256>` over `<t>.<body>`. The body is `{ id, type, created_at, data }`; `id` is a stable event id, identical on every retry and endpoint, also sent as the `eimailar-event-id` header (with `eimailar-event-type`) so receivers can deduplicate. Event types: `email.delivered`, `email.bounced`, `email.complained`, `email.opened`, `email.clicked`, and for transactional API mail `email.failed` (provider rejection, final soft bounce, expiry, domain or workspace gate; `data.reason`), `email.suppressed` (send-time suppression; `data.reason`) and `email.delivery_delayed` (SES DeliveryDelay; `data.delay`). Use `*` for all.
Request body
{
"url": "https://api.yourservice.com/eimailar-hook",
"event_types": [
"email.bounced",
"email.complained"
]
}