Skip to main content

Create and Manage WhatsApp Templates

A template is a message Meta approves in advance, so you can send it to a customer at any time. With the Public API your systems can create a WhatsApp number's templates, edit them and delete them, as on the dashboard's WhatsApp page. Meta reviews every new template and every change before it can be sent.

How do I create a template?​

Find the number's connection id as for listing templates, then POST the template:

curl -X POST https://api.mojeeb.app/v1/agents/YOUR_AGENT_ID/connections/YOUR_CONNECTION_ID/whatsapp-templates \
-H "Authorization: Bearer mk_live_YOUR_KEY_HERE" \
-H "Content-Type: application/json" \
-d '{
"name": "order_shipped",
"language": "en",
"category": "utility",
"body": "Hi {{1}}, your order {{2}} is on its way.",
"body_examples": { "1": "Sara", "2": "A-100" },
"footer": "Acme Clinics",
"buttons": [
{ "type": "url", "text": "Track order", "url": "https://example.com/track/{{1}}", "example": "A-100" }
]
}'

The answer is 201 with the template, usually status: pending. Every field is in the Create a template reference.

How do variables and samples work?​

Write variables as {{1}}, {{2}} and so on, in order, or as lower-case names such as {{first_name}}, with one style across the header and the body. Meta reviews a template with sample values, so give one for each variable: body_examples maps each body variable to a sample, keyed the way a send's parameters are ("1" or "first_name"), and header.example is the sample for a text header's one variable.

How do I add an image, video or document header?​

Set header.format and give header.media_url, an https link to a sample file. Mojeeb downloads it once and hands it to Meta for the review. When you send the template, you can send a different file with template.header_media_url. The link must answer with the file itself, with the file's type as its Content-Type, from a public address; redirects aren't followed. The reference lists the file types and the size Mojeeb accepts.

Which buttons can a template have?​

Quick replies, links (url, which may end with a {{1}} that a send fills in), one phone number and one copy-code button. Keep the quick replies together, before or after the other buttons. Location headers, carousels, limited-time offers, and catalog and Flow buttons are made in WhatsApp Manager, because Mojeeb can't send them yet.

How do I create a verification-code template?​

Set category to authentication and describe the code button in otp. copy_code lets the customer copy the code; one_tap and zero_tap hand it to your Android app, listed in supported_apps. Meta writes the message itself in the template's language, and you choose only whether it adds a security line and when the code expires:

{
"name": "login_code",
"language": "en",
"category": "authentication",
"otp": { "type": "copy_code", "add_security_recommendation": true, "code_expiration_minutes": 10 }
}

To send it, give the code as the body's "1" and as the button's otp_code; see Send a WhatsApp Template.

How do I know when Meta approves it?​

Read the template with GET on its id (Get a template) until status is no longer pending. approved can be sent; rejected says why in rejected_reason. Meta's review can take up to a day, so check every few minutes rather than every second: the template endpoints share a small rate limit, which Rate Limits explains.

How do I edit a template?​

PUT its whole content to its id. Meta replaces every part on an edit, so send everything it should say, not only the change. The name and language never change; leave category out to keep it. A media header sent without media_url keeps its sample; one that changes format needs media_url. Meta lets you edit an approved template once a day and ten times a month, and reviews each edit; content that equals what Meta already holds isn't sent and uses no edit. An authentication template, message_send_ttl_seconds or a new media_url always counts as a change, because Meta's list doesn't show them to compare. See the Edit a template reference.

How do I delete a template?​

DELETE it by id. This removes that one language version; its other languages stay. Deleting an approved or paused template locks its name at Meta for 30 days, so add ?acknowledge_name_lock=true; without it the API answers 409 template_delete_locks_name with the date. A deleted template can't be restored. See the Delete a template reference.

Why was my template refused?​

Nothing is sent to Meta until the template follows Meta's rules that Mojeeb can check:

  • 422 invalid_request_body: a part its category doesn't take, a variable without a sample, or buttons in the wrong order. param names the field, such as buttons[1].url.
  • 422 template_header_media_url_invalid: Mojeeb couldn't download the header's sample; the message says why.
  • 422 template_rejected: Meta refused the template, and the message is Meta's reason. An edit Meta wouldn't take, such as a new category for an approved template, is refused the same way before it reaches Meta.
  • 409 template_name_taken: the number already has a template with this name in this language.
  • 409 template_status_not_allowed, template_edit_limit_reached or template_in_use_by_broadcast: the template can't change right now.

Errors lists every code.

Common questions​

Can I retry a create that timed out?​

Yes. If the first one reached Meta, the retry answers 409 template_name_taken, because the name now exists in that language. Read the list to find it. A create needs no Idempotency-Key.

Do templates created through the API show in the dashboard?​

Yes. Templates live at Meta, on the number's WhatsApp Business Account, so the dashboard's WhatsApp page and WhatsApp Manager show them all, however they were made.

Which scopes do these calls need?​

whatsapp_templates:write to create, edit and delete templates, and whatsapp:read to read them. Every key holds both today; see Authentication.

Can an AI assistant create templates?​

Yes. Through the MCP server an assistant can create, read and edit templates, but never delete them.