Email API

Multipart requests with a JSON payload part and optional file attachments. Successful requests return 202 Accepted.

Overview

Use these endpoints to send transactional emails and to reply to prior emails. All requests use multipart/form-data with a JSON payload part, plus optional file attachments.

Authentication

Send these headers with every request. Tokens must match the sender email used in your payload.

  • X-Api-Access-Token
    Access token bound to the sender email.
  • X-Api-Secret-Token
    Secret token bound to the sender email.

If the sender isn’t registered with those tokens, the API returns 404.

Generate / View API Tokens

Opens your workspace’s Settings → Security.

POST /api/v1/emails

Create a new email and enqueue it for delivery.

POST https://api-marketing.cllavio.com/api/v1/emails
Content-Type: multipart/form-data

Multipart parts

  • payload (required, application/json) — matches SendEmailRequest:
    {
      "from": "no-reply@yourstore.com",
      "to":   ["alice@example.com","bob@example.com"],
      "cc":   ["manager@example.com"],
      "bcc":  [],
      "replyTo": ["support@yourstore.com"],
      "subject": "Welcome to our store!",
      "body": "<h1>Thanks for joining</h1><p>We're glad you're here.</p>"
    }
  • attachments (optional, file[], repeatable)

cURL

curl -X POST "https://api-marketing.cllavio.com/api/v1/emails" \
  -H "X-Api-Access-Token: <ACCESS_TOKEN>" \
  -H "X-Api-Secret-Token: <SECRET_TOKEN>" \
  -F 'payload={
    "from":"no-reply@yourstore.com",
    "to":["alice@example.com","bob@example.com"],
    "subject":"Welcome to our store!",
    "body":"<h1>Thanks for joining</h1>"
  };type=application/json' \
  -F "attachments=@/path/invoice.pdf" \
  -F "attachments=@/path/terms.pdf"

Success response (202)

Returns the enqueued email (attachments omitted).

{
  "referenceId": "ema_01JABCDEF1234XYZ",
  "from": "no-reply@yourstore.com",
  "to": ["alice@example.com","bob@example.com"],
  "cc": ["manager@example.com"],
  "bcc": [],
  "replyTo": ["support@yourstore.com"],
  "subject": "Welcome to our store!",
  "body": "<h1>Thanks for joining</h1>"
}

Validation & Limits

  • from, subject, body are required.
  • to must contain at least one valid email.
  • to 1000, cc 50, bcc 50, replyTo 50.
  • Monthly quota & bounce-rate protections enforced.

POST /api/v1/emails/{referenceId}/reply

Reply to a previously sent email using its referenceId.

POST https://api-marketing.cllavio.com/api/v1/emails/<referenceId>/reply
Content-Type: multipart/form-data

Multipart parts

  • payload (required, JSON) — matches ReplyEmailRequest:
    {
      "to": ["customer@example.com"],   // optional; defaults to original sender if omitted
      "body": "<p>Your refund has been processed.</p>"
    }
  • attachments (optional, file[], repeatable)

cURL

curl -X POST "https://api-marketing.cllavio.com/api/v1/emails/ema_01JABCDEF1234XYZ/reply" \
  -H "X-Api-Access-Token: <ACCESS_TOKEN>" \
  -H "X-Api-Secret-Token: <SECRET_TOKEN>" \
  -F 'payload={
    "body":"<p>Your refund has been processed.</p>"
  };type=application/json'

Success response (202)

{
  "referenceId": "ema_01JREPLY123XYZ",
  "originalReferenceId": "ema_01JABCDEF1234XYZ",
  "from": "no-reply@yourstore.com",
  "to": ["original.sender@example.com"],
  "subject": "Re: <original subject>",
  "body": "<p>Your refund has been processed.</p>"
}

POST /api/v1/emails/reply?from=&subject=

Reply referencing the most recent email with the given subject. If none exists, a new thread is created.

POST https://api-marketing.cllavio.com/api/v1/emails/reply?from=<sender>&subject=<subject>
Content-Type: multipart/form-data

Query params

  • from — sender email that owns the tokens (used to authenticate).
  • subject — subject to match (most recent row is used if found).

Multipart parts

  • payload (required, JSON) — matches ReplyEmailRequest:
    {
      "to": ["customer@example.com"],   // optional; defaults to API caller's email if omitted
      "body": "<p>Following up on your request.</p>"
    }
  • attachments (optional, file[], repeatable)

cURL

curl -X POST "https://api-marketing.cllavio.com/api/v1/emails/reply?from=no-reply@yourstore.com&subject=Order%20Update" \
  -H "X-Api-Access-Token: <ACCESS_TOKEN>" \
  -H "X-Api-Secret-Token: <SECRET_TOKEN>" \
  -F 'payload={
    "body":"<p>Here's the latest on your order.</p>"
  };type=application/json'

Success response (202)

{
  "referenceId": "ema_01JNEWREPLYXYZ",
  "originalReferenceId": "ema_01JORIGIFFOUND",   // may be null if no prior subject match
  "from": "no-reply@yourstore.com",
  "to": ["no-reply@yourstore.com"],              // default if 'to' omitted
  "subject": "Re: Order Update",
  "body": "<p>Here's the latest on your order.</p>"
}

Errors

The API uses HTTP status codes. These messages are emitted by the service layer.

400 Bad Request

  • Monthly e-mail quota exceeded
  • API access suspended – high bounce rate
  • Validation errors (e.g., missing from, empty to, list limits)
{
  "status": 400,
  "message": "Monthly e-mail quota exceeded"
}

404 Not Found

  • Sender email is not found in platform! (send)
  • Sender email not registered (reply by subject)
  • No API e-mail found for referenceId <id> (reply by reference)
{
  "status": 404,
  "message": "No API e-mail found for referenceId ema_01JABC..."
}