Templates API

Template groups, AI localization and Meta approval status. 30 ops: list_template_languages, list_templates, get_template, create_template, update_template, save_template_localization, translate_template, review_template_localization, validate_template, check_template_content, submit_template, submit

Template groups, AI localization and Meta approval status.

List template languages · POST /api/v1/list_template_languages · scope templates:read or GET …?input=

Every language code Meta accepts for WhatsApp templates (en_US, es, pt_BR, ar…), with its name and whether it is written right to left. Use these codes as locales everywhere in the template ops.

curl -X POST https://getwabi.dev/api/v1/list_template_languages \  -H "Authorization: Bearer wabi_…"

List templates · POST /api/v1/list_templates · scope templates:read or GET …?input=

The organization's message templates: one entry per logical template (name and category) with every locale's newest version, its status (draft, submitted, pending, approved, rejected, paused, disabled), review state, quality rating, rejection reason and the version sends use. Filter by status, category, account or a search over name and description.

curl -X POST https://getwabi.dev/api/v1/list_templates \  -H "Authorization: Bearer wabi_…"

Get a template · POST /api/v1/get_template · scope templates:read or GET …?input=

One template with everything about it: variables with examples, every locale and version (content, Meta components, validation issues, AI translation notes, review), Meta submissions, status and quality history, and open alerts. Call it before editing, reviewing or submitting.

curl -X POST https://getwabi.dev/api/v1/get_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Create a template · POST /api/v1/create_template · scope templates:write

Creates a logical template (one name and category, with a localization per language) and its default-locale draft. Content uses {{variable}} placeholders with sample values in variables or content.examples. Nothing reaches Meta until submit_template. Defaults to the only connected account, else the sandbox. Returns the template with its validation result, so problems show before submission. Then translate_template for more languages.

curl -X POST https://getwabi.dev/api/v1/create_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"name":"Support","category":"utility","content":{}}'

Update a template · POST /api/v1/update_template · scope templates:write

Changes template-level settings: description, variables (meaning and samples), target locales, locale fallbacks, the default locale, or the category while nothing has been submitted. Locale content is edited with save_template_localization.

curl -X POST https://getwabi.dev/api/v1/update_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Save a template locale · POST /api/v1/save_template_localization · scope templates:write

Writes one locale's content (header, body, footer, buttons, examples). A draft or rejected version is updated in place; an approved, paused or disabled version gets a new version, submitted later as its own Meta template (<name>_v<n>) while the approved one keeps sending. Refused while Meta is reviewing it. Returns the localization with its validation result.

curl -X POST https://getwabi.dev/api/v1/save_template_localization \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locale":"es","content":{}}'

Translate a template with AI · POST /api/v1/translate_template · scope templates:write

Drafts more locales of a template with AI (Claude): the brand glossary applied, variables protected, sample values localized, parameters checked against the source. Each draft gets a confidence and a reviewer note and must be approved with review_template_localization before submission. Never overwrites a locale a person wrote, reviewed or submitted (overwrite: true redoes unreviewed AI drafts only).

curl -X POST https://getwabi.dev/api/v1/translate_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locales":["es"]}'

Review a template locale · POST /api/v1/review_template_localization · scope templates:write

Approves a locale's draft for submission, or requests changes with a note. AI drafts can only be submitted once approved here. Applies to the newest version unless version is given.

curl -X POST https://getwabi.dev/api/v1/review_template_localization \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locale":"es","decision":"approve"}'

Validate a template · POST /api/v1/validate_template · scope templates:read or GET …?input=

Checks every locale (or the ones given) against Meta's rules before submission: name, language code, header/body/footer limits, variables and their samples, buttons, authentication format, likely category mismatch, parameter consistency across locales, glossary use and missing target locales. Errors block submit_template; warnings are common rejection reasons. Changes nothing.

curl -X POST https://getwabi.dev/api/v1/validate_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Check template content · POST /api/v1/check_template_content · scope templates:read or GET …?input=

