Templates
Create, submit for Meta approval, and list approved WhatsApp message templates.
WhatsApp messaging is template-first. Before you can POST /messages/template, you need a
template that Meta has approved. This API mirrors the approval workflow: draft → submit →
(Meta reviews) → approved.
| Scope | Endpoints |
|---|---|
templates:read | GET /templates, GET /templates/{id} |
templates:write | POST /templates, POST /templates/{id}/submit |
Base path: /api/v1/public/templates
Read endpoints return approved templates only. Drafts and pending-review templates are not visible to the Public API list/get endpoints. To inspect a draft, fetch its details from the dashboard.
Template object
| Field | Type | Notes |
|---|---|---|
id | UUID | Lynkist's internal template ID. Pass to campaigns. |
template_name | string (1-255) | The name Meta knows it by. Lowercase, snake_case. |
language | string (2-10) | Locale tag, e.g. en_US, hi, en_GB. |
category | string | Meta category: MARKETING, UTILITY, AUTHENTICATION. |
status | string | draft, pending, approved, rejected, disabled. |
components | object[] | null | Meta template-component objects (header, body, buttons, etc.). |
created_at | ISO-8601 | |
updated_at | ISO-8601 | null |
Component shape
Each component is one of HEADER, BODY, FOOTER or BUTTONS. The body is required; the
others are optional. Variables are written as {{1}}, {{2}}, … and are replaced at send time
by the components array on POST /messages/template.
{
"components": [
{ "type": "HEADER", "format": "TEXT", "text": "Order {{1}} update" },
{ "type": "BODY", "text": "Hi {{1}}, your order {{2}} has shipped. Track it: {{3}}." },
{ "type": "FOOTER", "text": "Reply STOP to opt out." },
{
"type": "BUTTONS",
"buttons": [
{ "type": "URL", "text": "Track", "url": "https://example.com/track/{{1}}" },
{ "type": "PHONE_NUMBER", "text": "Call us", "phone_number": "+1-555-0100" }
]
}
]
}The full grammar follows Meta's WhatsApp template component reference.
GET /templates — List approved templates
Paginated list of templates whose status is approved. Newest first.
Query parameters
| Param | Type | Default |
|---|---|---|
page | integer ≥1 | 1 |
limit | 1-100 | 20 |
curl "https://api.lynkist.io/api/v1/public/templates?page=1&limit=20" \
-H "Authorization: Bearer $LYNKIST_API_KEY"200 OK
{
"data": [
{
"id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"template_name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"status": "approved",
"components": [ /* see Component shape */ ],
"created_at": "2026-04-12T09:00:00Z",
"updated_at": "2026-04-12T11:14:33Z"
}
],
"pagination": {
"page": 1, "limit": 20,
"total_items": 4, "total_pages": 1,
"has_next": false, "has_prev": false
}
}GET /templates/{id} — Get an approved template
curl https://api.lynkist.io/api/v1/public/templates/f47ac10b-58cc-4372-a567-0e02b2c3d479 \
-H "Authorization: Bearer $LYNKIST_API_KEY"200 OK — the template object. 404 if not found or not approved.
POST /templates — Create a draft template
Creates a draft. The template is not yet sendable — call POST /templates/{id}/submit to
push it to Meta for review.
curl -X POST https://api.lynkist.io/api/v1/public/templates \
-H "Authorization: Bearer $LYNKIST_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"template_name": "order_confirmation",
"language": "en_US",
"category": "UTILITY",
"components": [
{ "type": "BODY", "text": "Hi {{1}}, your order {{2}} is confirmed." }
]
}'201 Created — returns the draft template with status: "draft".
Naming rules (enforced by Meta)
- Lowercase letters, digits and underscores only.
- 1-512 characters.
- Must be unique within your WABA.
If you submit a draft Meta rejects, the status becomes rejected and the dashboard surfaces
Meta's rejection reason.
POST /templates/{id}/submit — Submit for approval
Pushes a draft to Meta for review. Lynkist forwards the components verbatim — fix any rejection reasons on a new draft (Meta does not allow re-submitting a rejected template).
curl -X POST https://api.lynkist.io/api/v1/public/templates/f47ac10b-58cc-4372-a567-0e02b2c3d479/submit \
-H "Authorization: Bearer $LYNKIST_API_KEY"200 OK — returns the template, now in status: "pending".
Meta typically takes 1 minute to 24 hours to review. When Meta finishes, your template moves to
approved, rejected, or (rarely) disabled. Today there is no Lynkist webhook for the
approval transition — poll GET /templates/{id} (or watch the dashboard) until the status
changes. Template approval webhooks are on the roadmap.
Errors
| Status | When |
|---|---|
400 | Body missing required fields or malformed JSON |
401 | Missing / invalid API key |
403 | Key lacks templates:read or templates:write |
404 | Template not found, or not yet approved (read endpoints) |
409 | A template with the same template_name + language already exists |
422 | Validation error — bad component shape, illegal name characters |
See Errors for the response envelope.