REST API
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.
subject and body from that template. Do not pass subject / body when using template_id.GET /api/v1/contacts). Used only when recipients.type is "contacts". These are not template ids.acc_…, not the internal account UUID from list/get account responses.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.
{
"account_key": "acc_…",
"template_id": "00000000-0000-0000-0000-000000000001",
"recipients": { "emails": ["you@example.com"] },
"variables": { "first_name": "Alex", "promo_code": "SAVE20" }
}{
"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" }
}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.
{
"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": {}
}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.
/api/v1/composeSend 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
| Field | Type | Description |
|---|---|---|
| ok | boolean | True when the request was accepted and sends were attempted. |
| sent | number | Count of messages queued or sent successfully. |
| failed | { email: string; error: string }[] | Per-recipient failures (empty when all succeeded). |
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": [] }