Validates content that is not saved yet (a builder preview, a file before apply_templates) against Meta's rules and the category, without touching any template. Returns the same issues as validate_template.

curl -X POST https://getwabi.dev/api/v1/check_template_content \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"name":"Support","category":"utility","content":{}}'

Submit a template to Meta · POST /api/v1/submit_template · scope templates:write

Submits a template's ready locales (or the ones given) to Meta for review, each as its own Meta template. Each locale must pass validation and, for AI drafts, review; a likely category mismatch blocks unless accept_category_warnings is true. Returns a result per locale (submitted, invalid, blocked, needs_review, failed, skipped). Meta decides within minutes to a day (the sandbox in ~60 s); statuses then update from webhooks and sync_templates.

curl -X POST https://getwabi.dev/api/v1/submit_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Submit templates in bulk · POST /api/v1/submit_templates · scope templates:write

Bulk submission: every ready draft locale of the given templates, or of every template when template_ids is omitted. Same checks and per-locale results as submit_template, grouped by template.

curl -X POST https://getwabi.dev/api/v1/submit_templates \  -H "Authorization: Bearer wabi_…"

Sync template statuses · POST /api/v1/sync_templates · scope templates:write

Reconciles every submitted template's status, quality rating, rejection reason and category with Meta now (it also runs on its own every few minutes, and webhooks update statuses as they happen). Returns what changed and templates Meta no longer has.

curl -X POST https://getwabi.dev/api/v1/sync_templates \  -H "Authorization: Bearer wabi_…"

Import templates from a WABA · POST /api/v1/import_templates · scope templates:write

