Zernio
Zernio
PlatformsWhatsAppConnection & SetupBroadcastsTemplatesContacts & ProfilePhone NumbersCallingSandboxGroup ChatsInboxFlowsClick-to-WhatsApp AdsPricing & CostsMedia & Limits
Dashboard
llms.txtOpenAPI
OverviewPlatformsAPI ReferenceResources
WhatsApp

Templates

Create, list, and import Meta-approved WhatsApp message templates


Templates

WhatsApp templates are required for initiating conversations outside the 24-hour messaging window. They must be submitted to Meta for approval before use.

List Templates

const { data } = await zernio.whatsapp.getWhatsAppTemplates({
  query: { accountId: 'YOUR_ACCOUNT_ID' }
});
data.templates.forEach(t => console.log(`${t.name} (${t.status}) - ${t.language}`));

Create a Template

const { data } = await zernio.whatsapp.createWhatsAppTemplate({
  body: {
    accountId: 'YOUR_ACCOUNT_ID',
    name: 'order_confirmation',
    category: 'UTILITY',
    language: 'en',
    components: [{ type: 'body', text: 'Hi {{1}}, your order {{2}} has been confirmed!' }]
  }
});
console.log(`Template created: ${data.template.name} (${data.template.status})`);

Templates are reviewed by Meta and can take up to 24 hours to be approved. Only approved templates can be used for sending messages.

Delivery TTL

If a message cannot be delivered (phone off, no signal), WhatsApp keeps retrying for the template's time-to-live and drops it afterwards. Meta defaults to 10 minutes for AUTHENTICATION templates and 30 days for everything else, which is far too long for a delivery code or an order-ready notice. Set message_send_ttl_seconds on Create template to shorten it, or on either update endpoint to change it later (components is optional there when only the TTL changes).

CategoryAllowed rangeDefault
AUTHENTICATION30 to 900 seconds600
UTILITY30 to 43200 seconds (12 hours)30 days
MARKETING43200 to 2592000 seconds (12 hours to 30 days)30 days

-1 keeps the 30-day default on AUTHENTICATION and UTILITY, on create only (Meta rejects it on an edit). A value outside the category's range is a 400 with param: message_send_ttl_seconds. A TTL-only update does not send an approved template back to review; a component update does. Template reads return the field only while a custom TTL is set; if Meta recategorises a template, it clears the TTL, so read it back after a category change.

curl -X POST https://zernio.com/api/v1/whatsapp/templates \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "accountId": "YOUR_ACCOUNT_ID",
    "name": "order_ready",
    "category": "UTILITY",
    "language": "en",
    "message_send_ttl_seconds": 600,
    "components": [{"type": "body", "text": "Hi {{1}}, your order {{2}} is ready for pickup."}]
  }'

Template statuses

A template's status is Meta's review verdict, forwarded verbatim. Only an APPROVED template can be sent.

statusMeaning
PENDINGUnder Meta review.
APPROVEDLive — usable for sending.
REJECTEDMeta declined it. Fix the content and resubmit, or appeal the decision.
IN_APPEALA rejection appeal is being re-reviewed.
PAUSEDMeta paused delivery (typically negative recipient feedback); the template can't be sent while paused.
DISABLEDDisabled by Meta; the template can no longer be sent.
PENDING_DELETIONDelete requested; the template is removed after a 24-hour grace period.

Don't poll the template list to catch verdicts: the whatsapp.template.status_updated webhook fires whenever Meta finishes a (re)review of any template on the connected WABA, carrying the new status and Meta's reason ("NONE" on approval, an explanation string on rejection).

Import from the Template Library

Instead of writing a template, you can create one from Meta's pre-approved Template Library — these skip the review wait. Pass library_template_name instead of components.

Look the template up first to see its structure: a library template with URL or PHONE_NUMBER buttons requires a matching library_template_button_inputs array at create time (one entry per button, in order), or Meta rejects it with "give the same number of button inputs to match the library buttons." A library template usually exists in many languages — pass language to pick the right variant.

// 1. Look up the library template (to see its buttons + the exact language)
const { data: lib } = await zernio.whatsapp.getWhatsAppLibraryTemplate({
  query: { accountId: 'YOUR_ACCOUNT_ID', name: 'account_creation_confirmation_3', language: 'en_US' }
});

// 2. Create it, supplying inputs for its URL / PHONE_NUMBER buttons
const { data } = await zernio.whatsapp.createWhatsAppTemplate({
  body: {
    accountId: 'YOUR_ACCOUNT_ID',
    name: 'account_creation_confirmation_3',
    category: 'UTILITY',
    language: lib.template.language, // use the library template's actual code
    library_template_name: 'account_creation_confirmation_3',
    library_template_button_inputs: [
      { type: 'URL', url: { base_url: 'https://your-site.com/account', url_suffix_example: 'https://your-site.com/account' } }
    ]
  }
});
Was this page helpful?

Broadcasts

Send WhatsApp template messages to many recipients with per-recipient variables and scheduling

Contacts & Profile

Manage your WhatsApp contact list and business profile

On this page

TemplatesList TemplatesCreate a TemplateDelivery TTLTemplate statusesImport from the Template Library