← SentCONTENT HISTORYWHAT CHANGED · RULE-BASED ANALYSIS
Update to Sent
Snapshot Sep 30, 2026 · 22:48 UTC · version 1.0.0
Collection source: not recorded for this historical snapshot.
First saved snapshot
No earlier snapshot is available to establish a change.
Compare saved observations
Download comparison JSONFull technical diff · 0 changed fields
Full snapshot data
{
"name": "waba-template-author",
"description": "Writes, classifies, validates, and repairs WhatsApp templates using the Sent v3 template definition contract. Use for utility, marketing, authentication, OTP, Meta review, rejected templates, variables, buttons, channel overrides, or submission-ready Sent payloads.",
"included_files": [
{
"relative_path": "agents/openai.yaml",
"size_in_bytes": 210
},
{
"relative_path": "references/template-rejection-playbook.md",
"size_in_bytes": 2759
},
{
"relative_path": "references/waba-template-categories.md",
"size_in_bytes": 2303
},
{
"relative_path": "references/waba-template-examples.md",
"size_in_bytes": 2855
},
{
"relative_path": "scripts/fixtures/utility_bad.json",
"size_in_bytes": 220
},
{
"relative_path": "scripts/fixtures/utility_good.json",
"size_in_bytes": 1960
},
{
"relative_path": "scripts/lint_waba_template.py",
"size_in_bytes": 15175
}
],
"skill_md_contents": "---\nname: waba-template-author\ndescription: Writes, classifies, validates, and repairs WhatsApp templates using the Sent v3 template definition contract. Use for utility, marketing, authentication, OTP, Meta review, rejected templates, variables, buttons, channel overrides, or submission-ready Sent payloads.\n---\n\n# WhatsApp Template Author\n\nUse this skill to turn a messaging intent into a valid body for `POST /v3/templates`, review it for WhatsApp policy risk, and explain the resulting lifecycle. Sent's template request is not Meta's Cloud API `components[]` shape.\n\n## Source precedence\n\nWhen official sources disagree:\n\n1. Use the live Sent v3 OpenAPI for paths, request fields, and response shapes.\n2. Use the most specific current Sent guide for lifecycle and policy semantics.\n3. Preserve unknown provider values instead of forcing them into a closed enum.\n\nThe canonical references are the Sent template-definition guide, the v3 OpenAPI, and the webhook events reference. Do not use snapshot-era v2 examples.\n\n## Authoring workflow\n\n### 1. Establish intent and category\n\nCollect the business event, recipient expectation, requested action, language, channel overrides, and realistic sample values. Choose:\n\n- `UTILITY` for a specific non-promotional transaction, account, or service event.\n- `MARKETING` for promotions, offers, re-engagement, product discovery, or mixed promotional content.\n- `AUTHENTICATION` for one-time verification codes and supported authentication flows.\n\nIf content mixes utility and promotion, classify it as marketing or split it. See [references/waba-template-categories.md](references/waba-template-categories.md).\n\n### 2. Build the Sent create request\n\n`POST /v3/templates` accepts these top-level fields:\n\n| Field | Requirement |\n| --- | --- |\n| `definition` | Required. Contains `header`, `body`, `footer`, `buttons`, optional `definitionVersion`, and optional `authenticationConfig`. |\n| `category` | Optional: `UTILITY`, `MARKETING`, or `AUTHENTICATION`; omit for detection only when ambiguity is acceptable. |\n| `language` | Optional locale such as `en_US`. |\n| `creation_source` | Optional source string; `from-api` is the documented default. |\n| `submit_for_review` | Optional Boolean; default `false`. Draft and validate before review. |\n| `sandbox` | Optional Boolean for validation without side effects. |\n\nDo not put `name`, `channels`, `body`, `header`, `buttons`, or `components` at the request root. `name` exists on update/response surfaces, not on the current create request.\n\n```json\n{\n \"category\": \"UTILITY\",\n \"language\": \"en_US\",\n \"definition\": {\n \"header\": null,\n \"body\": {\n \"multiChannel\": {\n \"type\": \"body\",\n \"template\": \"Hi {{0:variable}}, order {{1:variable}} has shipped.\",\n \"variables\": [\n {\n \"id\": 0,\n \"name\": \"customerName\",\n \"type\": \"variable\",\n \"props\": {\"sample\": \"Avery\"}\n },\n {\n \"id\": 1,\n \"name\": \"orderNumber\",\n \"type\": \"variable\",\n \"props\": {\"sample\": \"A-1042\"}\n }\n ]\n },\n \"sms\": null,\n \"whatsapp\": null,\n \"rcs\": null\n },\n \"footer\": null,\n \"buttons\": null,\n \"definitionVersion\": \"1.0\",\n \"authenticationConfig\": null\n },\n \"creation_source\": \"from-api\",\n \"submit_for_review\": false,\n \"sandbox\": true\n}\n```\n\nUse `definition.body.multiChannel` as the channel-neutral body. `sms`, `whatsapp`, and `rcs` are complete channel overrides, not fragments. Keep each body at or below 1,024 characters.\n\n### 3. Define variables exactly\n\nUse placeholders such as `{{0:variable}}`, `{{1:link}}`, or `{{2:media}}`. Each placeholder needs one matching definition with:\n\n- a unique non-negative integer `id`;\n- a readable `name`;\n- a matching `type`;\n- `props.sample` with realistic review and preview data.\n\nKeep placeholder IDs and variable IDs aligned inside every body override. Never output naked `{{1}}` placeholders in a Sent request.\n\n### 4. Add supported buttons\n\nSent currently recognizes `QUICK_REPLY`, `URL`, `VOICE_CALL`, `PHONE_NUMBER`, and `COPY_CODE`. Enforce:\n\n- 10 buttons total;\n- at most 2 URL buttons;\n- at most 1 voice-call button;\n- at most 1 phone-number button;\n- at most 1 copy-code button;\n- quick replies may use the remaining slots, up to the total of 10.\n\nButtons use `id`, `type`, and `props`. Labels are at most 25 characters. Require type-specific properties: `quickReplyType`; `urlType` and `url`; `countryCode` and `phoneNumber`; or `offerCode`. Quick replies and calls-to-action may coexist—do not invent an XOR rule.\n\n### 5. Handle authentication templates\n\nFor `AUTHENTICATION`, use `definition.authenticationConfig`:\n\n```json\n{\n \"addSecurityRecommendation\": true,\n \"codeExpirationMinutes\": 10\n}\n```\n\nExpiration is 1–90 minutes. Keep authentication content to the verification purpose, use one code variable and the supported copy-code action, and do not add marketing language, unrelated links, media, or promotional buttons.\n\n### 6. Validate before submission\n\nRun:\n\n```bash\npython scripts/lint_waba_template.py template.json\n```\n\nThe linter validates the Sent request shape, variables, the 1,024-character limit, channel overrides, every current button type, per-type limits, and authentication configuration. A Meta Cloud API example with `components[]` must fail with an explicit conversion error.\n\nUse `sandbox: true` and `submit_for_review: false` while integrating. When the user is ready for provider review, show the final payload and explain that submission changes external state before proceeding.\n\n### 7. Track the right lifecycle surface\n\nSent template resources use the known states `DRAFT`, `PENDING`, `APPROVED`, `REJECTED`, and `PAUSED`. Do not claim this is every value the API may ever return.\n\nTemplate webhooks are WhatsApp approval events. They use `field: \"templates\"`, omit `sub_type` and `event`, and carry the provider status in `payload.status`:\n\n```json\n{\n \"field\": \"templates\",\n \"timestamp\": \"2026-08-09T12:00:00Z\",\n \"payload\": {\n \"account_id\": \"00000000-0000-0000-0000-000000000000\",\n \"template_id\": \"11111111-1111-1111-1111-111111111111\",\n \"template_name\": \"order_update\",\n \"whatsapp_template_id\": \"2222222222222222\",\n \"status\": \"APPROVED\",\n \"language\": \"en_US\",\n \"category\": \"UTILITY\",\n \"channel\": \"whatsapp\",\n \"reason\": null\n }\n}\n```\n\nCommon forwarded values include `PENDING`, `APPROVED`, `REJECTED`, and `CATEGORY_UPDATED`. Meta can also send values such as `PAUSED` or `DISABLED`. Persist the raw string, handle known values, and safely surface unknown ones. See [references/template-rejection-playbook.md](references/template-rejection-playbook.md).\n\n## Boundaries\n\nUse `template-builder-ui` for editor architecture and client-side validation UX. Use `sent-templates` to list, inspect, or delete existing templates through the connected Sent tools. Use `waba-embedded-signup` for WABA connection. Use `rcs-agent-onboarding` for current RCS launch capabilities.\n\nMeta Cloud API payloads may appear in [references/waba-template-examples.md](references/waba-template-examples.md), but every such example must be clearly labelled non-Sent and must never be passed to the Sent linter as a valid request.\n"
}SHA-256: f17ab2e61804cb4d356dc93fbb5d49e59e1bac63b3eafc740461e44d67acf6eb