Worked channels samples
The generated blocks below document every parameter and response shape; this overlay walks the chain an Apple Messages for Business integration actually ships: list connected agents → register one → transition its status → remove it, plus the WhatsApp Flow inventory your inbox composer polls. Every authenticated call on this page carriesX-API-Key; the two webhook
routes (POST .../channels/amb/webhook, POST .../channels/whatsapp/flows/endpoint)
are provider-facing and authenticate by signature, not by key — you never
call them from your own backend.
Every JSON response follows the { data, meta } envelope — data carries
the payload, meta carries the request_id and timestamp. Quote
meta.request_id when you report a bad payload.
The Node SDK does not wrap the channels namespace yet, so the typed tabs
below use the SDK’s orbit.request escape hatch (the same convention the
API recipes guide uses for uncovered resources) —
you get the SDK’s auth, retries, and envelope unwrapping against the raw
REST path.
1. List connected AMB agents
GET /api/v1/channels/amb/agents returns the tenant’s Apple Messages for
Business agents, newest first (capped at 200). Poll it on your
channel-settings screen to render connection state: the status field is
the approval lifecycle (pending → approved → suspended), and
has_secret: true confirms the agent carries a credential. The secret
itself is encrypted at rest and never serialised — a rotated secret still
reads as has_secret: true with no material exposed.
200
{"data": []} — render the connect prompt rather
than branching on null. A first-booted tenant whose AMB tables have not
finished provisioning also answers [] (a clean 200), so an empty list
never means the endpoint is down.
2. Register an AMB agent
POST /api/v1/channels/amb/agents creates the agent. You need the
business_id Apple Business Register issued and the base64 secret_key
assigned to the agent — the secret is encrypted with the platform envelope
before it persists and is never returned by any read. The idempotent
answer on a repeated submit is driven by the business_id: it is unique
per tenant, so re-POSTing the same one conflicts — see the 409 below.
201
data.id — updates and deletes address the agent by
that id, not by business_id. Registration also mirrors the
business_id → tenant mapping into the webhook registry, so inbound Apple
Messages start routing to your inbox the moment the POST succeeds.
3. Transition status / rotate the secret
PATCH /api/v1/channels/amb/agents/{id} is a partial update — only the
fields you send change. The two calls you make in practice: flip status
when Apple approves (or when you suspend the channel), and send a new
secret_key to rotate credentials (the replacement is encrypted before it
persists).
200
404 —
re-list (section 1) and re-read the id instead of retrying the same one;
the roster is the source of truth after any delete or re-register.
4. Disconnect an agent
DELETE /api/v1/channels/amb/agents/{id} removes the agent and drops its
business_id from the webhook registry, so inbound Apple Messages stop
routing to your inbox immediately. The response is the deleted id plus a
deleted: true marker.
200
5. Inventory WhatsApp Flows
GET /api/v1/channels/whatsapp/flows lists the tenant’s Meta WhatsApp
Flows (up to 100, newest first). Your inbox composer polls this to offer
a local-flow picker while a completion event is in flight: each row
carries the remote Meta flow_id, the lifecycle status
(draft / published / deprecated), and first_screen for the launch
surface. Flows POST /api/v1/channels/whatsapp/flows/endpoint receives
are landings of these same flows — an unknown flow_id in a completion
event means the flow was deprecated upstream; re-list here before
surfacing an error.
200
flow_id: null row is a draft that has not been published to Meta yet —
filter it out of any picker that launches live flows.
Errors worth branching on
The matrix below is scoped to what a channel-config client actually hits; the platform-wide retry-vs-terminal decision table lives in the error handling guide.409 — the channel is already connected
A second POST of abusiness_id your tenant already registered conflicts —
business_id is unique per tenant, and the create is not upsert-shaped.
The idempotent connect playbook is: POST once, and on 409 PATCH the
existing agent (rotate the secret, restate capabilities) instead of
re-POSTing.
409
403 — a read-scoped key tried to write
Create, update, and disconnect need a write-capable key (dashboard role owner/admin/developer). A key scoped to read-only gets a 403 — fix the key’s scope set on the developer page; retrying with the same key never heals it.403
422 — the provider fields did not validate
Body schema violations returnVALIDATION_ERROR with error.details
naming the field — a business_id Apple rejects, a secret_key shorter
than 16 or longer than 2048 base64 chars, a non-enum status, or an agent
id path segment that is not a UUID. Branch on error.details and resend
with the corrected field; a blind retry repeats the same 422.
422