Reference
Sending API
One endpoint sends any template you've published. Everything else — designing, publishing, keys and history — happens in the dashboard.
Send an email
Renders the template's published version with your variables and sends it to one recipient. Editing or saving a template never changes what this sends — only publishing does.
Authentication
Send your workspace API key as a bearer token. Keys start with ntl_, are created in Developers, and can only call this endpoint.
Authorization: Bearer ntl_…Request body
| Field | Type | Description |
|---|---|---|
template_key | string, required | The template's key, e.g. welcome. 1–200 characters. |
to | string, required | The recipient's email address. |
variables | object | A value for every variable the template's subject, preview text and body use. Values are strings, numbers or booleans. |
{
"template_key": "password-reset",
"to": "ram@example.com",
"variables": { "name": "Ram", "code": "482913" }
}Responses
| Status | Meaning | What to do |
|---|---|---|
202 | Sent. Body: {"status": "sent"} | Nothing — it's in Activity. |
401 | The key is missing, malformed, or revoked | Check the header; create a new key if needed. |
404 | No template with that key in this workspace | Check the key spelling. |
409 | The template exists but isn't published | Open it and choose Publish → Go live. |
422 | A variable is missing or has the wrong type, or the address is invalid | Read error.field_errors — it names the field. |
5xx | Delivery or service failure | Retry with backoff. The attempt is logged in Activity. |
A missing variable is refused, not guessed
{{name}} and you don't send name, the request fails with 422 instead of sending an email with a blank or literal placeholder.Error format
Every error has the same envelope. code is stable for branching; message is written for people; request_id matches the send in Activity and helps us trace a problem.
{
"error": {
"code": "validation_failed",
"message": "One or more fields are invalid.",
"request_id": "01J9…",
"field_errors": [
{ "field": "variables.code", "code": "required", "message": "Is required." }
]
}
}| code | Status |
|---|---|
invalid_request | 400 — the body isn't valid JSON |
unauthenticated | 401 |
forbidden | 403 |
not_found | 404 |
conflict | 409 |
validation_failed | 422 — see field_errors |
unprocessable_entity | 422 — the template itself couldn't be rendered |
internal | 500 |
Retries
Sending isn't idempotent yet: retrying a request that actually succeeded sends the email twice. Retry on network errors and 5xx responses, not on 4xx — those won't succeed without a change.