BluetickedDeveloper docs

Templates

4 endpoints, each with examples that open in the console prefilled.

All resourcesGuide: Templates and approval
POST/api/v1/templatestemplates:writeTry in console

Submit template

Submit a WhatsApp template for Meta approval through a connected WABA.

Body parameters
namerequiredstring
categoryrequiredstring
languagestring
bodyrequiredstring
  • Only approved templates can be used for outbound WhatsApp sends.
  • name must match ^[a-z0-9_]+$ (lowercase letters, numbers and underscores only); category is one of marketing, utility, authentication; language defaults to en_US.
  • Optional footer (≤60 chars) and up to 3 buttons, each { type: "url", text, url }, { type: "phone", text, phone } or { type: "quick_reply", text }.
  • channel_id chooses which connected WhatsApp number submits the template; omit it to use the workspace's connected number.
  • The template is returned flat (fields at the top level), matching GET /api/v1/templates/{id}.
  • Category is what the message does: utility only for updates about something the customer already has, with no promotional wording (Meta rejects it or moves it to marketing), marketing for anything promotional, authentication for codes. Number variables {{1}}, {{2}} and on, in order with none skipped.
  • You do not send sample values. Meta's reviewers need a sample for every variable, so Blueticked sends one per variable, chosen from the words around it (a first name after Hi, a date after on). To pick your own samples, create the template in the dashboard.
  • The API creates templates without a header (a body, with an optional footer and buttons). A template with a DOCUMENT header (a statement or an invoice) is made in the dashboard, then sent with document on POST /api/v1/messages or document_source on a campaign. A body carrying a header field (any field whose name starts with header, in any case: header, header_format, headerFormat) answers 422 template_kind_unsupported with details.field naming it, and nothing is created.
curl -X POST "https://app.blueticked.com/api/v1/templates" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: change-me-per-request-0001" \
  -d '{
  "name": "order_update_v1",
  "category": "utility",
  "language": "en_US",
  "body": "Hi {{1}}, your order {{2}} is ready."
}'
Response
{
  "id": "7af1270d-94ba-4661-9fc4-0d3852469977",
  "name": "order_update_v1",
  "category": "utility",
  "language": "en_US",
  "status": "pending",
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
GET/api/v1/templatestemplates:readTry in console

List templates

List WhatsApp templates and their approval status, with cursor pagination.

Query parameters
limitstring
  • Filter by ?status= to find approved templates ready to send.
  • Page with ?limit= (max 200, default 50) and ?cursor= (the previous page's next_cursor).
curl -X GET "https://app.blueticked.com/api/v1/templates?limit=50" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "data": [
    {
      "id": "7af1270d-94ba-4661-9fc4-0d3852469977",
      "name": "order_update_v1",
      "category": "utility",
      "language": "en_US",
      "status": "approved"
    }
  ],
  "next_cursor": null,
  "has_more": false,
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
GET/api/v1/templates/{id}templates:readTry in console

Get a template

Fetch one template, including its body, buttons, and rejection reason if any.

  • Poll this endpoint (or list templates) to track review progress. status moves from pending to approved/rejected as Meta's review completes. There is no template.* webhook event.
curl -X GET "https://app.blueticked.com/api/v1/templates/{id}" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "id": "7af1270d-94ba-4661-9fc4-0d3852469977",
  "channel_id": "1891a644-c71d-4a79-b679-6db1db14e065",
  "name": "order_update_v1",
  "category": "utility",
  "language": "en_US",
  "body": "Hi {{1}}, your order {{2}} is ready.",
  "footer": null,
  "buttons": [],
  "status": "approved",
  "external_id": "1234567890",
  "rejection_reason": null,
  "submitted_at": "2026-05-20T08:00:00.000Z",
  "approved_at": "2026-05-20T09:00:00.000Z",
  "created_at": "2026-05-20T08:00:00.000Z",
  "updated_at": "2026-05-20T09:00:00.000Z",
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}
POST/api/v1/templates/{id}/submittemplates:writeTry in console

Submit a draft template

Send an existing draft to Meta for review. The draft itself is submitted, so no second template is created.

  • Use it for a draft saved in the dashboard, or one POST /api/v1/templates left at draft when Meta refused it: correct the draft in the dashboard, then submit it here. POST /api/v1/templates always creates a new template, so retrying that call leaves the old draft behind.
  • The draft is checked the way the dashboard checks it before anything reaches Meta; a problem answers 400 validation_failed with what to change. A template that is not a draft (pending, approved, rejected, paused) answers 409 conflict with its status in details; to change a submitted template, create a new one. A draft that another submit is sending right now also answers 409 conflict (details.reason template_not_draft): only one submit of a draft reaches Meta. With the same Idempotency-Key, a retry of a success gets the first answer back.
  • It goes through the draft's own WhatsApp number, or the connected number of its business when it has none; a number that is not connected answers 503 channel_unavailable. Meta refusing the template answers 502 provider_error with Meta's words.
  • The response is the template with status: "pending"; poll GET /api/v1/templates/{id} for Meta's decision. A test key runs every check and stops before Meta: the draft is unchanged and the response carries test_mode: true and submitted_to_meta: false.
curl -X POST "https://app.blueticked.com/api/v1/templates/{id}/submit" \
  -H "Authorization: Bearer $BLUETICKED_API_KEY"
Response
{
  "id": "7af1270d-94ba-4661-9fc4-0d3852469977",
  "channel_id": "1891a644-c71d-4a79-b679-6db1db14e065",
  "name": "order_update_v1",
  "category": "utility",
  "language": "en_US",
  "body": "Hi {{1}}, your order {{2}} is ready.",
  "footer": null,
  "buttons": [],
  "status": "pending",
  "external_id": "1234567890",
  "rejection_reason": null,
  "submitted_at": "2026-05-20T08:00:00.000Z",
  "approved_at": null,
  "created_at": "2026-05-19T16:00:00.000Z",
  "updated_at": "2026-05-20T08:00:00.000Z",
  "request_id": "req_b2e3d610e10f1b07468721ee98f0e1d2"
}