REST API

Compose (one-off send)

Send transactional or ad-hoc email without a campaign — same merge rules as the in-app Compose screen. Authenticate with Authorization: Bearer (API keys). Pick a sending identity with account_key (the public acc_… string from Accounts, not the account UUID). Up to 100 recipients per request; daily limits still apply.

Know your IDs (common confusion)

  • template_id — UUID of a row in Templates. Loads subject and body from that template. Do not pass subject / body when using template_id.
  • contact_ids — UUIDs of people from Contacts (GET /api/v1/contacts). Used only when recipients.type is "contacts". These are not template ids.
  • account_key — public key like acc_…, not the internal account UUID from list/get account responses.

Message fields: subject, body, variables

Either use a saved template or supply content inline. Merge tags use {{ variable_name }} in subject and body (HTML). Provide values in variables (keys normalized to lowercase with underscores). If a tag is present but missing from variables, the API returns 400 with missing_variables.

To / Cc / Bcc: this endpoint sends to primary recipients only (recipients.emails, to, or contact emails when using contact_ids). Cc and Bcc are not supported here.

A — Saved template + manual To

JSON body
{
  "account_key": "acc_…",
  "template_id": "00000000-0000-0000-0000-000000000001",
  "recipients": { "emails": ["you@example.com"] },
  "variables": { "first_name": "Alex", "promo_code": "SAVE20" }
}

B — Inline subject & body + manual To

JSON body
{
  "account_key": "acc_…",
  "subject": "Hi {{first_name}}",
  "body": "<p>Use {{promo_code}} today.</p>",
  "recipients": { "emails": ["you@example.com"] },
  "variables": { "first_name": "Alex", "promo_code": "SAVE20" }
}

C — Inline content + saved contacts

Use contact UUIDs from your address book. Merge fields like {{ first_name }} can be filled from the contact when applicable; custom {{ promo_code }}-style tags still need variables.

JSON body
{
  "account_key": "acc_…",
  "subject": "Order update",
  "body": "<p>Hi {{first_name}}, your order shipped.</p>",
  "recipients": {
    "type": "contacts",
    "contact_ids": [
      "00000000-0000-0000-0000-000000000002",
      "00000000-0000-0000-0000-000000000003"
    ]
  },
  "variables": {}
}

Interactive request builder

Use the Try it panel on the right: enter your API key and account_key, choose template vs inline content, manual To vs contact ids, and fill variable fields the same way as the API key field. The live JSON preview matches what is sent to POST /api/v1/compose.

POST/api/v1/compose

Compose (one-off send)

Send up to 100 recipients without a campaign. Required: account_key (public acc_… string, not the account UUID). Content: either template_id (saved template UUID) or both subject and body — never both. Recipients: manual To list or recipients.type "contacts" with contact_ids (contact UUIDs from /api/v1/contacts, not template ids). variables fills {{ placeholders }}; omitted required tags return 400 with missing_variables. Cc/Bcc are not supported on this endpoint (To only).

Authentication: Authorization: Bearer with your Mailofly API key

Example — inline subject & body, manual To

Use template_id instead of subject/body to load a saved template. For contacts, set recipients.type to "contacts" and pass contact_ids.

{
  "account_key": "acc_YOUR_ACCOUNT_KEY",
  "subject": "Hi {{first_name}}",
  "body": "<p>Code: <strong>{{promo_code}}</strong></p>",
  "recipients": { "emails": ["friend@example.com"] },
  "variables": { "first_name": "Alex", "promo_code": "SAVE20" }
}

Returns

FieldType
okboolean
sentnumber
failed{ email: string; error: string }[]
cURL
curl -sS -X POST "https://www.mailofly.com/api/v1/compose" \
  -H "Accept: application/json" \
  -H "Authorization: Bearer mf_live_your_key_here" \
  -H "Content-Type: application/json" \
  -d "{\"account_key\":\"acc_YOUR_ACCOUNT_KEY\",\"variables\":{\"first_name\":\"Alex\",\"promo_code\":\"SAVE20\"},\"subject\":\"Hi {{first_name}}, your code is ready\",\"body\":\"<p>Hello {{first_name}},</p><p>Use <strong>{{promo_code}}</strong> at checkout.</p>\",\"recipients\":{\"emails\":[\"friend@example.com\"]}}"

Build the JSON body below. Requests use https://www.mailofly.com

Message content

Recipients

variables

Values for {{ placeholders }} in subject/body. Keys are normalized to lowercase with underscores (same as the API).

{
  "account_key": "acc_YOUR_ACCOUNT_KEY",
  "variables": {
    "first_name": "Alex",
    "promo_code": "SAVE20"
  },
  "subject": "Hi {{first_name}}, your code is ready",
  "body": "<p>Hello {{first_name}},</p><p>Use <strong>{{promo_code}}</strong> at checkout.</p>",
  "recipients": {
    "emails": [
      "friend@example.com"
    ]
  }
}

Response

Try it sends the request through this app to https://www.mailofly.com (no browser CORS issues).

Click Try it after filling the form.

Example responses

{ "ok": true, "sent": 1, "failed": [] }
POST/api/v1/compose