Templates
Register and sync WhatsApp message templates per channel.
Templates
WhatsApp requires you to use a template for any message sent outside an active 24-hour customer-service window. A template is a Meta-approved message body with placeholders that you fill in at send time.
TryVox templates are tied to a single channel. The same template name can exist on multiple channels — each is a separate Meta-side approval.
Endpoints
| Method | Path | Purpose |
|---|---|---|
GET | /v1/messaging/channels/{channel_id}/templates | List templates on this channel |
POST | /v1/messaging/channels/{channel_id}/templates | Create a template (submits to Meta for approval) |
POST | /v1/messaging/channels/{channel_id}/templates/sync | Pull template state from Meta into TryVox |
GET | /v1/messaging/templates | List templates across all channels on the tenant |
List templates on a channel
GET /v1/messaging/channels/{channel_id}/templatescurl -u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
https://api.tryvox.io/v1/messaging/channels/$CHANNEL_ID/templatesResponse
200 OK:
{
"data": [
{
"id": "1b2c3d4e-5f60-7180-9a2b-3c4d5e6f7a8b",
"channel_id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"name": "login_otp",
"language": "en_US",
"category": "AUTHENTICATION",
"status": "APPROVED",
"components": "[{\"type\":\"BODY\",\"text\":\"Your code is {{1}}\"}]",
"created_at": "2026-04-09T10:30:00Z",
"updated_at": "2026-04-09T10:35:12Z"
}
]
}The components field is a JSON string — parse it with JSON.parse() to get the structured Meta shape.
Create a template
POST /v1/messaging/channels/{channel_id}/templatesSubmits the template to Meta for approval. The TryVox record is created in PENDING and flips to APPROVED (or REJECTED) after Meta reviews. Approval typically takes minutes for AUTHENTICATION and UTILITY templates, and can take hours for MARKETING.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Template name. Lowercase, snake_case, unique per channel and language. |
language | string | yes | Language code in Meta's BCP-47-ish format (e.g. en_US, en_IN, hi_IN). |
category | string | yes | AUTHENTICATION, UTILITY, or MARKETING. |
components | string | yes | JSON-stringified component array (Meta's shape). |
Example
curl -X POST https://api.tryvox.io/v1/messaging/channels/$CHANNEL_ID/templates \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
-H "Content-Type: application/json" \
-d '{
"name": "appointment_reminder",
"language": "en_US",
"category": "UTILITY",
"components": "[{\"type\":\"BODY\",\"text\":\"Reminder: your appointment is on {{1}} at {{2}}.\",\"example\":{\"body_text\":[[\"April 12\",\"10:00am\"]]}}]"
}'Response
201 Created:
{
"id": "2c3d4e5f-6071-8293-a4b5-c6d7e8f9a0b1",
"channel_id": "8f7a4b2e-91c2-4f3d-9a1e-2c4b6d8f0a1c",
"name": "appointment_reminder",
"language": "en_US",
"category": "UTILITY",
"status": "PENDING",
"components": "[{\"type\":\"BODY\",\"text\":\"Reminder: your appointment is on {{1}} at {{2}}.\"}]",
"created_at": "2026-04-09T10:40:00Z"
}The send API will reject template_name lookups while status is PENDING or REJECTED. Wait for APPROVED or call Sync.
Sync templates
POST /v1/messaging/channels/{channel_id}/templates/syncPulls the current template list from Meta and reconciles it with TryVox. Use this when:
- You created templates directly in Meta Business Manager (not through the API) and need TryVox to know about them.
- A template's status changed (Meta approved or rejected since you last checked) and you want the local record refreshed.
- Templates were edited or deleted upstream.
curl -X POST \
-u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
https://api.tryvox.io/v1/messaging/channels/$CHANNEL_ID/templates/syncResponse
200 OK:
{
"synced": 12,
"created": 1,
"updated": 3,
"deleted": 0
}The full template list is also returned in the response body so you don't have to follow up with a GET.
List across all channels
GET /v1/messaging/templatesReturns templates across every channel on the tenant. Useful for an admin UI that compares template availability across numbers.
curl -u $TRYVOX_AUTH_ID:$TRYVOX_AUTH_TOKEN \
https://api.tryvox.io/v1/messaging/templatesThe response includes a channel_id on each entry so you can group client-side.
Component reference
Meta's component shapes — TryVox passes these through verbatim:
[
{"type": "HEADER", "format": "TEXT", "text": "Hi {{1}}"},
{"type": "BODY", "text": "Your code is {{1}}. Valid for 5 minutes."},
{"type": "FOOTER", "text": "Reply STOP to opt out."},
{"type": "BUTTONS", "buttons": [
{"type": "URL", "text": "View order", "url": "https://example.com/orders/{{1}}"}
]}
]Use the example field on text components to give Meta sample variable values for review — required for MARKETING, recommended for everything else.
Errors
| Status | Code | Reason |
|---|---|---|
| 400 | VALIDATION_FAILED | components not valid JSON, or required field missing |
| 401 | INVALID_CREDENTIALS | Auth ID / Auth Token bad |
| 404 | CHANNEL_NOT_FOUND | channel_id not on this tenant |
| 409 | TEMPLATE_NAME_TAKEN | (name, language) already exists on this channel |
| 502 | META_ERROR | Meta rejected the create — body includes Meta's error JSON |
Notes
- Names are stable. Once approved you can't rename a template. Create a new one and migrate sends.
- Quality rating affects throughput. Meta limits the daily messaging volume for templates with low quality ratings. Watch for
MESSAGING_LIMIT_TIERwarnings on the channel. - Editing templates is supported by Meta but not exposed on this API yet. Edit in Business Manager and then
Syncto pull the change.