HTTP API
Base URL example: http://127.0.0.1:3000.
Send routes require auth (Configuration). Content-Type: application/json. Body must be a JSON object.
Health
curl -s http://127.0.0.1:3000/health
# {"status":"ok"}curl -s http://127.0.0.1:3000/ready
# ok, or 503 if email is configured but no templates loadedNo auth on either.
Send email
POST /email/send
{
"templateId": "react-email-user-welcome",
"account": "zeptomail",
"payload": {
"userName": "Ada",
"appName": "MyApp",
"ctaUrl": "https://example.com"
},
"sendMailOptions": {
"to": ["[email protected]"],
"from": "[email protected]",
"subject": "Welcome",
"cc": [],
"bcc": [],
"replyTo": "[email protected]",
"attachments": [
{
"filename": "guide.pdf",
"contentType": "application/pdf",
"content": "<base64>"
}
]
}
}| Field | Required | Notes |
|---|---|---|
templateId | Yes | Must match a loaded template |
payload | Yes | Object; validated against template schema |
account | No | Overrides template / defaults |
sendMailOptions.to | Yes* | Must resolve after merge |
sendMailOptions.from | Yes* | Account, template, or request |
sendMailOptions.subject | Yes* | Template or request |
*After merge of account → template → request.
Zeptomail-only request fields: fromName, bounceAddress (400 if used with SES). Unknown sendMailOptions keys → 400.
Success:
{ "success": true, "messageId": "…" }HMAC example
const body = JSON.stringify({
templateId: 'mjml-user-welcome',
payload: { userName: 'Ada', appName: 'MyApp' },
sendMailOptions: { to: ['[email protected]'], subject: 'Welcome' },
});
await fetch(`${baseUrl}/email/send`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-notifier-signature': sign(body, process.env.NOTIFIER_SIGNING_SECRET),
},
body,
});API key example
await fetch(`${baseUrl}/email/send`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-notifier-api-key': process.env.NOTIFIER_API_KEY,
},
body,
});Send SMS
POST /sms/send. No templates.
{
"to": "23490126727",
"body": "Your OTP is 1234",
"account": "termii",
"sendOptions": {
"version": "v4",
"from": "MyApp",
"channel": "dnd",
"messageType": "plain"
}
}| Field | Required | Notes |
|---|---|---|
to | Yes | String or array, max 100. Digits with optional +, length 7-15 |
body | Yes | Plain text |
account | No | SMS account id |
sendOptions | No | version, from, channel, messageType |
If the account sets baseUrl, sendOptions.version is rejected (400). Unknown sendOptions keys → 400.
HMAC example
const body = JSON.stringify({
to: '23490126727',
body: 'Your OTP is 1234',
sendOptions: { version: 'v4', channel: 'dnd', messageType: 'plain' },
});
await fetch(`${baseUrl}/sms/send`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-notifier-signature': sign(body, process.env.NOTIFIER_SIGNING_SECRET),
},
body,
});Errors
Shape:
{ "success": false, "message": "…", "details": [] }| Status | When |
|---|---|
| 400 | Validation, unknown fields, missing template vars, bad emails/phones |
| 401 | Auth failure |
| 404 | Unknown templateId |
| 413 | Body too large |
| 502 | Provider error (message sanitized) |
| 503 | Channel missing / not ready |
| 500 | Unexpected |
Provider calls time out after 30 seconds.
Repo scripts
Under examples/notifier-service/scripts/:
send-welcome-mjml.js: sample email templates (--sample=1..7)send-sms.js: Termii SMSlib/notifier-client.js: small HMAC helper for those scripts
There is no published client SDK; copy the sign + fetch pattern into your services.
Last updated on