Skip to Content
Official · Meta Cloud APITemplates & Campaigns

Templates & Campaigns

Templates are pre-approved message blueprints — and the only way to start a conversation with a user who is outside your 24-hour window. Meta has three categories, all handled by the same two functions:

  • MARKETING — promos, announcements, offers.
  • UTILITY — transactional notices (order confirmed, appointment reminder).
  • AUTHENTICATION — one-time passwords (OTP).

Sending a template

sendTemplate(to, name, language, components?) — it takes the template name, not its id.

// template with a body variable {{1}} await wa.sendTemplate(to, 'promo_juli', 'id', [ { type: 'body', parameters: [{ type: 'text', text: 'Budi' }] }, ]) // template with an image header await wa.sendTemplate(to, 'flash_sale', 'id', [ { type: 'header', parameters: [{ type: 'image', image: { link: 'https://…/banner.jpg' } }] }, { type: 'body', parameters: [{ type: 'text', text: '50%' }] }, ])
⚠️

The number of parameters must exactly match the {{n}} placeholders, or Meta returns error 132000. Introspect a template first with wa.cloud.templates.get(nameOrId) to see its components.

sendTemplate(to, name, language, components?)

ParameterTypeNotes
tostringRecipient phone number (bare digits or JID).
namestringThe approved template’s name.
languagestringLanguage/locale code, e.g. id, en_US.
componentsarray?Header/body/button parameter objects; omit for static templates.

Returns the sent message key. Delivery is tracked via the message-status event.

OTP (one-time passwords)

Authentication templates are usually approved instantly. Create one, then send codes:

// 1) create the OTP template (once) await wa.cloud.templates.create({ name: 'kode_otp', category: 'AUTHENTICATION', language: 'id', components: [ { type: 'BODY', add_security_recommendation: true }, { type: 'FOOTER', code_expiration_minutes: 5 }, { type: 'BUTTONS', buttons: [{ type: 'OTP', otp_type: 'COPY_CODE' }] }, ], }) // 2) send a code — passed to both the body and the copy-code button await wa.sendTemplate(to, 'kode_otp', 'id', [ { type: 'body', parameters: [{ type: 'text', text: '839201' }] }, { type: 'button', sub_type: 'url', index: '0', parameters: [{ type: 'text', text: '839201' }] }, ])

Managing templates

MethodPurpose
wa.cloud.templates.list({ status?, limit? })List all templates on the WABA.
wa.cloud.templates.get(nameOrId)Fetch one template with its components (accepts a name or numeric id).
wa.cloud.templates.create({ name, category, language, components })Submit a new template for review.
wa.cloud.templates.delete(name, id?)Delete a template by name.
await wa.cloud.templates.list({ status: 'APPROVED' }) const tpl = await wa.cloud.templates.get('1783414372642659') // → components, category, language await wa.cloud.templates.delete('promo_juli')

The template-status event

Template review results arrive on the webhook:

wa.on('template-status', (t) => { console.log(t.name, t.event) // APPROVED / REJECTED / PAUSED / … })

Requires cloud.wabaId. All template management is WABA-scoped and throws ZaileysCloudError('CONFIG') if wabaId is missing.

Marketing campaigns

Combine templates with the shared broadcast() helper:

Create and approve the template

wa.cloud.templates.create({ category: 'MARKETING', … }), then wait for the template-status event (or poll templates.get) to reach APPROVED.

Broadcast to your audience

// per-recipient variables — loop sendTemplate: for (const { phone, name } of contacts) { await wa.sendTemplate(phone, 'promo_juli', 'id', [ { type: 'body', parameters: [{ type: 'text', text: name }] }, ]) } // or a static template to many numbers with rate limiting: await wa.broadcast(numbers, (b) => b, { rateLimitPerSec: 10, onProgress: (done, total) => console.log(`${done}/${total}`), })

Track delivery and results

wa.on('message-status', (s) => console.log(s.id, s.status)) // sent/delivered/read/failed const stats = await wa.cloud.analytics.messages({ start, end })

Marketing templates are subject to Meta’s per-user daily marketing limit and quality-based messaging tiers. Keep content relevant and honor opt-outs to protect your quality rating — check it any time with wa.cloud.info().

Last updated on