POST /messages/send
POST /messages/send
Section titled “POST /messages/send”Sends a notification rendered from a template approved for your account, from a MauKirim-managed sending number.
| Scope | notification |
| Auth | Authorization: Bearer mk_live_… |
| Content-Type | application/json (required) |
| Body limit | 8192 bytes |
| Idempotency | Required — Idempotency-Key, 1–128 characters |
Request
Section titled “Request”| Field | Type | Required | Validation |
|---|---|---|---|
phone |
string | yes | Non-blank; E.164 after stripping separators |
templateId |
string | yes | Non-blank; the template must exist, be approved, and belong to your account |
variables |
object | yes | Keys must equal the template’s top-level placeholder names exactly (same count, same names). A scalar placeholder takes a string matching /^[\p{L}\p{N}_ .,:!{}@+\/()&-]{1,64}$/u; a list section takes an array of 0–10 objects whose keys are exactly that section’s placeholders, each value the same 1–64-character string |
curl -X POST https://app.maukirim.com/api/v1/messages/send \ -H "Authorization: Bearer mk_live_…" \ -H "Content-Type: application/json" \ -H "Idempotency-Key: order-8821" \ -d '{"phone": "+6281234567890", "templateId": "tpl_…", "variables": {"order": "8821", "items": [{"name": "Kopi luwak", "quantity": "2"}, {"name": "Teh botol", "quantity": "3"}]}}'List sections
Section titled “List sections”When the approved template repeats a block with {{#name}} … {{/name}}, variables.name is an
array of at most 10 plain objects — one per repetition — instead of a string. An empty array
renders no repetitions; text-only sends still need some other rendered text, while media can have no
caption. Every object must carry exactly the placeholders used inside the section, each a string
matching /^[\p{L}\p{N}_ .,:!{}@+\/()&-]{1,64}$/u, and no other key. Quantities and numbers are sent as text.
A template may declare several named lists, but at most 8 top-level names in total; sections do not nest, section names are unique, and each list binds at most 8 fields. However many items render, the send is still one message with one charge.
The template summary reports lists as { name, fields }[] and variables as every top-level name —
each scalar placeholder and each list.
Response
Section titled “Response”200
{ "ok": true, "batchId": "gwb_…" }batchId is the dispatch attempt. Delivery state arrives on the webhook configured for the sending device;
message bodies are purged seven days after the item becomes terminal.
Errors
Section titled “Errors”| HTTP | Code | Condition |
|---|---|---|
| 400 | invalid_input |
Missing/wrong Content-Type; body over 8192 bytes or not an object; phone invalid; templateId missing; variables missing/not an object; variables that do not match the template, including a list object whose keys differ from its section; Idempotency-Key missing or over 128 |
| 401 | auth codes | See Authentication |
| 403 | api_key_scope_denied |
The key lacks notification |
| 403 | forbidden |
Account inactive; or the template is not approved, or belongs to another account, or changed since approval |
| 402 | insufficient_credits |
Balance below the cost (0 inside the plan allowance, else the plan’s overage rate, else 28) |
| 404 | not_found |
No account row for the key owner |
| 404 | device_not_found |
The chosen sending device vanished mid-request |
| 409 | batch_idempotency_conflict |
Same key, different normalized request |
| 409 | device_not_connected |
No ready MauKirim sending number |
| 413 | batch_too_large |
Submission key over 128 characters |
| 503 | worker_offline |
Dispatch worker offline |
| 500 | server_error |
Unexpected |