Skip to main content
A template is pre-approved content. It is the only way to message someone outside the 24-hour customer-service window, so most production traffic is templates. Templates belong to your workspace and mode — there is no accountId query parameter. LazyApp submits to Meta on the connected WABA for that workspace.

Quick start

List templates

GET /v1/templates returns cursor-paginated templates for the workspace. Response fields include uuid, name, language, category, status, body_text, header, buttons, rejection_reason, quality_score, and Meta’s provider_template_id when assigned. Retrieve one template by name or uuid: GET /v1/templates/{template}.

Categories

Meta requires one of three, and it drives pricing:
Meta re-categorises templates it judges to be miscategorised, which changes what you pay. A promotional message dressed as a utility template will be moved to marketing, and you receive a template.category_changed webhook.

Create a template

LazyApp uses a flat native shape on POST /v1/templates, not Zernio’s Meta components array on /whatsapp/templates:
Rules:
  • Names: lowercase letters, digits, underscores only (^[a-z0-9_]+$), unique per language in the workspace.
  • body_examples: one realistic string per {{n}} placeholder — Meta rejects templates it cannot evaluate.
  • submit: defaults to true (submit immediately). Pass "submit": false to keep a local draft.

Headers and buttons

header.format is NONE, TEXT, IMAGE, VIDEO, GIF, DOCUMENT, LOCATION or PRODUCT. Button types: QUICK_REPLY, URL, PHONE_NUMBER, OTP, FLOW, COPY_CODE, CATALOG, MPM, SPM and VOICE_CALL. URL buttons must be https://. Media headers need a sample for Meta’s review: upload it with POST /v1/templates/media and pass the handle as header.example_handle. Carousels, GIF headers, call buttons, call permission requests, delivery time limits and library templates are on Template formats. Authentication templates can pass:

Meta-shaped create (proxy)

If you already have Kapso/Cloud API payloads, create via the proxy with Meta’s components envelope:
See Migrating from Cloud API.

Template statuses

Only approved templates can be sent. LazyApp stores lowercase statuses mapped from Meta:
Meta review usually takes minutes but can take up to 24 hours. Do not poll the list in a tight loop — subscribe to template webhooks.

Webhooks

Pausing, categories, groups, comparisons, archiving and copying templates between accounts are on Managing templates.

Starter template sets

Platforms can seed templates when a customer connects via template_set on setup links. Discover valid keys:
Returns named packs (for example real_estate) with template names and languages — do not hardcode keys across deployments.

Sync and delete

Pull changes made in Meta Business Manager:
LazyApp also updates statuses from Meta webhooks; sync is for reconciliation. Delete at Meta and mark deleted locally:

Sending a template

See Messages, Broadcasts, or Events to pick the template for you. Each card of a carousel template needs its own image or video (or, on a product carousel, its own product) when you send it; the review sample is not reused. Add values for variables in the card text, the ending of any card link and, optionally, a payload for each quick reply. Pass them per card in template.features.cards, in card order:
LazyApp builds Meta’s carousel component from these and refuses the send with a field-level 422 when a card is missing its media, product or values. A media carousel takes exactly as many cards as it was approved with; a product carousel can show 1 to 10 products. See Template formats for every features key. Broadcasts take the same inputs in variable_map.features.cards, and the campaign form in the console asks for each card.
template.carousel (and variable_map.carousel on broadcasts) is an older alias and still accepted: each entry takes media, body and buttons keyed by index, where buttons holds link endings and quick-reply payloads alike. When both are sent, features.cards wins. Use features.cards in new code.

What we skip (Zernio-style)