What it is
WhatsApp templates are pre-approved message structures used to initiate or continue conversations outside the customer service window. A template is identified by WABA, name, and language. Use this guide to manage the API lifecycle and keep production template assets stable across teams, versions, and locales.Before you begin
- Connect the WABA that will own the template.
- Choose the template category, supported language, name, and components.
- Prepare representative variable and media examples required for review.
- Follow Meta policy for authentication, utility, and marketing content.
- Configure a webhook endpoint that can receive
whatsapp.template.reviewedevents.
How it works
- Create the template in a WABA.
- Store its name, language, category, and current
status. - Wait for approval when review is required.
- Retrieve or list templates to observe status changes.
- Send only a template that is valid for the target use case and in a sendable state.
- Edit or delete the template when its content or lifecycle changes.
Request
POST /whatsapp/templates
Response
PENDING does not mean the template can already be sent.
Define a stable asset identity
Treat each WABA, template name, and language combination as one asset. Keep an asset registry with the owningwabaId, stable name, exact locale code, purpose, owner, variable contract, current API status, rollout state, and replacement version.
Use a predictable name such as <domain>_<purpose>_v<major>:
auth_login_otp_v1orders_pickup_ready_v2growth_summer_offer_v3
Choose the category before writing content
Choose the category from the customer’s reason for receiving the message.
If a template mixes transactional information with a promotion, design it as marketing or split the purposes into separate templates.
Freeze the variable contract
Define variables as an API contract before copywriters or translators begin. For each variable, record its position, semantic meaning, format, source, representative example, and fallback behavior. For example,Order {{0}} is ready at {{1}}. can use this contract:
Keep each position’s meaning stable across versions and locales. Create a new version if you need to reorder or repurpose variables.
Before submission:
- Provide a safe, representative sample for every body or text-header variable.
- Validate media header URLs, formats, and file sizes.
- Keep a text header to at most one variable and include its sample.
- Confirm URL-button variables appear only where the API allows them, and include a complete sample URL.
- Never use credentials, one-time codes, personal data, or private media in review examples.
Organize locales as one release
Reuse the same versioned name for every locale in one release, but manage eachname and language pair as a separate asset. Keep variable meanings and button actions consistent even when word order changes.
Approve and release each locale independently. Never route a user to another language only because that locale is approved. Use the exact, case-sensitive locale code in create, retrieve, edit, delete, and send requests.
Gate sends on template status
Use retrieval orwhatsapp.template.reviewed webhooks to process approval, rejection, pause, disable, archive, and other lifecycle changes. Preserve the exact name and language used by message requests.
Store the API status separately from your rollout state. Only route production sends to a template whose current status is APPROVED and whose rollout state is active.
A successful create or edit response does not authorize production sends.
Synchronize state
Use Webhooks for prompt updates and retrieval or list APIs for reconciliation:- Verify the signature of each
whatsapp.template.reviewedevent. - Deduplicate deliveries by event
id. - Resolve the asset by
wabaId,name, andlanguage. - Store both the update event and current
status. - Stop routing immediately when the current status is not
APPROVED. - Retrieve the template when an event is missing, delayed, or conflicts with a newer registry state.
- Run a scheduled, paginated list reconciliation to detect drift.
Edit and delete behavior
- Edit only templates in a state supported by the endpoint.
- Include the complete desired component set in an edit request.
- Deleting by name removes every language with that name.
- Deleting by name and language removes only that localized template.
- Archived templates can still appear in list and retrieval results.
Release, roll back, and retire versions
Prefer a parallel version for material changes:- Create a new versioned name for every required locale. Keep the current approved version unchanged.
- Wait until each target locale is
APPROVED, then validate its variables, media, buttons, category, and rendered content. - Route a controlled share of eligible sends to the new version and monitor delivery, quality, replies, and status updates.
- Move the remaining traffic only after the new version meets your rollout criteria.
Limits and troubleshooting
- A send request fails when the template is not approved or its components do not match the message parameters.
- Authentication templates use restricted preset structures.
- Template category and content must align with Meta policy.
- Review rejection details before recreating the same content.
- Use a new name when a deleted or materially changed template cannot be restored safely.
Go-live checklist
- The name, purpose, owner, category, and version are recorded.
- Every variable has one meaning, format, safe example, and fallback rule.
- Media and buttons pass format, destination, and example checks.
- Every required locale is independently
APPROVED. - The send path rejects every status other than
APPROVED. - Webhook processing is verified, idempotent, and reconciled with retrieval.
- The rollout can restore a previous approved version.
- Queues, campaigns, configuration, tests, and runbooks use the intended version.
Supported languages
Select the exact language and regional locale code for a template.
Template creation examples
Adapt authentication, marketing, utility, commerce, Flow, and calling templates.
Create template API
Inspect the complete component schema.
Template review webhooks
Handle review and lifecycle state changes.

