eeimailar APIv1.0.0Dashboard →

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

  1. Claim your invitation, set your password, verify your email, and sign in to your customer workspace.
  2. 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.
  3. Open Settings, choose Plan & usage, and submit your sending review with your website and use case.
  4. In Developer → API keys, create a key with the send scope. Copy the secret when it appears and store it in your server's secret manager; it cannot be viewed again.
  5. Send from your server using an address on the exact verified transactional domain. Use a distinct idempotency key for each business event. A 201 queued response 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.

post/v1/emailsSend a transactional email

Queues 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"
}
post/v1/emails/batchSend up to 100 transactional emails

Resend-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"
    }
  ]
}
get/v1/emails/healthCheck transactional sending readiness

Read-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.

get/v1/emails/{id}Get an email and its event timeline

Parameters

  • 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.

get/v1/domainsList sending domains
post/v1/domainsAdd a sending domain

Returns 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"
}
post/v1/domains/{id}/verifyRe-check DNS now

Parameters

  • id (path, required)

Contacts

Manage contacts, consent, and CSV imports.

post/v1/conversionsRecord a business conversion

Requires 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.

get/v1/contactsList contacts

Parameters

  • status (query)
  • list_id (query)
  • q (query)
post/v1/contactsCreate a contact

Every 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"
    }
  }
}
post/v1/contacts/importBulk import contacts

Requires 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
}
post/v1/contacts/upsertCreate or update a contact

Retry-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.

get/v1/connectionsList inbound signup connections
post/v1/connectionsCreate an inbound signup connection

Returns 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"
    }
  }
}
get/v1/connections/{id}Get a connection and recent processing events

Parameters

  • id (path, required)
patch/v1/connections/{id}Update or pause a connection

Parameters

  • id (path, required)
delete/v1/connections/{id}Delete a connection

Parameters

  • id (path, required)
get/v1/connections/lifecycleList lifecycle source connections
post/v1/connections/lifecycleCreate a lifecycle source connection

Returns 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"
}
post/hooks/lifecycle/v1/{connectionId}Receive a signed lifecycle event

Source-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
}
post/hooks/contacts/{id}Receive an external signup

Public 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.

get/v1/listsList lists
post/v1/listsCreate a list

Request body

{
  "name": "Newsletter",
  "double_opt_in": true
}
patch/v1/lists/{id}Edit list metadata

Preserves 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"
}
delete/v1/lists/{id}Delete an unused list

Preserves 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.

get/v1/segmentsList segments
post/v1/segmentsCreate a segment

Request body

{
  "name": "Engaged pros",
  "rules": {
    "match": "all",
    "conditions": [
      {
        "kind": "attribute",
        "field": "plan",
        "op": "eq",
        "value": "pro"
      },
      {
        "kind": "activity",
        "op": "opened",
        "days": 30
      }
    ]
  }
}
post/v1/segments/previewPreview a rule set

Returns 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.

post/v1/conversion-goalsCreate a conversion objective

Requires campaigns scope. Sources must belong to the workspace. Attribution configuration is fixed after creation.

get/v1/conversion-goals/{id}Read objective and conversion totals

Parameters

  • id (path, required)
get/v1/campaignsList campaigns
post/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>"
}
post/v1/campaigns/{id}/sendSend now

Materializes the audience and starts the resumable send.

Parameters

  • id (path, required)
post/v1/campaigns/{id}/scheduleSchedule a send

Preflight-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"
}
post/v1/campaigns/{id}/unscheduleCancel a scheduled send

Returns the campaign to draft and drops the pending start. 409 unless the campaign is scheduled.

Parameters

  • id (path, required)
post/v1/campaigns/{id}/pausePause a sending campaign

Parameters

  • id (path, required)

Automations

Linear journeys triggered by contact events.

get/v1/automationsList automations
post/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>"
    }
  ]
}
post/v1/automations/{id}/activateActivate

Parameters

  • id (path, required)

Templates

Reusable visual email templates.

get/v1/templatesList templates
post/v1/templatesCreate a template

Provide a block `design`; eimailar renders it to html and text.

Webhooks

Receive signed delivery/engagement events.

get/v1/webhooksList webhook endpoints
post/v1/webhooksRegister a webhook endpoint

Returns 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"
  ]
}