Before you send
Templates
What you are allowed to send, and exactly which values each one needs. This endpoint is the contract the send endpoint validates against, so what it publishes here is what a send will accept.
List them
curl "https://sendrixbackend.exebee.com/v1/templates" \
-H "Authorization: Bearer sk_live_..."{
"object": "list",
"data": [
{
"id": "tpl_cb9182c4-6e22-4095-bd26-a61c9f8d7fba",
"object": "template",
"name": "order_shipped",
"language": "en",
"category": "UTILITY",
"status": "APPROVED",
"quality_score": "GREEN",
"sender_id": "snd_c9288d80-3860-45c0-bcec-577b19aaab62",
"body_text": "Hi {{1}}, your order {{2}} is on its way.",
"header": { "type": "TEXT", "text": "Order update" },
"variables": [
{ "key": "header", "kind": "header" },
{ "key": "1", "kind": "body" },
{ "key": "2", "kind": "body" }
],
"required_keys": ["header", "1", "2"],
"requires_media_header": false,
"sendable": true,
"sendable_reason": null
}
],
"limit": 50, "offset": 0, "total": 1, "has_more": false
}Requires the templates:read scope.
The variable shape
required_keys is the important field. It is the exact set of keys the send endpoint expects in template.variables, and it is derived from the same code that validates a send, so the two cannot disagree. Send fewer and you get missing_variables. Send more and you get the same error the other way round, which is almost always a misspelling.
| Key | Fills |
|---|---|
"1", "2", … | The numbered slots in the body, in order. {{1}} is "1". |
"header" | The variable in a text header, when the template has one. |
"button0", "button1" | Buttons that take a value, by position. variables[].button_kind says whether it wants a URL tail or a code. |
Templates that carry a file
requires_media_header is truewhen the template’s header is an image, video or document. Those are sendable like any other, but the send must include template.header_media as well as the variables — the file is not one of the required_keys, because it is a URL or an upload rather than text substituted into the message.
What you cannot send
By default the list only returns templates you can actually send. Pass ?sendable=all to see everything, and each blocked one carries a sendable_reason saying why:
| Reason | What to do |
|---|---|
| Not APPROVED | Wait for Meta's review, or fix what it objected to in the console. |
| Uses named parameters | The API sends positional parameters. Recreate the template with numbered variables. |
Filters
| Parameter | Effect |
|---|---|
status | Only this Meta status, for example APPROVED. |
language | Only this language code, for example en. |
sender_id | Only templates belonging to that number. |
sendable | true is the default, false shows only blocked ones, all shows everything. |
limit, offset | Paging. Up to 100 per page. |
Reading one by name
Your code stores order_shipped, not a UUID, so the single-template endpoint takes either:
curl "https://sendrixbackend.exebee.com/v1/templates/order_shipped?language=en" \
-H "Authorization: Bearer sk_live_..."Without a language, and where the same name exists in several, the approved one wins. Name the language when it matters. Then go to Send a message.