Maqetin queues one transactional email for each call your server makes.

Send one request with a template, a recipient and your data. Maqetin answers 202 with the message id, and the email follows.

The request

PartValue
RoutePOST https://api.maqetin.com/v1/public/messages
KeyA secret key in Authorization: Bearer mq_sec_…, made with the messages:send scope.
Idempotency-KeyOptional. Letters, digits and _ . : -, at most 100 characters.

The body

FieldRequiredWhat it holds
channelYesemail, the one channel built today.
templateIdYesThe id of a template in your workspace.
toYes{ "userId": "…" } for a person you identified, or { "email": "…" } for an address with no profile.
fromYesName <local@domain> or local@domain. Without a name, Maqetin uses the workspace name. The domain must be a verified sending domain of the workspace.
subjectNoReplaces the subject of the template.
dataNoMerge data for the template, at most 16 KB. It goes over the traits of the person but never over email or user_id.
{
  "channel": "email",
  "templateId": "tpl_receipt",
  "to": { "email": "ada@example.com" },
  "from": "Receipts <receipts@mail.harbourmoney.co.uk>",
  "subject": "Your receipt",
  "data": { "order": { "id": "o_42", "total": 12.5 } }
}

Replace the sample values with your own: templateId names one of your templates, and the domain of from is a verified sending domain of your workspace.

Send it

HTTP

curl https://api.maqetin.com/v1/public/messages \
  -H 'Authorization: Bearer mq_sec_…' \
  -H 'Content-Type: application/json' \
  -H 'Idempotency-Key: order-42:receipt' \
  -d '{
  "channel": "email",
  "templateId": "tpl_receipt",
  "to": { "email": "ada@example.com" },
  "from": "Receipts <receipts@mail.harbourmoney.co.uk>",
  "subject": "Your receipt",
  "data": { "order": { "id": "o_42", "total": 12.5 } }
}'

Node

import { MaqetinServer } from '@maqetin/sdk-js/server';

const mq = new MaqetinServer({ secretKey: process.env.MAQETIN_SECRET_KEY });
const { messageId } = await mq.messages.send({
  channel: 'email',
  templateId: 'tpl_receipt',
  to: { userId: 'u_42' }, // or { email: 'guest@example.com' }
  from: 'Harbour Money <receipts@mail.harbourmoney.co.uk>',
  data: { order: { id: 'o_42', total: 12.5 } },
  idempotencyKey: 'order-42:receipt',
});

The Node call is the server entry of the SDK. It makes an idempotency key when you give none.

Send a retry safely

Send the same Idempotency-Key on a retry and Maqetin sends the message once. The first body sent with a key is the one that counts.

The SDK retries after a 5xx, a 429 or a network error with the same key. It gives up on a request that does not answer after requestTimeoutMs, 15 seconds by default.

What comes back

A reply of the API holds success and data. The answer of a 202 is in data: { messageId, status: "queued" }.

StatusMeaning
400The body or a header does not parse.
401The request has no secret key.
403The key has no messages:send scope.
404The userId has no profile, or the profile has no address, or the template is not there.
409The send is refused. The reason is one of sending_disabled, workspace_inactive, sending_not_approved and sender_domain_invalid.
429Over 300 sends a minute for the key, or over its request limit.

What a transactional message does

  • It reaches a person who unsubscribed from marketing.
  • It never reaches a suppressed address.
  • It has no unsubscribe link.

Create a workspace and send your first email.