agents/openai.yaml
interface: display_name: "Sent WABA Signup" short_description: "Plan WhatsApp Business onboarding" default_prompt: "Use $waba-embedded-signup to review my WABA onboarding flow and readiness."
sentdm/sent-plugin · GitHub
Guides WhatsApp Business Account onboarding through Sent, separating dashboard Embedded Signup, organization WABA inheritance, and direct child-profile credentials. Use for WABA connection, Meta signup, profile creation, access-token handling, phone number mapping, completion callbacks, or WhatsApp onboarding failures.
프로젝트 폴더에서 아래 명령어를 실행하고, 설치할 에이전트를 선택하세요.
npx skills add sentdm/sent-plugin --skill waba-embedded-signup설치 명령을 직접 실행해야 적용됩니다. 지원 에이전트와 필요한 권한·라이선스는 제작자의 안내를 확인하세요.
agents/openai.yamlinterface: display_name: "Sent WABA Signup" short_description: "Plan WhatsApp Business onboarding" default_prompt: "Use $waba-embedded-signup to review my WABA onboarding flow and readiness."
references/waba-embedded-signup-spec.md# WABA integration specification
## Capability boundaries
- Organization Embedded Signup is launched in the Sent dashboard.
- No public Sent endpoint starts that hosted signup.
- `POST /v3/profiles` can inherit the organization's WABA or accept a dedicated WABA.
- Direct profile credentials are not an Embedded Signup endpoint.
## Dedicated credentials
```text
whatsapp_business_account
waba_id required string
access_token required secret string
phone_number_id optional string
```
Omitting `phone_number_id` invokes the current provisioning behavior documented by the profile contract. The token is write-only operational input and must never appear in API output, logs, fixtures, traces, analytics, or support text.
## Inheritance
Omit the entire `whatsapp_business_account` object to inherit. This succeeds only if the organization has completed Embedded Signup; otherwise expect `422`.
## Auth matrix
| Key | `x-profile-id` | Result |
| --- | --- | --- |
| Profile key | Omitted | Profile-scoped operation. |
| Profile key | Present | `403`. |
| Organization key | Valid child UUID | Child-scoped operation; organization rate-limit pool. |
| Organization key | Unowned UUID | `404`. |
`x-sender-id` belongs to legacy v1/v2 guidance.
## Profile completion
The request requires `webHookUrl`. A `202` only confirms processing began. A `200` can report an already-complete profile. Completion callback event values include `COMPLETED`, `SUBMITTED`, and `failed`; do not treat that vocabulary as the REST profile enum.
```json
{
"event": "SUBMITTED",
"profile_id": "00000000-0000-0000-0000-000000000000",
"timestamp": "2026-08-09T12:00:00Z"
}
```
Completion callbacks use `event`, not `sub_type`. Meta Embedded Signup browser messages also use an `event` field but have a different producer and payload. Keep the two handlers distinct.
references/waba-onboarding-runbook.md# WABA onboarding runbook
## 1. Choose the path
- Organization needs its first WABA: use dashboard Embedded Signup.
- Child shares the organization WABA: create a profile and omit credentials.
- Child owns a dedicated WABA: create a profile with `waba_id` and `access_token`; optionally include `phone_number_id`.
Record why the choice matches brand, tenant, compliance, and blast-radius requirements.
## 2. Prepare access
Use a profile key alone or an organization key with `x-profile-id` for existing-child operations. Do not use `x-profile-id` with a profile key. Remove legacy `x-sender-id` examples.
## 3. Handle secrets
- Receive tokens only through a protected server-side path.
- Store them in a secret manager if your system must retain them.
- Redact request bodies before logging.
- Never send tokens back to the frontend.
- Do not include tokens in screenshots, fixtures, errors, or support tickets.
## 4. Create or update the profile
Use `sandbox: true` first. On a dedicated WABA path, confirm that the returned non-secret WABA and number identifiers match intent. On inheritance, treat `422` as evidence the organization WABA prerequisite is absent.
## 5. Complete
Send `webHookUrl` to `/v3/profiles/{profileId}/complete`. Persist the request ID and profile ID. A `202` is not final approval.
The callback handler:
1. verifies the callback;
2. reads top-level `event`;
3. deduplicates by profile/event and delivery identity when available;
4. preserves unknown event strings;
5. records `COMPLETED`, `SUBMITTED`, or `failed` without coercing REST status.
## 6. Smoke test
- Create a synthetic draft template with the Sent `definition` request shape.
- Validate with `sandbox: true`.
- Submit only after explicit review.
- Send to a controlled recipient.
- Persist the returned `message_id` with tenant/profile attribution.
- Verify the normal Sent message webhook separately from the completion callback.
## 7. Rollback
If the WABA or number is wrong, stop new sends, revoke exposed credentials, correct profile mapping, and retain audit evidence. Avoid deleting a profile until number ownership and message retention are resolved.
references/whatsapp-sender-profile-mapping.md# WhatsApp Sender Profile mapping ## Recommended records ```text tenant_id sent_profile_id waba_mode # organization_inherited | dedicated waba_id whatsapp_phone_number_id whatsapp_phone_number profile_key_secret_ref status_raw status_surface ``` Do not store `access_token` in this record. Use a secret-manager reference when retention is necessary. ## Mapping invariants - A dedicated WABA profile has a recorded `waba_id` matching the intended tenant. - An inherited profile explicitly records that it shares the organization WABA. - A WhatsApp number maps to one current tenant/profile route unless the product has a documented coexistence model. - `message_id` is persisted with tenant and profile before webhook events arrive. - Unknown REST or completion callback statuses are stored verbatim with their surface. ## Auth ownership Profile keys minimize tenant credential blast radius. Organization keys with `x-profile-id` centralize control but share the organization rate-limit pool and expand credential impact. Never expose the organization key to tenant code. ## Event surfaces | Surface | Discriminator | | --- | --- | | Meta Embedded Signup browser message | `event` plus Meta session/data fields | | Sent profile completion callback | top-level `event` | | Sent message webhook | `field: "message"` plus `sub_type` | | Sent template webhook | `field: "templates"`, no `sub_type` | Do not copy envelopes between these integrations. They have different producers, authenticity checks, and retry behavior.
SKILL.md---
name: waba-embedded-signup
description: Guides WhatsApp Business Account onboarding through Sent, separating dashboard Embedded Signup, organization WABA inheritance, and direct child-profile credentials. Use for WABA connection, Meta signup, profile creation, access-token handling, phone number mapping, completion callbacks, or WhatsApp onboarding failures.
---
# WABA Onboarding and Embedded Signup
Keep three integration paths distinct. Calling all of them “Embedded Signup” creates wrong API designs and unsafe credential handling.
## The three paths
| Path | Where it starts | Profile behavior |
| --- | --- | --- |
| Organization Embedded Signup | Sent dashboard | Connects the organization's WABA through the hosted Meta flow. There is no public Sent endpoint that starts this flow. |
| Organization WABA inheritance | `POST /v3/profiles` | Omit `whatsapp_business_account`; the child inherits the organization's connected WABA. |
| Dedicated child-profile WABA | `POST /v3/profiles` | Supply `whatsapp_business_account.waba_id` and `.access_token`; `phone_number_id` is optional. |
If credentials are omitted and the organization has no connected WABA, profile creation returns `422`. Direct WABA credentials are a profile-creation feature, not a public “Embedded Signup endpoint.”
## Authentication
Use either:
- a profile-specific key in `x-api-key`; or
- an organization key in `x-api-key` plus `x-profile-id` when operating for an existing child profile.
Only organization keys may use `x-profile-id`; profile keys receive `403`. `x-sender-id` is legacy v1/v2 terminology.
## Path A: organization Embedded Signup
1. An authorized organization administrator opens the Sent dashboard WhatsApp connection flow.
2. The hosted Meta Embedded Signup UI collects the Meta authorization and WABA/number choices.
3. Confirm the organization shows a connected WABA before creating inheriting children.
4. Record non-secret identifiers and audit who completed the action.
Do not invent a `POST /embedded-signup` or token-exchange endpoint in Sent's public API. If building your own Meta Tech Provider integration outside the Sent dashboard, follow Meta's current documentation and keep that system separate from the Sent API contract.
Meta's browser `postMessage` events use an `event` field and nested data/session information. Do not rewrite them as Sent webhook `sub_type` envelopes.
## Path B: inherit the organization WABA
Omit `whatsapp_business_account`:
```json
{
"name": "Tenant Support",
"description": "Synthetic child profile",
"short_name": "SUPPORT",
"inherit_templates": true,
"billing_model": "organization",
"sandbox": true
}
```
Use this only after the organization WABA is connected. Inheritance means the tenant shares that WABA boundary; confirm this matches the tenant/brand architecture.
## Path C: dedicated WABA credentials
```json
{
"name": "Dedicated Tenant",
"whatsapp_business_account": {
"waba_id": "123456789012345",
"phone_number_id": "987654321098765",
"access_token": "<injected secret>"
},
"sandbox": true
}
```
`waba_id` and `access_token` are required. `phone_number_id` is optional: when omitted, the current contract describes provisioning and registration during onboarding.
The token needs the applicable WhatsApp Business messaging and management permissions. Inject it from a secret manager. Never log it, echo it, write it to fixtures, return it to the browser, include it in support output, or retain it in general profile storage. Sent does not return it in API responses.
## Complete the profile
Call `POST /v3/profiles/{profileId}/complete` with the required `webHookUrl`:
```json
{
"webHookUrl": "https://example.com/webhooks/profile-complete",
"sandbox": true
}
```
- `202` means background processing started; there is no final status in that response.
- `200` can mean the profile was already complete and currently demonstrates lowercase `completed`.
- The completion callback can report `COMPLETED`, `SUBMITTED`, or `failed`.
Treat the completion callback as its own integration surface. Its envelope uses `event`, not `sub_type`:
```json
{
"event": "COMPLETED",
"profile_id": "00000000-0000-0000-0000-000000000000",
"timestamp": "2026-08-09T12:00:00Z"
}
```
Preserve unknown event strings. Verify authenticity using the mechanism Sent documents for the callback endpoint and make processing idempotent.
## Verify operational readiness
- Profile WABA ID matches the intended business.
- Selected number is mapped to the intended profile.
- Template sharing/inheritance is intentional.
- A test template can be created with `sandbox: true`.
- The completion callback is reachable and idempotent.
- Returned message IDs are stored against the tenant/profile before webhook processing.
- Tokens and payment values are absent from logs.
For ordinary message and template webhooks, follow Sent's current events reference; those are separate from Meta browser events and profile-completion callbacks.
## Failure routing
| Failure | Next action |
| --- | --- |
| `422` when credentials are omitted | Connect the organization WABA or provide dedicated credentials. |
| `403` with profile key and `x-profile-id` | Remove `x-profile-id` or use an authorized organization key. |
| Wrong WABA/number | Stop before completion and correct the profile mapping. |
| Expired/under-scoped token | Replace it securely; never print it while diagnosing. |
| Completion remains submitted | Inspect prerequisite and callback evidence; do not assume final failure from the `202`. |
Use [references/waba-embedded-signup-spec.md](references/waba-embedded-signup-spec.md), [references/waba-onboarding-runbook.md](references/waba-onboarding-runbook.md), and [references/whatsapp-sender-profile-mapping.md](references/whatsapp-sender-profile-mapping.md). Use `sender-profile-architect` for tenant boundaries and `waba-template-author` for the first template.