Send template messages with variables
Save a message once with {{variable}} placeholders, then render it for each recipient with a fresh set of values. A template keeps your copy consistent — an order confirmation, an OTP notice, a status update — and one POST sends the rendered text to any chat.
This guide shows you how to create, list, fetch, update, and delete templates, and how to send a rendered template to a chat.
- A session in the
readystate — see Connect a Session. - An API key with the operator role or higher, sent as
X-API-Key— see Authentication.
All examples use these placeholders. Set them once in your shell:
export BASE="http://localhost:2785/api" # /api is the global prefix; behind your domain + TLS in production
export API_KEY="YOUR_API_KEY" # an operator-or-higher key, from your dashboard
export SESSION="8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a" # the UUID id of a ready session
Create a template
Send a POST to /api/sessions/{sessionId}/templates. name and body are required; header and footer are optional. Use {{variable}} tokens in the body for the parts that change per recipient.
curl -X POST "$BASE/sessions/$SESSION/templates" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"name": "order-confirmation",
"body": "Hi {{customer}}, your order {{orderId}} has shipped.",
"header": "OpenWA Store",
"footer": "Reply STOP to unsubscribe."
}'
A 201 returns the stored template with its id and timestamps:
{
"id": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"sessionId": "8f3c2b1a-9d4e-4c7a-8b2f-1e6d5a4c3b2a",
"name": "order-confirmation",
"body": "Hi {{customer}}, your order {{orderId}} has shipped.",
"header": "OpenWA Store",
"footer": "Reply STOP to unsubscribe.",
"createdAt": "2026-07-28T10:00:00.000Z",
"updatedAt": "2026-07-28T10:00:00.000Z"
}
name is unique within the session and capped at 100 characters. The rendered body is capped at 4096 characters; header and footer at 1024 each.
Send a rendered template
POST /api/sessions/{sessionId}/messages/send-template takes the recipient chatId and either templateId or templateName, plus a vars object whose keys substitute the {{tokens}} in the body.
curl -X POST "$BASE/sessions/$SESSION/messages/send-template" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chatId": "628123456789@c.us",
"templateName": "order-confirmation",
"vars": {
"customer": "Alice",
"orderId": "1234"
}
}'
A 201 means the template rendered and the message was sent. A 400 means the session is not active or the request is invalid; a 404 means the session or the template does not exist.
Send by id instead of name when you want to pin a specific revision:
curl -X POST "$BASE/sessions/$SESSION/messages/send-template" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chatId": "628123456789@c.us",
"templateId": "b1c2d3e4-f5a6-7890-bcde-f01234567890",
"vars": { "customer": "Bob", "orderId": "5678" }
}'
List templates
GET /api/sessions/{sessionId}/templates returns every template for the session as an array.
curl "$BASE/sessions/$SESSION/templates" \
-H "X-API-Key: $API_KEY"
Fetch a template by id
GET /api/sessions/{sessionId}/templates/{id} returns one template. A 404 means the id does not exist for this session.
curl "$BASE/sessions/$SESSION/templates/b1c2d3e4-f5a6-7890-bcde-f01234567890" \
-H "X-API-Key: $API_KEY"
Update a template
PUT /api/sessions/{sessionId}/templates/{id} replaces the fields you send — name, body, header, footer — and returns the updated template. All fields are optional on update; omitted fields keep their current value.
curl -X PUT "$BASE/sessions/$SESSION/templates/b1c2d3e4-f5a6-7890-bcde-f01234567890" \
-H "X-API-Key: $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"body": "Hi {{customer}}, your order {{orderId}} is out for delivery."
}'
Delete a template
DELETE /api/sessions/{sessionId}/templates/{id} removes the template and returns 204 with no body.
curl -X DELETE "$BASE/sessions/$SESSION/templates/b1c2d3e4-f5a6-7890-bcde-f01234567890" \
-H "X-API-Key: $API_KEY"
Troubleshooting
| Problem | Cause | Fix |
|---|---|---|
404 Template not found | The id does not belong to this session, or the template was deleted | List templates to get a current id |
404 Session or template not found on send | The template name/id does not exist, or the session is not started | Confirm the session is ready and the template exists |
400 Session not active or invalid request | Session is not in a sendable state, or vars does not match the body tokens | Start the session; keep vars keys aligned with the {{tokens}} in the body |
Template text arrives with {{tokens}} unrendered | vars omitted a key the body references | Provide every token used in the body |
Next steps
- Send other message types — see Send messages from a session.
- See the full request and response shapes in the API reference.
- Learn how to keep account copy consistent with Webhooks for delivery receipts.