Brings the templates that already exist on a connected WhatsApp Business Account under management (grouped by name, one localization per language, with Meta's status and quality), so they can be translated, analyzed and replaced here. Skips ones already tracked. Defaults to the only connected account, else the sandbox.

curl -X POST https://getwabi.dev/api/v1/import_templates \  -H "Authorization: Bearer wabi_…"

Resolve the template to send · POST /api/v1/resolve_template · scope templates:read or GET …?input=

Which approved localization to send for a locale or a contact (their saved locale): the exact locale, then configured fallbacks, then another variant of the language, then the default locale. Never picks an unapproved one; reports any substitution in fallback and why each other locale was skipped. Returns Meta's name and language for send_message and the parameters to pass. 409 no_approved_locale when nothing approved fits.

curl -X POST https://getwabi.dev/api/v1/resolve_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Pin a template version (rollback) · POST /api/v1/pin_template_version · scope templates:write

Chooses which approved version of a locale sends use: a rollback to an earlier approved version, or back to the newest approved one with version null. Only approved versions can be pinned.

curl -X POST https://getwabi.dev/api/v1/pin_template_version \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locale":"es","version":1}'

Compare template versions · POST /api/v1/compare_template_versions · scope templates:read or GET …?input=

Field-by-field differences between two versions of one locale (header, body, footer, buttons, examples), with each version's status and Meta name.

curl -X POST https://getwabi.dev/api/v1/compare_template_versions \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locale":"es","from":1,"to":1}'

Archive a template · POST /api/v1/archive_template · scope templates:write

Hides a template from lists and stops it from being edited or submitted. Its Meta templates are left as they are (delete them in Meta if they should stop existing) and its history stays.

curl -X POST https://getwabi.dev/api/v1/archive_template \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id"}'

Delete a template draft · POST /api/v1/delete_template_draft · scope templates:write

Deletes a locale's draft version that was never submitted to Meta (the newest unless version is given). Submitted versions are kept for their history.

curl -X POST https://getwabi.dev/api/v1/delete_template_draft \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"template_id":"template_id","locale":"es"}'

List starter templates · POST /api/v1/list_template_library · scope templates:read or GET …?input=

The starter library: ready-to-submit templates for one-time passwords, booking confirmations, appointment reminders, driver assignment, payment receipts, delivery and trip updates, support cases, cancellations and schedule changes, feedback and re-engagement, each in the category Meta would give it and why.

curl -X POST https://getwabi.dev/api/v1/list_template_library \  -H "Authorization: Bearer wabi_…"

Install starter templates · POST /api/v1/install_template_library · scope templates:write

Adds starter templates (all, or the keys given) to an account as English drafts, optionally drafting more locales with AI and submitting the English ones. Skips any already installed. Returns each template's id.

curl -X POST https://getwabi.dev/api/v1/install_template_library \  -H "Authorization: Bearer wabi_…"

Apply template definitions · POST /api/v1/apply_templates · scope templates:write

Syncs templates from a definition file kept in a repository (YAML or JSON text in source, or the parsed object in definitions): creates missing templates and locales, updates changed drafts, opens replacement versions for changed approved locales, drafts translate: locales with AI and submits when submit: true. dry_run: true returns the plan without changing anything. Idempotent: applying the same file twice changes nothing. Never deletes. CLI: wabi apply_templates --source "$(cat templates.yaml)" --dry_run true.

curl -X POST https://getwabi.dev/api/v1/apply_templates \  -H "Authorization: Bearer wabi_…"

Export template definitions · POST /api/v1/export_templates · scope templates:read or GET …?input=

The definition file (YAML or JSON) for existing templates, newest version of each locale, to commit to a repository and manage with apply_templates from then on.

curl -X POST https://getwabi.dev/api/v1/export_templates \  -H "Authorization: Bearer wabi_…"

List the brand glossary · POST /api/v1/list_template_glossary · scope templates:read or GET …?input=

The brand glossary used by translate_template: terms kept verbatim in every language (brand and product names) and terms with a mandatory translation per locale.

curl -X POST https://getwabi.dev/api/v1/list_template_glossary \  -H "Authorization: Bearer wabi_…"

Set a glossary term · POST /api/v1/set_template_glossary_term · scope templates:write

Adds or replaces a brand glossary term: do_not_translate for names that stay verbatim, or translations per locale ({ "es": "reserva" }). Applies to translations drafted from now on and to the glossary checks.

curl -X POST https://getwabi.dev/api/v1/set_template_glossary_term \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"term":"term"}'

Delete a glossary term · POST /api/v1/delete_template_glossary_term · scope templates:write

Removes a term from the brand glossary, by id or by the term itself.

curl -X POST https://getwabi.dev/api/v1/delete_template_glossary_term \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"term":"term"}'

List template alerts · POST /api/v1/list_template_alerts · scope templates:read or GET …?input=

Open alerts about templates: rejected, paused or disabled by Meta, quality dropping to yellow or red, or Meta filing a template under another category. Each says what happened and what to do.

curl -X POST https://getwabi.dev/api/v1/list_template_alerts \  -H "Authorization: Bearer wabi_…"

Acknowledge a template alert · POST /api/v1/acknowledge_template_alert · scope templates:write

Marks a template alert as handled; it no longer shows as open. A repeat of the same problem opens a new one.

curl -X POST https://getwabi.dev/api/v1/acknowledge_template_alert \  -H "Authorization: Bearer wabi_…" \  -H "Content-Type: application/json" \  -d '{"alert_id":"6f1c2e0a-4b7d-4c2e-9a51-0d3b8e7f9a10"}'

Template analytics · POST /api/v1/get_template_analytics · scope templates:read or GET …?input=

Per template and locale over a date range (default the last 30 days): attempts, sent, delivered, read, failed, button clicks, replies, opt-outs and their rates from first-party message events, next to Meta's aggregate template analytics and cost, with discrepancies between the two labeled and explained. With template_id, also its status and quality history.

curl -X POST https://getwabi.dev/api/v1/get_template_analytics \  -H "Authorization: Bearer wabi_…"

Refresh template analytics · POST /api/v1/refresh_template_analytics · scope templates:write

Recomputes first-party template numbers from messages and pulls Meta's template analytics for the date range (default the last 30 days). Runs on its own every hour; call it to see the latest now.

curl -X POST https://getwabi.dev/api/v1/refresh_template_analytics \  -H "Authorization: Bearer wabi_…"