{
    "openapi": "3.1.0",
    "info": {
        "title": "Momo Business Customer API",
        "version": "3.1.0",
        "description": "Customer integration reference for REST messaging, contacts, catalogues, orders, payments, automations, data tables, agent tasks and MCP transport. Use the developer handbook at `/api-docs` for complete workflows and operational guidance.\n\n## Authentication\n\nCreate an account REST key at `/app/api-credentials` and send `Authorization: Bearer <key>`. `/api/v3` and `/api/engine` use REST keys; MCP requires its own connection credential or OAuth token. Keys are scoped to an account. Data, group, payment and automation endpoints additionally enforce the issuer permissions described on each operation.\n\n## Response families\n\nMost v3 successes are `{status: \"success\", data: ...}` and errors are `{status: \"error\", message, errors?}`. Data endpoints intentionally return native `{tables}`, `{records,...}` or `{record}` objects, and expected data-domain failures carry `{error: {code, message, retryable, ...}, message, code, errors?}`. Payment lists return `{data: [...], meta: {...}}`; automation reads return `{events,...}`, `{subscriptions}` or `{schedules}`. Agent endpoints return execution-specific objects; MCP uses JSON-RPC. Consult each response schema rather than assuming a universal envelope.\n\n## Limits and delivery\n\nThe v3 route limit is 120 requests/minute per Bearer token. Throttled requests provide Retry-After; authentication failures can occur before rate headers are attached. Provider throughput limits are separate. Agent and MCP routes have their own contracts.\n\nSMS and WhatsApp sends normally attempt provider delivery inside the request. HTTP 201 means message records were created, including records whose status is failed. Future schedules, admission deferral or fallback can return queued. Save every message UID and inspect its status. Ordinary message and campaign POSTs do not implement request-key idempotency; agent task submission does.\n\n## Identifiers\n\nMessage, campaign and contact lookups accept their public UID or numeric ID. Catalogue, product, order and WhatsApp group resource paths use numeric local IDs. Data tables, groups and records use UUIDs. Provider message IDs, provider catalogue IDs and retailer IDs are distinct from local identifiers."
    },
    "servers": [
        {
            "url": "https://business.momo.tz",
            "description": "Production"
        }
    ],
    "security": [
        {
            "BearerToken": []
        }
    ],
    "tags": [
        {
            "name": "Authentication",
            "description": "Send `Authorization: Bearer <REST key>`. Create and revoke keys at `/app/api-credentials`; the plaintext is returned once. Tenant identity comes from the key, never a request tenant_id.\n\nData and WhatsApp group endpoints check the key issuer's current permissions; a missing/deactivated issuer is refused there. Legacy message, campaign, contact, catalogue and profile controllers use the tenant credential without this per-action permission map. Treat REST keys as powerful credentials.\n\nMissing, invalid, revoked, expired or wrong-kind REST credentials return 401. A suspended/inactive account returns 403. REST API keys and MCP credentials cannot be interchanged."
        },
        {
            "name": "SMS",
            "description": "Send single or bulk SMS, create SMS campaigns against contact groups, and read back message and campaign state. `GET /api/v3/sms/senders` lists the identities a message can be sent as."
        },
        {
            "name": "WhatsApp",
            "description": "Send WhatsApp text, media, template, interactive and reaction messages, and read back message state. Free-text sends are only delivered inside the 24-hour customer service window; outside it, use an approved template. `GET /api/v3/whatsapp/accounts` lists the business accounts and the numbers a message can be sent from."
        },
        {
            "name": "WhatsApp groups",
            "description": "Groups of up to 8 people created from a business number. Invite-only: you send the link, they choose to join. Needs an Official Business Account. Group events also arrive as webhooks (group.created, group.participant_joined, \u2026).\n\nA key here inherits the permissions of the user who created it: `communications.groups.view` to read, `communications.groups.manage` to change a group, and both that and `communications.send` to post into one. A key with no creator on record is refused."
        },
        {
            "name": "WhatsApp templates",
            "description": "Message templates on a WhatsApp Business Account: the pre-approved copy WhatsApp requires before a business may start a conversation. Create one here (in Meta's own `components` shape or with flat fields), it is submitted to Meta for review in the same request, and the answer comes back three ways \u2014 `GET` the template, `POST \u2026/refresh` to ask Meta right now, or subscribe to the `template.status_changed` webhook. `POST \u2026/sync` imports every approved template the account already has. Reads need the issuer's `communications.templates.view` permission, writes `communications.templates.manage`. A template is one name in one language on one business account; another language is another template, and another account is a deployment (`POST \u2026/deployments`)."
        },
        {
            "name": "Contacts",
            "description": "The account's contact directory: groups, the people in them, and the custom fields a group declares. `GET /api/v3/contact-groups` is where the `{group_id}` every contact path takes comes from. Contacts are reachable two ways \u2014 the five original `/contacts/{group_id}/\u2026` paths, and ordinary REST under `/contact-groups/{group}/contacts` \u2014 and both do the same thing to the same records. A group or a contact may be named by its numeric id or by its UID. Reading needs the issuer's `contacts.view`; writing needs `contacts.create` / `contacts.edit`; deleting needs `contacts.delete`; the bulk import needs `contacts.import`. A key created before 7 September 2026 has no recorded issuer; those keep the five original `/contacts/{group_id}/\u2026` paths they were issued under and are refused on everything added since. Rotate one from Settings \u2192 API credentials to bring it under the permission model."
        },
        {
            "name": "Catalogue",
            "description": "Read existing shops, manage products, send WhatsApp product messages and inspect customer orders. Resource paths use local numeric IDs; commerce sends use provider catalogue IDs and product retailer IDs. Product price/sale_price and order total_amount use integer hundredths; these differ from data-table currency fields.\n\nProduct send endpoints call the provider directly and return its message_id, not a local Message UID. Product synchronization is not an atomic transaction across the local store and provider. Order status updates accept the documented enum and record history without enforcing a linear transition graph or performing a payment refund."
        },
        {
            "name": "Data tables",
            "description": "Read schemas and operate on account-defined business records. Tables, groups and records use UUIDs. Read permissions are data.view; record writes need data.records.edit plus table access. Schema responses describe types, masks, grants, unique sets, quotas and state rules.\n\nRecord pages use next_cursor/has_more, with a default limit of 50 and maximum 200. Record PATCH merges submitted keys, with null clearing an optional value. Source stays fixed at creation. State changes are enforced; history is an audit trail, not a record-version rollback API.\n\nData responses have native envelopes. Expected refusals contain a structured error object: validation_error 422, conflict 409, quota_exceeded 402, not_found 404, permission_denied 403, not_supported 501, rate_limited 429, provider_failure 502 or temporary_failure 503. Framework/authentication failures can use the standard v3 error envelope."
        },
        {
            "name": "Payments",
            "description": "Money this business collects from ITS customers, and money it sends out. Not the same thing as the business's own Momo bill, which lives under Profile & Balance. Reads only: asking a customer for money or refunding one goes through a surface attributable to a person, never a long-lived API key."
        },
        {
            "name": "Profile & Balance",
            "description": "The tenant behind the token and its wallet balance."
        },
        {
            "name": "Webhooks",
            "description": "Two customer callback protocols are documented here. Communication callbacks use X-Signature and a flat event payload, with one delivery attempt. Automation subscription callbacks use X-Momo-Signature over a signed timestamp and raw body, a business-event envelope and bounded retries. These are requests sent to your receiver, not callable paths on this API. Read the corresponding webhook entry before implementing signature verification."
        },
        {
            "name": "Automations",
            "description": "What this business has arranged to happen without a person: the log of business events, the subscriptions that react to them, and the schedules that run on a rhythm. Reads only \u2014 creating an automation is a decision made on a screen or through an MCP connection with an explicit elevation, never with a long-lived key."
        },
        {
            "name": "Operations",
            "description": "The named things this business can do \u2014 create a booking, register a customer, process a refund \u2014 each written down once by the business and callable from a chat flow, a phone menu, an assistant or your own code. An operation validates its inputs before anything happens, runs its steps inside a compensating transaction, and records every run with its inputs, its outputs and per-step timing.\n\nThis is the one write these platform phases added to v3, and deliberately: an operation can only do what somebody in the workspace already defined for it, so a key calling `create_booking` cannot make it do anything but create a booking. The definitions themselves are written on the Operations page or through an MCP connection \u2014 never with a long-lived key."
        },
        {
            "name": "Agent tasks",
            "description": "Submit prompts to configured account agents and poll run progress. Uses a REST API key at /api/engine, with native run envelopes and optional Idempotency-Key protection.\n\nThe account engine, agent profile and API availability must permit execution. Tasks may incur usage. Queued acceptance is 202; sync HTTP 200 still requires checking the run status. This route group is separate from the v3 shared throttle and error renderer."
        },
        {
            "name": "Flows",
            "description": "Message flows \u2014 the WhatsApp conversations a workspace scripts in the builder \u2014 and their sessions. Read flows, publish a draft, export a bundle, list and end sessions, start one for a customer. The graph itself is edited in the builder or over MCP, never here. Subscribe a webhook to flow.session.started / flow.session.ended for the CRM side."
        },
        {
            "name": "Posts",
            "description": "Social publishing: drafts, scheduling and publishing to Facebook Pages, Instagram, TikTok, YouTube and LinkedIn \u2014 the same posts the composer makes, over an API key. Reads need posts.view, writes posts.manage, on the person who issued the key; what that person is assigned to bounds what the key sees."
        },
        {
            "name": "MCP",
            "description": "The same account, the same permissions, reached by a language model instead of by your own code.\n\nMCP \u2014 the Model Context Protocol \u2014 is not a REST API, and this document does not pretend that it is. One MCP server is **one HTTP endpoint** speaking JSON-RPC 2.0: the operation is the `method` in the body rather than the URL, the tools are discovered at runtime with `tools/list`, and each tool's arguments are a JSON Schema rather than path, query and body parameters.\n\nWriting 305 tools as 305 near-identical `POST` operations would validate perfectly and teach nobody anything. So what is documented under this tag is the **transport** \u2014 the 29 servers' endpoints, the envelope, the OAuth handshake and where the tool contract lives. The tool contract itself is `GET /api-docs/mcp.json`, which carries a full JSON Schema per tool and is generated from the same code as this section.\n\n## Which one should I use\n\n**The REST API** when your own code drives the interaction \u2014 a cron job, a webhook handler, your backend. You know before you deploy which call you want to make, so a fixed contract is exactly what you want.\n\n**MCP** when a language model drives it \u2014 Claude, ChatGPT, or an agent you built. It chooses the call at runtime from what `tools/list` told it, which is only possible because the tool list is negotiated rather than compiled in.\n\nThey reach the same data and enforce the same permissions. What differs is who is holding the wheel.\n\n## Where each REST tag lands in MCP\n\n| REST tag | MCP server | Endpoint |\n|---|---|---|\n| Authentication | `account` | `/mcp/v1/account` |\n| SMS | `messaging` | `/mcp/v1/messaging` |\n| WhatsApp | `messaging`, `inbox` | `/mcp/v1/messaging`, `/mcp/v1/inbox` |\n| WhatsApp groups | `groups` | `/mcp/v1/groups` |\n| WhatsApp templates | `messaging` | `/mcp/v1/messaging` |\n| Contacts | `contacts` | `/mcp/v1/contacts` |\n| Catalogue | `shop`, `orders` | `/mcp/v1/shop`, `/mcp/v1/orders` |\n| Profile & Balance | `overview`, `account` | `/mcp/v1/overview`, `/mcp/v1/account` |\n| Webhooks | \u2014 | \u2014 |\n\n**Webhooks have no MCP equivalent, and will not.** MCP is request/response with the model asking; Momo Business calling *you* when something happens stays an HTTP callback.\n\nReachable only over MCP today: `ivr`, `flows`, `data`, `approvals`, `payments`, `automations`, `alerts`, `operations`, `studio`, `numbers`, `agents`, `tickets`, `kb`, `content`, `calls`, `routing`, `meetings`, `comments`, `posts`, `accounts`, `navigate`.\n\n## Authenticating\n\nTwo credentials reach the same endpoints, and both resolve to the account's identity narrowed to what was actually granted.\n\n- **`Authorization: Bearer momo_mcp_\u2026`** \u2014 an MCP connection from Dashboard \u2192 Settings \u2192 API credentials. For Claude Code, Claude Desktop, a self-hosted agent or curl. A v3 API key is refused here: same table, very different blast radius.\n- **OAuth 2.1 with dynamic client registration** \u2014 for claude.ai and ChatGPT, which have nowhere to paste a static token. Discovery, registration, authorization code with PKCE (S256), then the same bearer header.\n\nScopes come in two kinds, and the split *is* the safety model: a **capability** says which part of the business, an **elevation** says how far \u2014 publish, send, spend, delete, and for the data tables write and shape \u2014 and crosses every capability granted.\n\n| Scope | Grants | On the consent screen |\n|---|---|---|\n| `mcp:overview` | Overview and analytics | ticked |\n| `mcp:calls` | Calls | ticked |\n| `mcp:routing` | Call routing | off |\n| `mcp:numbers` | Phone numbers | off |\n| `mcp:meetings` | Meetings | off |\n| `mcp:builders` | Call flows and chat flows | off |\n| `mcp:data` | Data tables | off |\n| `mcp:studio` | Voice and audio | off |\n| `mcp:contacts` | Contacts | ticked |\n| `mcp:agents` | AI agents | off |\n| `mcp:commerce` | Orders and shop | off |\n| `mcp:support` | Support tickets | ticked |\n| `mcp:accounts` | Connected accounts | ticked |\n| `mcp:approvals` | Approvals | off |\n| `mcp:payments` | Payments | off |\n| `mcp:automations` | Automations | off |\n| `mcp:alerts` | Alerts and service levels | off |\n| `mcp:operations` | Operations | off |\n| `mcp:navigate` | Finding things | ticked |\n| `mcp:messaging` | Messaging | off |\n| `mcp:inbox` | Inbox | off |\n| `mcp:comments` | Comments | off |\n| `mcp:posts` | Posts | off |\n| `mcp:groups` | WhatsApp groups | off |\n| `mcp:publish` | Publish things | never ticked |\n| `mcp:send` | Send messages and place calls | never ticked |\n| `mcp:spend` | Start purchases and ask customers to pay | never ticked |\n| `mcp:delete` | Delete things | never ticked |\n| `mcp:write` | Save and change records | never ticked |\n| `mcp:shape` | Change tables and fields | never ticked |\n| `mcp:automate` | Set up things that run without you | never ticked |\n| `mcp:approve` | Answer approvals for you | never ticked |\n\nWhatever is granted is still intersected with what the consenting person can do. Scopes are a request; permissions are the ceiling.",
            "externalDocs": {
                "description": "The tool manifest \u2014 every server, every tool, a JSON Schema each.",
                "url": "https://business.momo.tz/api-docs/mcp.json"
            },
            "x-generated-by": "php artisan mcp:manifest",
            "x-mcp-servers": [
                {
                    "key": "ivr",
                    "name": "IVR",
                    "description": "Build and edit call flows: read the graph, apply node operations, validate, simulate, version and assign to numbers.",
                    "path": "/mcp/v1/ivr",
                    "module": "calls"
                },
                {
                    "key": "flows",
                    "name": "Message flows",
                    "description": "Build and edit WhatsApp conversation flows: nodes, edges, triggers, validation, simulation and analytics.",
                    "path": "/mcp/v1/flows",
                    "module": "flows"
                },
                {
                    "key": "data",
                    "name": "Data tables",
                    "description": "The tables this business defined for itself and their records: read with filters, create/update/upsert rows, shape fields, run and save reports, and group related tables into folders with reports that read across them. Flows and IVRs read the same tables.",
                    "path": "/mcp/v1/data",
                    "module": "data"
                },
                {
                    "key": "approvals",
                    "name": "Approvals",
                    "description": "Decisions a person has been asked for before something happens: read the queue, read one in full with every comment on it, answer one.",
                    "path": "/mcp/v1/approvals",
                    "module": "approvals"
                },
                {
                    "key": "payments",
                    "name": "Payments",
                    "description": "Money this business collects from its customers: what has been asked for and where each one got to, one payment's whole timeline, asking a customer to pay, and refunds. Not the business's own Momo bill.",
                    "path": "/mcp/v1/payments",
                    "module": "payments"
                },
                {
                    "key": "automations",
                    "name": "Automations",
                    "description": "What happens without anybody there: the log of what has actually happened in the business, the subscriptions that react to it, and the schedules that run on a rhythm.",
                    "path": "/mcp/v1/automations",
                    "module": "automations"
                },
                {
                    "key": "alerts",
                    "name": "Alerts & service levels",
                    "description": "The business watching itself: the alert rules it wrote, the service-level promises and the clocks running against them, the risk rules that hold or refuse an action, and one log of everything that fired \u2014 including what reached nobody.",
                    "path": "/mcp/v1/alerts",
                    "module": "alerts"
                },
                {
                    "key": "operations",
                    "name": "Operations",
                    "description": "The named things this business can do \u2014 create a booking, register a customer, process a refund \u2014 each written down once, and the log of every time one ran.",
                    "path": "/mcp/v1/operations",
                    "module": "operations"
                },
                {
                    "key": "studio",
                    "name": "Studio",
                    "description": "Voice and audio: browse the voice library, generate speech, convert audio and publish it for use in an IVR.",
                    "path": "/mcp/v1/studio",
                    "module": null
                },
                {
                    "key": "numbers",
                    "name": "Numbers",
                    "description": "Phone numbers: what you own, what is available, what one costs, and how to pay for it.",
                    "path": "/mcp/v1/numbers",
                    "module": "calls"
                },
                {
                    "key": "groups",
                    "name": "WhatsApp groups",
                    "description": "Groups the business runs from its WhatsApp number: create, invite, post, approve joins, remove members.",
                    "path": "/mcp/v1/groups",
                    "module": "groups"
                },
                {
                    "key": "agents",
                    "name": "Agents",
                    "description": "Your own AI specialists: see the roster and ask one a question.",
                    "path": "/mcp/v1/agents",
                    "module": null
                },
                {
                    "key": "orders",
                    "name": "Orders",
                    "description": "Customer orders across every platform: find, read, move status, request payment.",
                    "path": "/mcp/v1/orders",
                    "module": "catalogue"
                },
                {
                    "key": "shop",
                    "name": "Shop",
                    "description": "Products, brands and categories, plus the order tools.",
                    "path": "/mcp/v1/shop",
                    "module": "catalogue"
                },
                {
                    "key": "tickets",
                    "name": "Tickets",
                    "description": "Support tickets: create, update, assign, reply, labels and notifications.",
                    "path": "/mcp/v1/tickets",
                    "module": null
                },
                {
                    "key": "kb",
                    "name": "Knowledge base",
                    "description": "Your knowledge base: categories, search and full article text.",
                    "path": "/mcp/v1/kb",
                    "module": null
                },
                {
                    "key": "content",
                    "name": "Platform content",
                    "description": "Public help articles, changelog, roadmap and system status.",
                    "path": "/mcp/v1/content",
                    "module": null
                },
                {
                    "key": "calls",
                    "name": "Calls",
                    "description": "Call history, recordings, transcripts, events and Call Studio scripts.",
                    "path": "/mcp/v1/calls",
                    "module": "calls"
                },
                {
                    "key": "routing",
                    "name": "Call routing",
                    "description": "Routing rules, ring groups, working hours and forwarding targets.",
                    "path": "/mcp/v1/routing",
                    "module": "calls"
                },
                {
                    "key": "meetings",
                    "name": "Meetings",
                    "description": "See and schedule meetings, and invite people to them.",
                    "path": "/mcp/v1/meetings",
                    "module": "calls"
                },
                {
                    "key": "messaging",
                    "name": "Messaging",
                    "description": "Templates, sender IDs, campaigns, message history \u2014 and sending SMS and WhatsApp.",
                    "path": "/mcp/v1/messaging",
                    "module": "marketing"
                },
                {
                    "key": "inbox",
                    "name": "Inbox",
                    "description": "Customer conversations across WhatsApp, SMS, social and email \u2014 read, assign, reply, and send new mail.",
                    "path": "/mcp/v1/inbox",
                    "module": "inbox"
                },
                {
                    "key": "comments",
                    "name": "Comments",
                    "description": "Comments on your Facebook, Instagram and TikTok posts.",
                    "path": "/mcp/v1/comments",
                    "module": "comments"
                },
                {
                    "key": "posts",
                    "name": "Posts",
                    "description": "Social posts to Facebook, Instagram, TikTok, YouTube and LinkedIn: what is drafted, scheduled and sent; drafting a new one; scheduling or publishing it.",
                    "path": "/mcp/v1/posts",
                    "module": "posts"
                },
                {
                    "key": "contacts",
                    "name": "Contacts",
                    "description": "The contact book and groups.",
                    "path": "/mcp/v1/contacts",
                    "module": "contacts"
                },
                {
                    "key": "overview",
                    "name": "Overview",
                    "description": "The dashboard, business analytics, call stats and spend \u2014 how the business is doing.",
                    "path": "/mcp/v1/overview",
                    "module": null
                },
                {
                    "key": "accounts",
                    "name": "Connected accounts",
                    "description": "The WhatsApp numbers, social profiles, mailboxes and SMS routes this business has connected, and what each can actually do.",
                    "path": "/mcp/v1/accounts",
                    "module": null
                },
                {
                    "key": "navigate",
                    "name": "Finding things",
                    "description": "Where pages and settings live in the app, and what each form asks for.",
                    "path": "/mcp/v1/navigate",
                    "module": null
                },
                {
                    "key": "account",
                    "name": "Account",
                    "description": "A cross-domain starting point: overview, search, fetch, and the most-used read tools.",
                    "path": "/mcp/v1/account",
                    "module": null
                }
            ],
            "x-rest-tag-map": {
                "Authentication": [
                    "account"
                ],
                "SMS": [
                    "messaging"
                ],
                "WhatsApp": [
                    "messaging",
                    "inbox"
                ],
                "WhatsApp groups": [
                    "groups"
                ],
                "WhatsApp templates": [
                    "messaging"
                ],
                "Contacts": [
                    "contacts"
                ],
                "Catalogue": [
                    "shop",
                    "orders"
                ],
                "Profile & Balance": [
                    "overview",
                    "account"
                ],
                "Webhooks": []
            }
        }
    ],
    "components": {
        "securitySchemes": {
            "BearerToken": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "tenant_api_token",
                "description": "A tenant API token from Dashboard \u2192 Settings \u2192 API Keys. Send it as `Authorization: Bearer <token>` on every request."
            },
            "McpBearerToken": {
                "type": "http",
                "scheme": "bearer",
                "bearerFormat": "momo_mcp",
                "description": "An MCP credential from Dashboard \u2192 Settings \u2192 API credentials \u2192 MCP connections. For Claude Code, Claude Desktop, a self-hosted agent, or curl. A v3 API key is **not** accepted here.",
                "x-generated-by": "php artisan mcp:manifest"
            },
            "McpOAuth": {
                "type": "oauth2",
                "description": "For hosted clients \u2014 claude.ai, ChatGPT \u2014 which have nowhere to paste a static token. Register with RFC 7591 dynamic client registration, then run authorization code + PKCE (S256). The account holder chooses the scopes on our consent screen, and whatever is granted is still intersected with what that person can actually do.",
                "flows": {
                    "authorizationCode": {
                        "authorizationUrl": "https://business.momo.tz/oauth/authorize",
                        "tokenUrl": "https://business.momo.tz/oauth/token",
                        "refreshUrl": "https://business.momo.tz/oauth/token",
                        "scopes": {
                            "mcp:overview": "How the business is doing \u2014 calls, messages, spend, and what needs attention.",
                            "mcp:calls": "Call history, recordings, transcripts and Call Studio scripts.",
                            "mcp:routing": "Routing rules, ring groups, working hours and forwarding targets.",
                            "mcp:numbers": "What you own, what is available, what one costs, and how it is configured.",
                            "mcp:meetings": "See and schedule meetings, and invite people to them.",
                            "mcp:builders": "Build and edit your IVRs and WhatsApp conversation flows \u2014 as drafts.",
                            "mcp:data": "The tables your business defined for itself \u2014 read records, save them, shape fields, run reports \u2014 and the business rules (limits, fees, eligibility, opening hours) your flows enforce. Flows and IVRs read the same tables and the same rules.",
                            "mcp:studio": "Voices, and generating spoken prompts for your call flows.",
                            "mcp:contacts": "Your contact book and groups.",
                            "mcp:agents": "Your AI agents, what they know, how they behave, and what they have done.",
                            "mcp:commerce": "Customer orders, products, brands and categories.",
                            "mcp:support": "Tickets and your knowledge base.",
                            "mcp:accounts": "Which WhatsApp numbers, social profiles and mailboxes are connected, and what each can do.",
                            "mcp:approvals": "Decisions people in your business are waiting on \u2014 what is pending, what was decided, and why. Answering one is separate.",
                            "mcp:payments": "Money your customers pay you: what has been asked for, what arrived, and each payment's history. Asking for money and refunding it need the spending tick as well.",
                            "mcp:automations": "What your business has set up to happen on its own \u2014 what reacts to an event, what runs on a rhythm, and a log of what actually fired. Changing any of it is separate.",
                            "mcp:alerts": "How your business watches itself: what it has asked to be told about, how quickly it promises to do things, what it checks before letting something through, and a log of everything that fired \u2014 including anything that reached nobody. Changing any of it is separate.",
                            "mcp:operations": "The named things your business can do \u2014 create a booking, register a customer, process a refund. Seeing what they are is included; DOING one needs the ticks its own steps call for.",
                            "mcp:navigate": "Where pages and settings live in the app, so it can point you to them.",
                            "mcp:messaging": "Templates, sender IDs, campaigns and your message history. Sending is separate.",
                            "mcp:inbox": "Read your customer conversations across WhatsApp, SMS, social and email.",
                            "mcp:comments": "Read comments on your Facebook, Instagram and TikTok posts.",
                            "mcp:posts": "Read what the business has drafted, scheduled and published on its social accounts. Drafting, scheduling and publishing are separate.",
                            "mcp:groups": "Groups your business runs from its WhatsApp number.",
                            "mcp:publish": "Make a call flow answer real calls, a chat flow reach real customers, or a routing change go live.",
                            "mcp:send": "Send an SMS, WhatsApp or email to a real person, reply to a customer, or ring a phone.",
                            "mcp:spend": "Begin buying a number or topping up, and ask your customers to pay you. You still approve every payment yourself, on your phone, and a refund still waits for somebody in your business to say yes.",
                            "mcp:delete": "Permanently remove flows, audio, contacts and tickets.",
                            "mcp:write": "Create, update and upsert rows in your data tables, and save reports.",
                            "mcp:shape": "Create tables, add, rename, retype or remove fields, put indexes and \"unique together\" rules on them, and arrange tables into groups. This changes what every screen and flow sees.",
                            "mcp:automate": "Create or change an automation: something that reacts to an event on its own, or runs on a rhythm \u2014 including sending your business's data to an address outside it.",
                            "mcp:approve": "Approve or reject a request somebody is waiting on \u2014 releasing a discount, a refund or a payout that was deliberately held for a person to sign off.",
                            "mcp:use": "The base grant every MCP token carries."
                        }
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            }
        },
        "schemas": {
            "LegacyErrorEnvelope": {
                "type": "object",
                "required": [
                    "status",
                    "message"
                ],
                "description": "Error response envelope for validation and server errors.",
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "error"
                        ],
                        "description": "Always \"error\" for failure responses."
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable error message."
                    },
                    "errors": {
                        "type": "object",
                        "description": "Optional field-level validation errors; keys are field names, values are arrays of messages.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                }
            },
            "RateLimitError": {
                "type": "object",
                "required": [
                    "status",
                    "message"
                ],
                "description": "Returned when the 120 requests/minute token limit is exceeded. Retry after the `Retry-After` header.",
                "properties": {
                    "status": {
                        "type": "string",
                        "enum": [
                            "error"
                        ],
                        "description": "Always \"error\"."
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable rate limit message."
                    }
                }
            },
            "Pagination": {
                "type": "object",
                "required": [
                    "current_page",
                    "per_page",
                    "last_page",
                    "total",
                    "has_more_pages"
                ],
                "description": "Cursor-less pagination metadata for list endpoints.",
                "properties": {
                    "current_page": {
                        "type": "integer",
                        "description": "1-based current page index."
                    },
                    "per_page": {
                        "type": "integer",
                        "description": "Number of items per page."
                    },
                    "last_page": {
                        "type": "integer",
                        "description": "1-based index of the last page."
                    },
                    "total": {
                        "type": "integer",
                        "description": "Total number of items across all pages."
                    },
                    "has_more_pages": {
                        "type": "boolean",
                        "description": "True if more pages exist after the current page."
                    }
                }
            },
            "Message": {
                "type": "object",
                "required": [
                    "id",
                    "uid",
                    "direction",
                    "channel_type",
                    "recipient",
                    "body",
                    "status"
                ],
                "description": "SMS or WhatsApp message record with delivery and metadata fields.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal numeric id."
                    },
                    "uid": {
                        "type": "string",
                        "description": "Public unique identifier (e.g. msg_01JXYZSMS01)."
                    },
                    "direction": {
                        "type": "string",
                        "enum": [
                            "inbound",
                            "outbound"
                        ],
                        "description": "Whether you sent the message (`outbound`) or received it (`inbound`)."
                    },
                    "channel_type": {
                        "type": "string",
                        "enum": [
                            "sms",
                            "whatsapp"
                        ],
                        "description": "Channel: sms or whatsapp."
                    },
                    "tenant_channel_id": {
                        "type": "integer",
                        "description": "The account channel selected automatically by the outbound routing policy."
                    },
                    "channel_code": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Resolved channel code returned for observability; it is not caller-selectable."
                    },
                    "sender": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Sender identity; inbound messages can contain the customer phone or provider identity."
                    },
                    "recipient": {
                        "type": "string",
                        "description": "Recipient phone number (E.164 or national)."
                    },
                    "body": {
                        "type": "string",
                        "description": "Message text content."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "queued",
                            "processing",
                            "sent",
                            "checking_delivery",
                            "delivered",
                            "read",
                            "failed",
                            "received"
                        ],
                        "description": "Delivery status. Outbound messages walk queued \u2192 processing \u2192 sent \u2192 delivered \u2192 read, or stop at failed with `error_message` set; `received` is what inbound messages carry."
                    },
                    "media_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The attached file, when the message carries one."
                    },
                    "media_type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The kind of attached media (image, video, audio, document, sticker)."
                    },
                    "gateway_message_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Provider message ID, used for replies/reactions. Customer message webhooks identify local records with numeric message_id instead."
                    },
                    "error_message": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why the send failed, straight from the gateway. Null unless `status` is `failed`."
                    },
                    "metadata": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": true,
                        "description": "Anything extra recorded with the message \u2014 the interactive or reaction payload, the id it replies to, the source that created it."
                    },
                    "template_params": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": true,
                        "description": "The template name, language and variables used, when the message was sent from a template."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of when the message record was created."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of the last change to the record."
                    },
                    "sent_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the gateway accepted the message. Null until then."
                    },
                    "delivered_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the gateway confirmed delivery to the recipient's device."
                    },
                    "read_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the recipient opened it. WhatsApp only, and only with read receipts on."
                    }
                }
            },
            "Campaign": {
                "type": "object",
                "required": [
                    "id",
                    "uid",
                    "name",
                    "status",
                    "channel_type",
                    "message"
                ],
                "description": "SMS campaign with recipient counts and status.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal numeric id."
                    },
                    "uid": {
                        "type": "string",
                        "description": "Public unique identifier."
                    },
                    "name": {
                        "type": "string",
                        "description": "Campaign name."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "draft",
                            "scheduled",
                            "running",
                            "paused",
                            "completed",
                            "cancelled"
                        ],
                        "description": "Campaign status. A campaign created without `schedule_time` starts as `draft` and begins immediately; one with a schedule waits in `scheduled`."
                    },
                    "channel_type": {
                        "type": "string",
                        "enum": [
                            "sms"
                        ],
                        "description": "Channel type; currently only sms."
                    },
                    "tenant_channel_id": {
                        "type": "integer",
                        "description": "The account channel selected automatically when the campaign was created."
                    },
                    "channel_code": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Resolved channel code returned for observability; it is not caller-selectable."
                    },
                    "message": {
                        "type": "string",
                        "description": "Campaign message text."
                    },
                    "sender": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The sender identity the campaign sends from."
                    },
                    "scheduled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the campaign is due to start. Null for one that started immediately."
                    },
                    "total_recipients": {
                        "type": "integer",
                        "description": "How many contacts the campaign will send to."
                    },
                    "sent_count": {
                        "type": "integer",
                        "description": "How many have been sent so far."
                    },
                    "failed_count": {
                        "type": "integer",
                        "description": "How many the gateway refused."
                    },
                    "contact_group": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "properties": {
                            "id": {
                                "type": "integer",
                                "description": "Numeric group id."
                            },
                            "uid": {
                                "type": "string",
                                "description": "Group UUID \u2014 the form you can also pass as `contact_list_id`."
                            },
                            "name": {
                                "type": "string",
                                "description": "Group name as it appears in the dashboard."
                            }
                        },
                        "additionalProperties": false,
                        "description": "The contact group this campaign sends to."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of when the campaign was created."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of the last change to it."
                    }
                }
            },
            "Contact": {
                "type": "object",
                "required": [
                    "id",
                    "uid",
                    "group_id",
                    "group_uid",
                    "name",
                    "country_code",
                    "phone_number",
                    "full_phone_number",
                    "is_subscribed"
                ],
                "description": "Contact record within a group, with phone and optional custom fields.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Internal numeric id."
                    },
                    "uid": {
                        "type": "string",
                        "description": "Public unique identifier."
                    },
                    "group_id": {
                        "type": "integer",
                        "description": "Contact group internal id."
                    },
                    "group_uid": {
                        "type": "string",
                        "description": "Contact group public uid."
                    },
                    "name": {
                        "type": "string",
                        "description": "Contact display name."
                    },
                    "country_code": {
                        "type": "string",
                        "description": "Country code (e.g. 255)."
                    },
                    "phone_number": {
                        "type": "string",
                        "description": "National number without country code."
                    },
                    "full_phone_number": {
                        "type": "string",
                        "description": "E.164 or full number for sending."
                    },
                    "is_subscribed": {
                        "type": "boolean",
                        "description": "Stored subscription flag; not automatically applied by the current SMS campaign dispatch loop."
                    },
                    "custom_field_values": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Every non-reserved field you sent when creating or updating the contact, echoed back. Always an object \u2014 `{}` when there are none."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of when the contact was created."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 8601 timestamp of the last change to it."
                    }
                }
            },
            "Catalogue": {
                "type": "object",
                "description": "A shop: a set of products that can be shown to customers on WhatsApp.",
                "required": [
                    "id",
                    "name"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Catalogue id. Use it in every /catalogues/{catalogue} path."
                    },
                    "name": {
                        "type": "string",
                        "description": "Shop name as customers see it."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Optional shop description."
                    },
                    "vertical": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta commerce vertical, e.g. \"commerce\"."
                    },
                    "default_currency": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "ISO 4217 currency new products default to."
                    },
                    "sku_prefix": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The prefix on codes this shop issues itself, such as `AMY` in `AMY-00042`. Fixed once the shop exists."
                    },
                    "stock_policy": {
                        "type": "string",
                        "enum": [
                            "external",
                            "momo"
                        ],
                        "description": "`external`: your system owns the stock count, we mirror it and tell you what sold. `momo`: we keep the count, and orders reserve and commit against it. Shops created through this API default to `external`."
                    },
                    "source_of_truth": {
                        "type": "string",
                        "enum": [
                            "api",
                            "momo",
                            "platform"
                        ],
                        "description": "Who wins on product fields when a selling platform has drifted from us."
                    },
                    "allow_backorder": {
                        "type": "boolean",
                        "description": "Sell past zero. When false, a count of zero sets availability to `out of stock`."
                    },
                    "reservation_ttl_hours": {
                        "type": "integer",
                        "description": "How long a pending order holds stock before it goes back on the shelf."
                    },
                    "low_stock_threshold": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Raise `stock.low` at or below this count. Null means never."
                    },
                    "meta_catalogue_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta catalogue id when the shop is connected; null keeps every product local."
                    },
                    "is_connected_to_waba": {
                        "type": "boolean",
                        "description": "True once the shop is bound to a WhatsApp Business Account."
                    },
                    "is_catalogue_visible": {
                        "type": "boolean",
                        "description": "Whether customers can browse the catalogue in the chat."
                    },
                    "is_cart_enabled": {
                        "type": "boolean",
                        "description": "Whether customers can build a cart and submit an order."
                    },
                    "channels": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/CatalogueChannel"
                        },
                        "description": "Where this shop is published. Empty is normal for a shop that sells only through the assistant or the phone menus."
                    },
                    "products_count": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Number of products in the shop."
                    },
                    "orders_count": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Number of orders received by the shop."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the shop last synced to Meta."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 creation timestamp."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 update timestamp."
                    }
                }
            },
            "Product": {
                "type": "object",
                "description": "One product inside a catalogue. Prices are integers in the minor unit of `currency` (2500000 = TZS 25,000.00 for a 2-decimal currency).",
                "required": [
                    "id",
                    "retailer_id",
                    "name",
                    "price",
                    "currency"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Product id."
                    },
                    "catalogue_id": {
                        "type": "integer",
                        "description": "Catalogue this product belongs to."
                    },
                    "sku": {
                        "type": "string",
                        "description": "Your product code, and the identity this API addresses a product by. The shop issues one (`AMY-00042`) when you send none, and it is frozen once the product is live on any platform."
                    },
                    "retailer_id": {
                        "type": "string",
                        "description": "The older name for `sku`, kept in step with it. Prefer `sku` in new code."
                    },
                    "meta_product_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta product id once mirrored; null for a local-only product."
                    },
                    "name": {
                        "type": "string",
                        "description": "Product name (max 100 characters)."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Long description (max 5000 characters)."
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Link to the product page on your own site."
                    },
                    "price": {
                        "type": "integer",
                        "description": "Price in the minor unit of `currency`."
                    },
                    "currency": {
                        "type": "string",
                        "description": "ISO 4217 currency code."
                    },
                    "sale_price": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Optional sale price in the minor unit."
                    },
                    "image_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Publicly reachable product image. Meta fetches it directly."
                    },
                    "availability": {
                        "type": "string",
                        "enum": [
                            "in stock",
                            "out of stock",
                            "preorder",
                            "available for order",
                            "discontinued"
                        ],
                        "description": "Stock state."
                    },
                    "condition": {
                        "type": "string",
                        "enum": [
                            "new",
                            "refurbished",
                            "used"
                        ],
                        "description": "Product condition."
                    },
                    "brand": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Brand name."
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Category label."
                    },
                    "product_type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Your own product taxonomy string."
                    },
                    "inventory": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Stock count."
                    },
                    "visibility": {
                        "type": "string",
                        "enum": [
                            "staging",
                            "published"
                        ],
                        "description": "Whether customers can see it."
                    },
                    "review_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta review outcome: pending, approved or rejected."
                    },
                    "sync_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "pending",
                            "syncing",
                            "synced",
                            "failed",
                            "blocked",
                            "drifted",
                            null
                        ],
                        "description": "A roll-up of `listings`. A product on a shop with no platforms is `synced`, because there is nothing to sync."
                    },
                    "listings": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/ProductListing"
                        },
                        "description": "One row per platform this shop sells on."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the product last synced to Meta."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 creation timestamp."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 update timestamp."
                    }
                }
            },
            "OrderItem": {
                "type": "object",
                "description": "One line of a customer order, exactly as WhatsApp reported it.",
                "properties": {
                    "product_retailer_id": {
                        "type": "string",
                        "description": "The SKU the customer added to the cart."
                    },
                    "quantity": {
                        "type": "integer",
                        "description": "How many."
                    },
                    "item_price": {
                        "type": "integer",
                        "description": "Unit price in the minor unit of `currency`."
                    },
                    "currency": {
                        "type": "string",
                        "description": "ISO 4217 currency code."
                    },
                    "unit_price_minor": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Unit price in the minor unit. Prefer this over `item_price`, which is Meta's own field and is in MAJOR units."
                    },
                    "line_total_minor": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Unit price times quantity, in the minor unit."
                    },
                    "reserved": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "How many units of this line are actually being held for the order."
                    },
                    "stock_short": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "True when we could not hold the whole quantity. The order was still recorded."
                    },
                    "unresolved": {
                        "type": [
                            "boolean",
                            "null"
                        ],
                        "description": "True when this product code is not in the catalogue. The code is kept verbatim so a person can work out what the customer meant."
                    }
                }
            },
            "Order": {
                "type": "object",
                "description": "An order a customer submitted from a WhatsApp cart.",
                "required": [
                    "id",
                    "customer_wa_id",
                    "status"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Order id."
                    },
                    "catalogue_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Catalogue the cart was built from."
                    },
                    "catalogue": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Compact catalogue reference.",
                        "properties": {
                            "id": {
                                "type": "integer",
                                "description": "Catalogue id."
                            },
                            "name": {
                                "type": "string",
                                "description": "Catalogue name."
                            }
                        }
                    },
                    "platform": {
                        "type": "string",
                        "description": "Where the order came from: `whatsapp`, `storefront`, `instagram`, `ivr`, `manual` and so on."
                    },
                    "customer_handle": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Whatever identifies the customer on their own platform \u2014 a WhatsApp id, a handle, an email, a typed phone number."
                    },
                    "customer_wa_id": {
                        "type": "string",
                        "description": "The older name for `customer_handle`. It has not held only WhatsApp ids since orders became platform-neutral; prefer `customer_handle`."
                    },
                    "customer_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "WhatsApp profile name, when shared."
                    },
                    "customer_phone": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Phone number when it differs from the WhatsApp id."
                    },
                    "customer_note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Free text the customer attached to the order."
                    },
                    "product_items": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        },
                        "description": "The cart lines."
                    },
                    "total_amount": {
                        "type": "integer",
                        "description": "Order total in the minor unit of `total_currency`."
                    },
                    "total_currency": {
                        "type": "string",
                        "description": "ISO 4217 currency code."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "confirmed",
                            "processing",
                            "shipped",
                            "delivered",
                            "cancelled",
                            "refunded"
                        ],
                        "description": "Fulfilment state."
                    },
                    "needs_attention": {
                        "type": "boolean",
                        "description": "Somebody has to look at this before it can be fulfilled: a line we could not hold stock for, or a product code that is not in the catalogue. The order still exists \u2014 a customer asked for it \u2014 and the offending line says which of the two it is."
                    },
                    "gateway_message_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "WhatsApp message id the order arrived on."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 creation timestamp."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "ISO 8601 update timestamp."
                    }
                }
            },
            "WebhookEvent": {
                "type": "object",
                "properties": {
                    "event": {
                        "type": "string",
                        "description": "Event name. The full list with a sample payload each is at `GET /api/v3/webhooks/events`; the dashboard picker and this enum both read the same catalogue.",
                        "enum": [
                            "message.received",
                            "message.sent",
                            "message.delivered",
                            "message.read",
                            "message.failed",
                            "message.echoed",
                            "message.updated",
                            "order.received",
                            "order.status_changed",
                            "order.cancelled",
                            "order.paid",
                            "sync.completed",
                            "stock.low",
                            "product.blocked",
                            "product.drifted",
                            "campaign.completed",
                            "campaign.failed",
                            "group.created",
                            "group.create_failed",
                            "group.updated",
                            "group.deleted",
                            "group.suspended",
                            "group.suspension_cleared",
                            "group.participant_joined",
                            "group.participant_left",
                            "group.participant_removed",
                            "group.join_requested",
                            "group.join_request_revoked",
                            "group.invite_sent",
                            "template.status_changed",
                            "webhook.paused"
                        ]
                    },
                    "timestamp": {
                        "type": "string",
                        "description": "Dispatch time in ISO8601.",
                        "format": "date-time"
                    },
                    "message_id": {
                        "type": "integer",
                        "description": "Message events: local numeric message ID, usable in SMS/WhatsApp lookup."
                    },
                    "direction": {
                        "type": "string",
                        "description": "Message direction.",
                        "enum": [
                            "inbound",
                            "outbound"
                        ]
                    },
                    "sender": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Message sender identity."
                    },
                    "recipient": {
                        "type": "string",
                        "description": "Message recipient identity."
                    },
                    "status": {
                        "type": "string",
                        "description": "Message delivery state."
                    },
                    "body": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Message body."
                    },
                    "media_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Attached media URL."
                    },
                    "channel_type": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Message channel type."
                    },
                    "order_id": {
                        "type": "integer",
                        "description": "Order events: local order ID."
                    },
                    "customer_wa_id": {
                        "type": "string",
                        "description": "order.received: customer WhatsApp identifier."
                    },
                    "customer_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "order.received: customer name."
                    },
                    "product_items": {
                        "type": "array",
                        "description": "order.received: incoming cart items.",
                        "items": {
                            "$ref": "#/components/schemas/OrderItem"
                        }
                    },
                    "total_amount": {
                        "type": "integer",
                        "description": "order.received: total in integer hundredths."
                    },
                    "total_currency": {
                        "type": "string",
                        "description": "order.received: currency code."
                    },
                    "customer_note": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "order.received: customer note."
                    },
                    "conversation_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Order event: linked conversation ID."
                    },
                    "created_at": {
                        "type": "string",
                        "description": "order.received: creation time.",
                        "format": "date-time"
                    },
                    "payment_id": {
                        "type": "integer",
                        "description": "order.paid: payment ID."
                    },
                    "method": {
                        "type": "string",
                        "description": "order.paid: payment method."
                    },
                    "amount_minor": {
                        "type": "integer",
                        "description": "order.paid: paid amount in minor units."
                    },
                    "currency": {
                        "type": "string",
                        "description": "order.paid: currency code."
                    },
                    "payer_msisdn": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "order.paid: payer phone number."
                    },
                    "paid_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "order.paid: settlement time.",
                        "format": "date-time"
                    },
                    "group": {
                        "$ref": "#/components/schemas/WhatsAppGroup",
                        "description": "Current local WhatsApp group summary, when the event concerns a group."
                    },
                    "wa_ids": {
                        "type": "array",
                        "description": "Participant event: affected WhatsApp IDs.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Participant event reason when supplied."
                    },
                    "applied": {
                        "type": "object",
                        "description": "group.updated: applied settings.",
                        "additionalProperties": true
                    },
                    "errors": {
                        "type": [
                            "array",
                            "object",
                            "null"
                        ],
                        "description": "Provider/group error details.",
                        "items": [],
                        "additionalProperties": true
                    },
                    "sent": {
                        "type": [
                            "integer",
                            "array"
                        ],
                        "description": "group.invite_sent: successfully sent invitations.",
                        "items": []
                    },
                    "failed": {
                        "type": [
                            "integer",
                            "array"
                        ],
                        "description": "group.invite_sent: failed invitations.",
                        "items": []
                    },
                    "template_id": {
                        "type": "integer",
                        "description": "template.status_changed: local template id, for `GET /api/v3/whatsapp/templates/{template}`."
                    },
                    "name": {
                        "type": "string",
                        "description": "template.status_changed: the template name."
                    },
                    "language": {
                        "type": "string",
                        "description": "template.status_changed: the template language."
                    },
                    "whatsapp_business_account_id": {
                        "type": "string",
                        "description": "template.status_changed: the WhatsApp Business Account whose review moved."
                    },
                    "whatsapp_template_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "template.status_changed: Meta's id on that account."
                    },
                    "previous_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "template.status_changed: the status before this change."
                    },
                    "whatsapp_status": {
                        "type": "string",
                        "description": "template.status_changed: the status now.",
                        "enum": [
                            "pending",
                            "in_review",
                            "approved",
                            "rejected",
                            "disabled",
                            "paused"
                        ]
                    },
                    "rejection_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "template.status_changed: Meta's reason when the new status is rejected."
                    }
                },
                "required": [
                    "event",
                    "timestamp"
                ],
                "description": "Actual flat ChannelWebhook payload. Message events include message_id/direction/sender/recipient/status/body/media_url/channel_type. Orders and groups supply their own fields. No data wrapper, tenant_id or occurred_at is added by this dispatcher."
            },
            "WhatsAppGroup": {
                "type": "object",
                "description": "A WhatsApp group the business number created. `id` is the platform id every endpoint takes; `meta_group_id` is WhatsApp's own id and is null while status is `creating`.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Platform id of the group; what every group endpoint takes."
                    },
                    "meta_group_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "WhatsApp's own group id. Null while the group is still being created."
                    },
                    "request_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "WhatsApp's create request id; how the confirmation webhook is matched."
                    },
                    "phone_number_id": {
                        "type": "string",
                        "description": "The business number the group was created from."
                    },
                    "waba_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The WhatsApp Business Account the number belongs to."
                    },
                    "subject": {
                        "type": "string",
                        "maxLength": 128,
                        "description": "The group name, up to 128 characters."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 2048,
                        "description": "What the group is for; members see it before joining. Up to 2048 characters."
                    },
                    "join_approval_mode": {
                        "type": "string",
                        "enum": [
                            "auto_approve",
                            "approval_required"
                        ],
                        "description": "auto_approve: anyone with the link joins. approval_required: the business approves each request."
                    },
                    "invite_link": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The chat.whatsapp.com link people tap to join. Null until WhatsApp confirms the group."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "creating",
                            "active",
                            "suspended",
                            "deleted",
                            "failed"
                        ],
                        "description": "creating (waiting for WhatsApp), active, suspended (by WhatsApp, for policy), deleted, or failed (WhatsApp refused to create it; see last_error)."
                    },
                    "participant_count": {
                        "type": "integer",
                        "description": "Members besides the business."
                    },
                    "max_participants": {
                        "type": "integer",
                        "description": "8, the business counted in."
                    },
                    "seats_left": {
                        "type": "integer",
                        "description": "How many more people can join."
                    },
                    "pending_join_requests": {
                        "type": "integer",
                        "description": "People waiting for approval on an approval_required group."
                    },
                    "conversation_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The inbox thread for the group."
                    },
                    "invite_template_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The approved template used for invites from this group."
                    },
                    "last_message_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the thread last had a message, either way."
                    },
                    "last_error": {
                        "type": [
                            "object",
                            "array",
                            "null"
                        ],
                        "description": "WhatsApp's last refusal, when there was one."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the roster and settings were last read back from WhatsApp."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the platform created the record."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it last changed."
                    }
                },
                "required": [
                    "id",
                    "subject",
                    "status",
                    "participant_count",
                    "max_participants"
                ]
            },
            "WhatsAppGroupParticipant": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Platform id of the group; what every group endpoint takes."
                    },
                    "wa_id": {
                        "type": "string",
                        "description": "The person, as WhatsApp identifies them (digits, international format)."
                    },
                    "display_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The name WhatsApp showed with their last message, when known."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "invited",
                            "member",
                            "left",
                            "removed",
                            "failed"
                        ],
                        "description": "creating (waiting for WhatsApp), active, suspended (by WhatsApp, for policy), deleted, or failed (WhatsApp refused to create it; see last_error)."
                    },
                    "invited_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the invite template was sent to them."
                    },
                    "joined_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When they joined."
                    },
                    "left_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When they left or were removed."
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "How they got here: invite_link, left, removed_by_business, sync, group_deleted."
                    },
                    "last_error": {
                        "type": [
                            "object",
                            "array",
                            "null"
                        ],
                        "description": "WhatsApp's last refusal, when there was one."
                    }
                }
            },
            "WhatsAppGroupJoinRequest": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Platform id of the group; what every group endpoint takes."
                    },
                    "join_request_id": {
                        "type": "string",
                        "description": "WhatsApp's id for the request; what approve and reject take."
                    },
                    "wa_id": {
                        "type": "string",
                        "description": "The person, as WhatsApp identifies them (digits, international format)."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "approved",
                            "rejected",
                            "revoked",
                            "failed"
                        ],
                        "description": "creating (waiting for WhatsApp), active, suspended (by WhatsApp, for policy), deleted, or failed (WhatsApp refused to create it; see last_error)."
                    },
                    "requested_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When they asked to join."
                    },
                    "resolved_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the request was approved, rejected or withdrawn."
                    }
                }
            },
            "WhatsAppGroupEvent": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Platform id of the group; what every group endpoint takes."
                    },
                    "type": {
                        "type": "string",
                        "description": "What happened, e.g. group.participant_joined."
                    },
                    "actor": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "business",
                            "participant",
                            "meta",
                            "user",
                            null
                        ],
                        "description": "Who did it: business, participant, meta, or a user of this platform."
                    },
                    "payload": {
                        "type": [
                            "object",
                            "array",
                            "null"
                        ],
                        "description": "Event-specific detail."
                    },
                    "occurred_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it happened."
                    }
                }
            },
            "WhatsAppGroupDetail": {
                "allOf": [
                    {
                        "$ref": "#/components/schemas/WhatsAppGroup"
                    },
                    {
                        "type": "object",
                        "properties": {
                            "participants": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/WhatsAppGroupParticipant"
                                },
                                "description": "Everyone ever invited into or seen in the group, with their current state."
                            },
                            "join_requests": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/WhatsAppGroupJoinRequest"
                                },
                                "description": "Join requests, newest first."
                            },
                            "invite_template": {
                                "type": [
                                    "object",
                                    "null"
                                ],
                                "properties": {
                                    "id": {
                                        "type": "integer",
                                        "description": "Platform id of the group; what every group endpoint takes."
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "Template name."
                                    },
                                    "language": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "description": "Template language code."
                                    },
                                    "whatsapp_status": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "description": "The template's approval state on WhatsApp."
                                    }
                                },
                                "description": "Name of an approved group-invite template on this account."
                            },
                            "events": {
                                "type": "array",
                                "items": {
                                    "$ref": "#/components/schemas/WhatsAppGroupEvent"
                                },
                                "description": "Recent activity, newest first."
                            }
                        }
                    }
                ]
            },
            "DataTable": {
                "type": "object",
                "description": "A table as the list shows it.",
                "required": [
                    "id",
                    "name",
                    "slug",
                    "records_count",
                    "columns_count"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The table id; the `{table}` path parameter everywhere else."
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "slug": {
                        "type": "string",
                        "description": "URL-safe name, unique within the tenant."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the table holds, as written by whoever created it."
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Icon name chosen in the dashboard, or null."
                    },
                    "records_count": {
                        "type": "integer",
                        "description": "Live (not deleted) records in the table."
                    },
                    "columns_count": {
                        "type": "integer",
                        "description": "Columns defined on the table."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the table or its columns last changed (ISO-8601)."
                    }
                }
            },
            "DataTableDetail": {
                "type": "object",
                "description": "The table as the schema payload describes it: the list row plus storage, the title column and the creation time.",
                "required": [
                    "id",
                    "name",
                    "slug",
                    "records_count",
                    "storage_bytes"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The table id."
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "slug": {
                        "type": "string",
                        "description": "URL-safe name, unique within the tenant."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the table holds, or null."
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Icon name chosen in the dashboard, or null."
                    },
                    "records_count": {
                        "type": "integer",
                        "description": "Live (not deleted) records in the table."
                    },
                    "storage_bytes": {
                        "type": "integer",
                        "description": "Bytes the records occupy, counted against the storage quota."
                    },
                    "title_column": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Key of the column that names a record (the `title` on every record row), or null when the first text column is used."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the table was created (ISO-8601)."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the table or its columns last changed (ISO-8601)."
                    },
                    "retention": {
                        "type": "object",
                        "description": "Retention policy description.",
                        "additionalProperties": true
                    },
                    "legal_hold": {
                        "type": "boolean",
                        "description": "Whether retention deletion is held for this table."
                    }
                }
            },
            "DataColumn": {
                "type": "object",
                "description": "One column of a table: its key (the name to use in `data` and in filters), its type, the operators the type accepts in a filter, the validation rules a write runs, and display hints. A column whose type this version does not know comes back as `type: \"unknown\"` with a `warning`; its values are read-only.",
                "required": [
                    "id",
                    "key",
                    "label",
                    "type",
                    "position",
                    "required",
                    "unique",
                    "indexed",
                    "rules",
                    "operators",
                    "ui"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The column id."
                    },
                    "key": {
                        "type": "string",
                        "description": "The key this column has inside a record's `data`, and the `column` to name in a filter or a `sort`."
                    },
                    "label": {
                        "type": "string",
                        "description": "Display label."
                    },
                    "type": {
                        "type": "string",
                        "enum": [
                            "text",
                            "long_text",
                            "number",
                            "currency",
                            "boolean",
                            "date",
                            "datetime",
                            "phone",
                            "email",
                            "select",
                            "multi_select",
                            "relation",
                            "file",
                            "auto_number",
                            "unknown"
                        ],
                        "description": "The field type. Its rules, operators and display hints are in `types` on the schema payload. `auto_number` is written by the platform: its `ui.readonly` is true and a value sent for it is refused."
                    },
                    "stored_type": {
                        "type": "string",
                        "description": "Only when `type` is `unknown`: the type name actually stored, which this version cannot render."
                    },
                    "position": {
                        "type": "integer",
                        "description": "Zero-based column order; record `data` keys come back in this order."
                    },
                    "required": {
                        "type": "boolean",
                        "description": "A create must supply a value; an update may not clear it."
                    },
                    "unique": {
                        "type": "boolean",
                        "description": "No two live records may share a value. A duplicate answers 422 with `errors`."
                    },
                    "indexed": {
                        "type": "boolean",
                        "description": "Whether the column has an index. Sorting a large table on a column needs one \u2014 see `sort_index_threshold`."
                    },
                    "index_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "enum": [
                            "pending",
                            "building",
                            "ready",
                            "failed",
                            "dropping",
                            null
                        ],
                        "description": "State of the latest index job on this column, or null when none was ever requested. Only `ready` makes the column sortable at scale."
                    },
                    "index_error": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why the index build failed, when `index_status` is `failed`."
                    },
                    "config": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Type-specific settings: `options` for select/multi_select, `table_id` for relation, `default`, `ui` hints, and so on."
                    },
                    "rules": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "The validation rules a write runs, Laravel-style (`required`, `phone:TZ`, `max:255`, \u2026)."
                    },
                    "operators": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "equals",
                                "not_equals",
                                "contains",
                                "starts_with",
                                "greater_than",
                                "less_than",
                                "between",
                                "is_empty",
                                "is_not_empty",
                                "in"
                            ]
                        },
                        "description": "The filter operators this column accepts. Any other operator answers 422."
                    },
                    "ui": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Display hints for a grid or form: `cell` and `input` renderer names, `filter` widget, `width` in pixels, plus any of `hidden_in_grid`, `hidden_in_form`, `help_text`, `placeholder`, `is_title_field` set in the dashboard.",
                        "properties": {
                            "cell": {
                                "type": "string",
                                "description": "Renderer for the value in a grid cell."
                            },
                            "input": {
                                "type": "string",
                                "description": "Renderer for the value in a form."
                            },
                            "filter": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Filter widget, or null when the column cannot be filtered."
                            },
                            "width": {
                                "type": "integer",
                                "description": "Suggested column width in pixels."
                            }
                        }
                    },
                    "warning": {
                        "type": "string",
                        "description": "Only when `type` is `unknown`: why the column is read-only."
                    }
                }
            },
            "DataFieldType": {
                "type": "object",
                "description": "What one field type can do, keyed by type name in the schema payload's `types`.",
                "required": [
                    "label",
                    "operators",
                    "ui",
                    "numeric",
                    "temporal"
                ],
                "properties": {
                    "label": {
                        "type": "string",
                        "description": "Display label of the type."
                    },
                    "operators": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "equals",
                                "not_equals",
                                "contains",
                                "starts_with",
                                "greater_than",
                                "less_than",
                                "between",
                                "is_empty",
                                "is_not_empty",
                                "in"
                            ]
                        },
                        "description": "The filter operators the type accepts."
                    },
                    "ui": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "Default display hints for columns of this type (`cell`, `input`, `filter`, `width`).",
                        "properties": {
                            "cell": {
                                "type": "string",
                                "description": "Renderer for the value in a grid cell."
                            },
                            "input": {
                                "type": "string",
                                "description": "Renderer for the value in a form."
                            },
                            "filter": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Filter widget, or null."
                            },
                            "width": {
                                "type": "integer",
                                "description": "Suggested column width in pixels."
                            }
                        }
                    },
                    "numeric": {
                        "type": "boolean",
                        "description": "True for number and currency: `greater_than`, `less_than` and `between` compare as numbers."
                    },
                    "temporal": {
                        "type": "boolean",
                        "description": "True for date and datetime: filter values may be a `{\"relative\": \"<preset>\"}` window."
                    }
                }
            },
            "DataSystemColumn": {
                "type": "object",
                "description": "A column every table has without defining it. Filter and sort on it by its `$`-prefixed key.",
                "required": [
                    "key",
                    "label",
                    "type",
                    "operators"
                ],
                "properties": {
                    "key": {
                        "type": "string",
                        "enum": [
                            "$id",
                            "$created_at",
                            "$updated_at",
                            "$source"
                        ],
                        "description": "The key to use in a filter `column` or in `sort`."
                    },
                    "label": {
                        "type": "string",
                        "description": "Display label."
                    },
                    "type": {
                        "type": "string",
                        "description": "The field type its values behave as."
                    },
                    "operators": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "enum": [
                                "equals",
                                "not_equals",
                                "contains",
                                "starts_with",
                                "greater_than",
                                "less_than",
                                "between",
                                "is_empty",
                                "is_not_empty",
                                "in"
                            ]
                        },
                        "description": "The operators this system column accepts."
                    }
                }
            },
            "DataSchema": {
                "type": "object",
                "description": "Everything a client needs to read and write one table: the table, its columns, what each type can do, the system columns, quota usage and what this key may do. Re-fetch it after any column change in the dashboard.",
                "required": [
                    "table",
                    "columns",
                    "types",
                    "system_columns",
                    "limits",
                    "sort_index_threshold",
                    "can",
                    "access",
                    "actions",
                    "unique_sets"
                ],
                "properties": {
                    "table": {
                        "$ref": "#/components/schemas/DataTableDetail",
                        "description": "The table."
                    },
                    "columns": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataColumn"
                        },
                        "description": "The columns, in position order."
                    },
                    "types": {
                        "type": "object",
                        "additionalProperties": {
                            "$ref": "#/components/schemas/DataFieldType"
                        },
                        "description": "Every field type this version knows, keyed by name (`text`, `number`, `phone`, \u2026)."
                    },
                    "system_columns": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataSystemColumn"
                        },
                        "description": "The `$id`, `$created_at`, `$updated_at` and `$source` columns."
                    },
                    "limits": {
                        "type": "object",
                        "description": "Current table allowances and usage. Record/storage quota refusals use HTTP 402 with error.code quota_exceeded and quota/limit/used in error.details.",
                        "properties": {
                            "columns": {
                                "type": "object",
                                "description": "How many columns the table uses against its allowance.",
                                "properties": {
                                    "used": {
                                        "type": "integer",
                                        "description": "columns in use."
                                    },
                                    "max": {
                                        "type": "integer",
                                        "description": "The most columns this table may have."
                                    }
                                }
                            },
                            "indexes": {
                                "type": "object",
                                "description": "How many indexes the table uses against its allowance.",
                                "properties": {
                                    "used": {
                                        "type": "integer",
                                        "description": "indexes in use."
                                    },
                                    "max": {
                                        "type": "integer",
                                        "description": "The most indexes this table may have."
                                    }
                                }
                            },
                            "records": {
                                "type": "object",
                                "description": "How many records the table uses against its allowance.",
                                "properties": {
                                    "used": {
                                        "type": "integer",
                                        "description": "records in use."
                                    },
                                    "max": {
                                        "type": "integer",
                                        "description": "The most records this table may have."
                                    }
                                }
                            },
                            "storage": {
                                "type": "object",
                                "description": "Bytes the records occupy against the table's storage allowance.",
                                "properties": {
                                    "used_bytes": {
                                        "type": "integer",
                                        "description": "Bytes in use."
                                    },
                                    "max_bytes": {
                                        "type": "integer",
                                        "description": "The storage allowance in bytes."
                                    }
                                }
                            }
                        }
                    },
                    "sort_index_threshold": {
                        "type": "integer",
                        "description": "At or above this record count, sorting on an unindexed user column returns 501 not_supported with reason sort_needs_index. System timestamp sorts remain supported."
                    },
                    "can": {
                        "type": "object",
                        "description": "What the user who issued this key may do.",
                        "properties": {
                            "manage": {
                                "type": "boolean",
                                "description": "May change tables and columns (in the dashboard; not over this API)."
                            },
                            "edit_records": {
                                "type": "boolean",
                                "description": "May create, change and delete records \u2014 the gate on the write endpoints here."
                            },
                            "manage_reports": {
                                "type": "boolean",
                                "description": "May save reports on this table."
                            }
                        }
                    },
                    "access": {
                        "type": "object",
                        "description": "Per-table access for this caller, including governed state and granted capabilities.",
                        "additionalProperties": true
                    },
                    "actions": {
                        "type": "array",
                        "description": "Available record-action summaries, without private action secrets.",
                        "items": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    },
                    "unique_sets": {
                        "type": "array",
                        "description": "Unique field combinations and their index state.",
                        "items": {
                            "type": "object",
                            "additionalProperties": true
                        }
                    }
                }
            },
            "DataRecord": {
                "type": "object",
                "description": "One record: its values keyed by column key, who wrote it, when, and what names it.",
                "required": [
                    "id",
                    "data",
                    "source",
                    "created_at",
                    "updated_at",
                    "title"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The record id."
                    },
                    "data": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "The values, keyed by column key, in column position order. A column with no value is absent or null."
                    },
                    "source": {
                        "type": "string",
                        "description": "Who created the record, fixed at create time: `ui` for a person in the dashboard, `api` for this API, a flow identifier for a flow. Filter on it with the `$source` system column."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the record was created \u2014 UTC, with microseconds, so a cursor built from it resumes at exactly this row."
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the record last changed (UTC, microseconds)."
                    },
                    "title": {
                        "type": "string",
                        "description": "What names this record: the table's title column, else its first text column, else the id."
                    },
                    "titles": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "string"
                        },
                        "description": "Only on tables with relation columns: the related record's title keyed by the relation column key, resolved once per page so a client never fetches per cell."
                    }
                }
            },
            "DataRecordPage": {
                "type": "object",
                "description": "One keyset page of records.",
                "required": [
                    "records",
                    "next_cursor",
                    "has_more",
                    "count",
                    "served_at"
                ],
                "properties": {
                    "records": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataRecord"
                        },
                        "description": "The records on this page, in the requested sort order."
                    },
                    "next_cursor": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Opaque position of the last row served. Pass it back as `cursor` \u2014 with the same `filter`, `q`, `sort` and `dir` \u2014 for the next page. Null on the last page."
                    },
                    "has_more": {
                        "type": "boolean",
                        "description": "Whether another page follows."
                    },
                    "count": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Total records matching the filter and search \u2014 only when `with_count=1` was sent, otherwise null."
                    },
                    "served_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When this page was read (UTC). Records created after it are not on any later page of the same cursor chain when sorting `$created_at desc`."
                    }
                }
            },
            "DataCondition": {
                "type": "object",
                "description": "A filter, as a condition tree. A node is either a group \u2014 `{\"all\": [...]}` (AND) or `{\"any\": [...]}` (OR), nested up to 6 deep \u2014 or a leaf `{column, op, value}`. At most 40 leaves. An empty object is no filter.\n\n`column` is a column key from the schema, or a system column: `$id` (equals, in), `$created_at` / `$updated_at` (equals, not_equals, greater_than, less_than, between), `$source` (equals, in, starts_with). `op` must be one the column's type lists in `operators`, or the request answers 422.\n\n`value` follows the type: a scalar for equals/not_equals/contains/starts_with/greater_than/less_than, a list for `in` and for `between` (`[from, to]`), nothing for is_empty/is_not_empty. Values are validated and coerced through the column type first, so `phone equals 0712345678` matches the stored `+255712345678`. For date and datetime columns `value` may be `{\"relative\": \"<preset>\"}` \u2014 `today`, `yesterday`, `last_7_days`, `last_30_days`, `last_90_days`, `this_month`, `last_month` \u2014 with any temporal operator: equals/between = inside the window, greater_than = since its start, less_than = before its end. On `multi_select`, `contains` means has ANY of the listed options and `in` means has ALL.",
                "properties": {
                    "all": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataCondition"
                        },
                        "description": "Every child must match (AND)."
                    },
                    "any": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataCondition"
                        },
                        "description": "At least one child must match (OR)."
                    },
                    "column": {
                        "type": "string",
                        "description": "Leaf only: the column key, or a `$`-prefixed system column."
                    },
                    "op": {
                        "type": "string",
                        "enum": [
                            "equals",
                            "not_equals",
                            "contains",
                            "starts_with",
                            "greater_than",
                            "less_than",
                            "between",
                            "is_empty",
                            "is_not_empty",
                            "in"
                        ],
                        "description": "Leaf only: the operator. Must be one the column's type accepts."
                    },
                    "value": {
                        "description": "Leaf only: the value to compare with \u2014 a scalar, a list for `in`/`between`, a `{\"relative\": preset}` window on temporal columns, or omitted for `is_empty`/`is_not_empty`."
                    }
                }
            },
            "DataError": {
                "type": "object",
                "properties": {
                    "error": {
                        "$ref": "#/components/schemas/DataErrorDetails",
                        "description": "Structured domain refusal with a stable machine code and retry guidance."
                    },
                    "message": {
                        "type": "string",
                        "description": "Compatibility human message from the originating refusal."
                    },
                    "code": {
                        "type": "string",
                        "description": "Same category as error.code.",
                        "enum": [
                            "validation_error",
                            "conflict",
                            "not_found",
                            "rate_limited",
                            "quota_exceeded",
                            "temporary_failure",
                            "permission_denied",
                            "not_supported",
                            "provider_failure"
                        ]
                    },
                    "errors": {
                        "type": "object",
                        "description": "Optional field messages in Laravel validation shape.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                },
                "required": [
                    "error",
                    "message",
                    "code"
                ],
                "description": "Expected refusal from the data store. Authentication/framework failures can instead use LegacyErrorEnvelope. Quotas are 402; conflicts 409; unsupported operators and sorts needing an index 501."
            },
            "DataTableGroup": {
                "type": "object",
                "description": "A named folder of related tables inside the tenant's workspace, with a report layer that reads across every table in it.",
                "required": [
                    "id",
                    "name",
                    "slug",
                    "position",
                    "tables_count",
                    "records_count"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The group id; the `{group}` path parameter everywhere else."
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "slug": {
                        "type": "string",
                        "description": "URL-safe name, unique within the tenant."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the group holds."
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "An emoji shown before the name, or null."
                    },
                    "color": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "One of the select-option palette keys (gray, red, orange, amber, yellow, lime, green, emerald, teal, cyan, sky, blue, indigo, violet, purple, fuchsia, pink, rose), or null."
                    },
                    "position": {
                        "type": "integer",
                        "description": "Order among the tenant's groups, first = 0."
                    },
                    "tables_count": {
                        "type": "integer",
                        "description": "Member tables."
                    },
                    "records_count": {
                        "type": "integer",
                        "description": "Live records across the member tables."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was created (ISO-8601)."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it last changed (ISO-8601)."
                    }
                }
            },
            "DataDrill": {
                "type": "object",
                "description": "How to open the table's Records view on exactly the rows behind a number: `GET /api/v3/data/tables/{table_id}/records?filter=<filter>`.",
                "required": [
                    "table_id",
                    "filter",
                    "range"
                ],
                "properties": {
                    "table_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The table id."
                    },
                    "filter": {
                        "$ref": "#/components/schemas/DataCondition",
                        "description": "A condition tree for the records endpoint."
                    },
                    "range": {
                        "type": "object",
                        "required": [
                            "from",
                            "to"
                        ],
                        "properties": {
                            "from": {
                                "type": "string",
                                "format": "date-time",
                                "description": "Start of the window (inclusive, ISO-8601)."
                            },
                            "to": {
                                "type": "string",
                                "format": "date-time",
                                "description": "End of the window (exclusive, ISO-8601)."
                            }
                        },
                        "description": "The half-open [from, to) window."
                    }
                }
            },
            "DataGroupTableCard": {
                "type": "object",
                "description": "One member table as the group overview shows it.",
                "required": [
                    "id",
                    "name",
                    "slug",
                    "records_count",
                    "columns_count",
                    "headline",
                    "created_last_range",
                    "drill"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id."
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "slug": {
                        "type": "string",
                        "description": "URL-safe name, unique within the tenant."
                    },
                    "icon": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "An emoji shown before the name, or null."
                    },
                    "records_count": {
                        "type": "integer",
                        "description": "Live records in the table."
                    },
                    "columns_count": {
                        "type": "integer",
                        "description": "Columns defined on the table."
                    },
                    "headline": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "The first amount-like column's total over the range, or null when the table has none.",
                        "properties": {
                            "label": {
                                "type": "string",
                                "description": "Human label."
                            },
                            "fn": {
                                "type": "string",
                                "enum": [
                                    "sum"
                                ],
                                "description": "The aggregate."
                            },
                            "column": {
                                "type": "string",
                                "description": "The column key."
                            },
                            "value": {
                                "type": [
                                    "number",
                                    "null"
                                ],
                                "description": "The computed value, or null when nothing matched."
                            },
                            "unit": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "The column's unit (e.g. TZS), or null."
                            }
                        }
                    },
                    "created_last_range": {
                        "type": "integer",
                        "description": "Records created inside the range."
                    },
                    "drill": {
                        "$ref": "#/components/schemas/DataDrill",
                        "description": "How to open the rows behind the number."
                    },
                    "columns": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataColumn"
                        },
                        "description": "The table's columns in the schema shape (`GET /groups/{group}` only)."
                    }
                }
            },
            "DataGroupOverview": {
                "type": "object",
                "description": "The group's overview for a range, derived at read time (cached 60 s, invalidated by any write to a member table).",
                "required": [
                    "totals",
                    "tables",
                    "over_time",
                    "headlines",
                    "relations",
                    "range"
                ],
                "properties": {
                    "totals": {
                        "type": "object",
                        "required": [
                            "tables",
                            "records",
                            "storage_bytes"
                        ],
                        "properties": {
                            "tables": {
                                "type": "integer",
                                "description": "Member tables."
                            },
                            "records": {
                                "type": "integer",
                                "description": "Live records across the group."
                            },
                            "storage_bytes": {
                                "type": "integer",
                                "description": "JSONB bytes across the group."
                            }
                        },
                        "description": "Sums across the member tables."
                    },
                    "tables": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/DataGroupTableCard"
                        },
                        "description": "Member tables."
                    },
                    "over_time": {
                        "type": "object",
                        "description": "Records created per bucket, stacked by table. The bucket follows the range: day up to 31 days, week up to 182, else month.",
                        "required": [
                            "bucket",
                            "rows"
                        ],
                        "properties": {
                            "bucket": {
                                "type": "string",
                                "enum": [
                                    "day",
                                    "week",
                                    "month"
                                ],
                                "description": "The bucket start date."
                            },
                            "rows": {
                                "type": "array",
                                "items": {
                                    "type": "object",
                                    "required": [
                                        "bucket",
                                        "total",
                                        "by_table"
                                    ],
                                    "properties": {
                                        "bucket": {
                                            "type": "string",
                                            "format": "date",
                                            "description": "The bucket start date."
                                        },
                                        "total": {
                                            "type": "integer",
                                            "description": "Records across every table in the bucket."
                                        },
                                        "by_table": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "integer"
                                            },
                                            "description": "table id \u2192 records created in the bucket."
                                        },
                                        "drill": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "$ref": "#/components/schemas/DataDrill"
                                            },
                                            "description": "table id \u2192 drill for that bucket."
                                        }
                                    }
                                },
                                "description": "One row per bucket, oldest first."
                            }
                        }
                    },
                    "headlines": {
                        "type": "array",
                        "description": "Every amount-like number column across the group (a key or label naming money, or `config.ui.is_summary_metric`), totalled over the range.",
                        "items": {
                            "type": "object",
                            "required": [
                                "table_id",
                                "table",
                                "label",
                                "fn",
                                "column",
                                "value",
                                "unit",
                                "chart",
                                "drill"
                            ],
                            "properties": {
                                "table_id": {
                                    "type": "string",
                                    "format": "uuid",
                                    "description": "The table id."
                                },
                                "table": {
                                    "type": "string",
                                    "description": "The table's display name."
                                },
                                "label": {
                                    "type": "string",
                                    "description": "Human label."
                                },
                                "fn": {
                                    "type": "string",
                                    "description": "The aggregate."
                                },
                                "column": {
                                    "type": "string",
                                    "description": "The column key."
                                },
                                "value": {
                                    "type": [
                                        "number",
                                        "null"
                                    ],
                                    "description": "The computed value, or null when nothing matched."
                                },
                                "unit": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "The column's unit (e.g. TZS), or null."
                                },
                                "chart": {
                                    "type": "string",
                                    "enum": [
                                        "number"
                                    ],
                                    "description": "How the card is drawn."
                                },
                                "drill": {
                                    "$ref": "#/components/schemas/DataDrill",
                                    "description": "How to open the rows behind the number."
                                }
                            }
                        }
                    },
                    "relations": {
                        "type": "array",
                        "description": "Relation columns whose target table is inside the group.",
                        "items": {
                            "type": "object",
                            "required": [
                                "from_table_id",
                                "from_column",
                                "to_table_id"
                            ],
                            "properties": {
                                "from_table_id": {
                                    "type": "string",
                                    "format": "uuid",
                                    "description": "The table holding the relation column."
                                },
                                "from_column": {
                                    "type": "string",
                                    "description": "The relation column key."
                                },
                                "to_table_id": {
                                    "type": "string",
                                    "format": "uuid",
                                    "description": "The table the relation points at."
                                }
                            }
                        }
                    },
                    "range": {
                        "type": "object",
                        "required": [
                            "from",
                            "to"
                        ],
                        "properties": {
                            "from": {
                                "type": "string",
                                "format": "date-time",
                                "description": "Start of the window (inclusive, ISO-8601)."
                            },
                            "to": {
                                "type": "string",
                                "format": "date-time",
                                "description": "End of the window (exclusive, ISO-8601)."
                            },
                            "relative": {
                                "type": "string",
                                "description": "The preset the range came from, when it did."
                            }
                        },
                        "description": "The half-open [from, to) window."
                    },
                    "computed_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the numbers were computed (ISO-8601)."
                    }
                }
            },
            "DataGroupReport": {
                "type": "object",
                "description": "A saved cross-table report. The definition is the group-report shape: `series` (one measure per member table, or a `formula` over the other series' slugified labels), a `dimension` of `{\"column\":\"$created_at\",\"bucket\":\"week\"}` (shared time axis), `{\"kind\":\"table\"}` (one row per series) or null (one number per series), a `date_range`, a `chart`, and optionally `compare`, `sort`, `limit`.",
                "required": [
                    "id",
                    "group_id",
                    "name",
                    "definition",
                    "is_pinned"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The id."
                    },
                    "group_id": {
                        "type": "string",
                        "format": "uuid",
                        "description": "The group id."
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "description": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "One line on what it shows, or null."
                    },
                    "definition": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "The report definition."
                    },
                    "is_pinned": {
                        "type": "boolean",
                        "description": "Pinned to the top of the Reports tab."
                    },
                    "is_default": {
                        "type": "boolean",
                        "description": "Always false for a saved report."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was created (ISO-8601)."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it last changed (ISO-8601)."
                    }
                }
            },
            "DataErrorDetails": {
                "type": "object",
                "properties": {
                    "code": {
                        "type": "string",
                        "description": "Stable refusal category.",
                        "enum": [
                            "validation_error",
                            "conflict",
                            "not_found",
                            "rate_limited",
                            "quota_exceeded",
                            "temporary_failure",
                            "permission_denied",
                            "not_supported",
                            "provider_failure"
                        ]
                    },
                    "message": {
                        "type": "string",
                        "description": "Human-readable explanation."
                    },
                    "retryable": {
                        "type": "boolean",
                        "description": "Whether repeating unchanged could succeed; still apply operation idempotency rules."
                    },
                    "field": {
                        "type": "string",
                        "description": "Field key associated with this refusal."
                    },
                    "expected_type": {
                        "type": "string",
                        "description": "Expected field type when available."
                    },
                    "received": {
                        "type": "string",
                        "description": "JSON type/shape description, not the submitted sensitive value."
                    },
                    "retry_after_seconds": {
                        "type": "integer",
                        "description": "Suggested wait before retry.",
                        "minimum": 0
                    },
                    "details": {
                        "type": "object",
                        "description": "Additional field errors, quota details or reason information.",
                        "additionalProperties": true
                    }
                },
                "required": [
                    "code",
                    "message",
                    "retryable"
                ]
            },
            "DataTableStates": {
                "type": "object",
                "properties": {
                    "table": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string",
                                "description": "Table UUID.",
                                "format": "uuid"
                            },
                            "name": {
                                "type": "string",
                                "description": "Table name."
                            },
                            "slug": {
                                "type": "string",
                                "description": "Table slug."
                            }
                        },
                        "required": [
                            "id",
                            "name",
                            "slug"
                        ],
                        "description": "Identity of the table whose status fields are described."
                    },
                    "fields": {
                        "type": "array",
                        "description": "One entry per status field; empty when the table has none.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "key": {
                                    "type": "string",
                                    "description": "Column key."
                                },
                                "label": {
                                    "type": "string",
                                    "description": "Field label."
                                },
                                "required": {
                                    "type": "boolean",
                                    "description": "Whether a value is required."
                                },
                                "strict": {
                                    "type": "boolean",
                                    "description": "Whether configured transition restrictions apply."
                                },
                                "initial": {
                                    "type": "array",
                                    "description": "Allowed initial state keys.",
                                    "items": {
                                        "type": "string"
                                    }
                                },
                                "states": {
                                    "type": "array",
                                    "description": "All configured states and moves.",
                                    "items": {
                                        "type": "object",
                                        "properties": {
                                            "key": {
                                                "type": "string",
                                                "description": "State key to write."
                                            },
                                            "label": {
                                                "type": "string",
                                                "description": "Display label."
                                            },
                                            "color": {
                                                "type": "string",
                                                "description": "Display color."
                                            },
                                            "initial": {
                                                "type": "boolean",
                                                "description": "May be an initial record state."
                                            },
                                            "final": {
                                                "type": "boolean",
                                                "description": "Final-state marker."
                                            },
                                            "next": {
                                                "type": "array",
                                                "description": "Available outgoing moves, annotated for the caller.",
                                                "items": {
                                                    "type": "object",
                                                    "properties": {
                                                        "key": {
                                                            "type": "string",
                                                            "description": "Destination state key."
                                                        },
                                                        "label": {
                                                            "type": "string",
                                                            "description": "Destination label."
                                                        },
                                                        "color": {
                                                            "type": "string",
                                                            "description": "Display color."
                                                        },
                                                        "final": {
                                                            "type": "boolean",
                                                            "description": "Whether destination is final."
                                                        },
                                                        "action": {
                                                            "type": "string",
                                                            "description": "Label for this move."
                                                        },
                                                        "requires": {
                                                            "type": [
                                                                "string",
                                                                "null"
                                                            ],
                                                            "description": "Additional permission required for this move."
                                                        },
                                                        "allowed": {
                                                            "type": "boolean",
                                                            "description": "Whether this caller may make this move."
                                                        }
                                                    },
                                                    "required": [
                                                        "key",
                                                        "label",
                                                        "color",
                                                        "final",
                                                        "action",
                                                        "requires",
                                                        "allowed"
                                                    ]
                                                }
                                            }
                                        },
                                        "required": [
                                            "key",
                                            "label",
                                            "color",
                                            "initial",
                                            "final",
                                            "next"
                                        ]
                                    }
                                }
                            },
                            "required": [
                                "key",
                                "label",
                                "required",
                                "strict",
                                "initial",
                                "states"
                            ]
                        }
                    }
                },
                "required": [
                    "table",
                    "fields"
                ]
            },
            "EngineTaskResult": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "description": "Domain execution outcome; inspect even on HTTP 200."
                    },
                    "run_uuid": {
                        "type": "string",
                        "description": "Stable run UUID.",
                        "format": "uuid"
                    },
                    "output": {
                        "type": [
                            "object",
                            "array",
                            "null"
                        ],
                        "description": "Agent output shaped by its execution contract.",
                        "additionalProperties": true,
                        "items": []
                    },
                    "denial_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Machine-readable reason when denied."
                    },
                    "usage": {
                        "type": "object",
                        "description": "Execution usage including token/cost values when available.",
                        "additionalProperties": true
                    }
                },
                "required": [
                    "status",
                    "run_uuid",
                    "output",
                    "denial_reason",
                    "usage"
                ]
            },
            "EngineTaskAccepted": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "description": "Current run status."
                    },
                    "run_uuid": {
                        "type": "string",
                        "description": "Run UUID.",
                        "format": "uuid"
                    },
                    "execution_state": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Execution progress state."
                    },
                    "delivery_state": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Delivery progress separate from computation."
                    },
                    "deadline_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Execution deadline.",
                        "format": "date-time"
                    },
                    "status_url": {
                        "type": "string",
                        "description": "Authenticated run polling URL.",
                        "format": "uri"
                    },
                    "denial_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Reason when admission was denied."
                    }
                },
                "required": [
                    "status",
                    "run_uuid",
                    "execution_state",
                    "delivery_state",
                    "deadline_at",
                    "status_url",
                    "denial_reason"
                ]
            },
            "EngineRunDetail": {
                "type": "object",
                "properties": {
                    "run": {
                        "type": "object",
                        "properties": {
                            "uuid": {
                                "type": "string",
                                "description": "Run UUID.",
                                "format": "uuid"
                            },
                            "trigger": {
                                "type": "string",
                                "description": "Trigger that created this run."
                            },
                            "status": {
                                "type": "string",
                                "description": "Execution outcome/status."
                            },
                            "execution_state": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Fine-grained execution state."
                            },
                            "delivery_state": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Delivery state."
                            },
                            "deadline_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Execution deadline.",
                                "format": "date-time"
                            },
                            "denial_reason": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Denial reason, when present."
                            },
                            "output": {
                                "type": [
                                    "object",
                                    "array",
                                    "null"
                                ],
                                "description": "Agent output.",
                                "additionalProperties": true,
                                "items": []
                            },
                            "provider": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Model provider."
                            },
                            "model_name": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Model identifier."
                            },
                            "prompt_tokens": {
                                "type": "integer",
                                "description": "Prompt tokens."
                            },
                            "completion_tokens": {
                                "type": "integer",
                                "description": "Completion tokens."
                            },
                            "cost_wallet": {
                                "type": "number",
                                "description": "Usage cost in cost_currency."
                            },
                            "cost_currency": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Cost currency."
                            },
                            "duration_ms": {
                                "type": [
                                    "integer",
                                    "null"
                                ],
                                "description": "Duration in milliseconds."
                            },
                            "created_at": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Run creation time.",
                                "format": "date-time"
                            }
                        },
                        "required": [
                            "uuid",
                            "trigger",
                            "status",
                            "execution_state",
                            "delivery_state",
                            "deadline_at",
                            "denial_reason",
                            "output",
                            "provider",
                            "model_name",
                            "prompt_tokens",
                            "completion_tokens",
                            "cost_wallet",
                            "cost_currency",
                            "duration_ms",
                            "created_at"
                        ],
                        "description": "Current run outcome, execution state and accumulated model usage."
                    },
                    "children": {
                        "type": "array",
                        "description": "Child executions belonging to this tenant.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "uuid": {
                                    "type": "string",
                                    "description": "Run UUID.",
                                    "format": "uuid"
                                },
                                "status": {
                                    "type": "string",
                                    "description": "Execution outcome/status."
                                },
                                "execution_state": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "Fine-grained execution state."
                                },
                                "deadline_at": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "Execution deadline.",
                                    "format": "date-time"
                                }
                            },
                            "required": [
                                "uuid",
                                "status",
                                "execution_state",
                                "deadline_at"
                            ]
                        }
                    },
                    "steps": {
                        "type": "array",
                        "description": "Trace steps, including linked result steps when available.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "position": {
                                    "type": "integer",
                                    "description": "Step order."
                                },
                                "kind": {
                                    "type": "string",
                                    "description": "Step type."
                                },
                                "tool_name": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "Tool invoked, when applicable."
                                },
                                "arguments": {
                                    "type": [
                                        "object",
                                        "array",
                                        "null"
                                    ],
                                    "description": "Tool arguments; can contain sensitive business data.",
                                    "additionalProperties": true,
                                    "items": []
                                },
                                "result_preview": {
                                    "type": [
                                        "string",
                                        "object",
                                        "array",
                                        "null"
                                    ],
                                    "description": "Recorded result preview.",
                                    "additionalProperties": true,
                                    "items": []
                                },
                                "status": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "Step status."
                                },
                                "duration_ms": {
                                    "type": [
                                        "integer",
                                        "null"
                                    ],
                                    "description": "Step duration."
                                }
                            },
                            "required": [
                                "position",
                                "kind",
                                "tool_name",
                                "arguments",
                                "result_preview",
                                "status",
                                "duration_ms"
                            ]
                        }
                    }
                },
                "required": [
                    "run",
                    "children",
                    "steps"
                ]
            },
            "EngineRequestError": {
                "type": "object",
                "properties": {
                    "message": {
                        "type": "string",
                        "description": "Framework validation error."
                    },
                    "errors": {
                        "type": "object",
                        "description": "Field errors, including idempotency_key for an invalid header.",
                        "additionalProperties": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            }
                        }
                    }
                },
                "required": [
                    "message"
                ]
            },
            "EngineAdmissionError": {
                "type": "object",
                "properties": {
                    "status": {
                        "type": "string",
                        "description": "busy, denied or conflict depending on the refusal."
                    },
                    "message": {
                        "type": "string",
                        "description": "Optional explanation."
                    },
                    "reason": {
                        "type": "string",
                        "description": "Ingress refusal code, e.g. ingress_busy."
                    },
                    "run_uuid": {
                        "type": "string",
                        "description": "Accepted/denied run UUID when known.",
                        "format": "uuid"
                    },
                    "denial_reason": {
                        "type": "string",
                        "description": "Capacity refusal code."
                    },
                    "retryable": {
                        "type": "boolean",
                        "description": "Whether a safe retry can succeed."
                    },
                    "retry_after": {
                        "type": "integer",
                        "description": "Suggested delay in seconds."
                    },
                    "status_url": {
                        "type": "string",
                        "description": "Run lookup URL when known.",
                        "format": "uri"
                    }
                },
                "required": [
                    "status"
                ]
            },
            "BusinessWebhookEvent": {
                "type": "object",
                "description": "Automation subscription delivery envelope. Verify the timestamped X-Momo-Signature before parsing the raw JSON bytes.",
                "required": [
                    "id",
                    "event",
                    "occurred_at",
                    "tenant_id",
                    "subject",
                    "actor",
                    "data",
                    "subscription"
                ],
                "properties": {
                    "id": {
                        "type": "string",
                        "description": "Stable business event UUID; retain to deduplicate each subscription delivery.",
                        "format": "uuid"
                    },
                    "event": {
                        "type": "string",
                        "description": "Known business event key. Use event_keys from the event read API to discover live publishers.",
                        "example": "record.created"
                    },
                    "occurred_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Time the business event occurred, distinct from the signature delivery timestamp.",
                        "format": "date-time"
                    },
                    "tenant_id": {
                        "type": "integer",
                        "description": "Account that owns this business event."
                    },
                    "subject": {
                        "type": "object",
                        "description": "Business resource the event concerns.",
                        "properties": {
                            "type": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Resource family, such as data_record."
                            },
                            "id": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Resource identifier within that family."
                            }
                        },
                        "required": [
                            "type",
                            "id"
                        ]
                    },
                    "actor": {
                        "type": [
                            "object",
                            "array"
                        ],
                        "description": "Publisher-provided actor attribution; shape varies by event source.",
                        "additionalProperties": true,
                        "items": []
                    },
                    "data": {
                        "type": [
                            "object",
                            "array"
                        ],
                        "description": "Publisher-provided event payload; shape varies by event key.",
                        "additionalProperties": true,
                        "items": []
                    },
                    "subscription": {
                        "type": "object",
                        "description": "Subscription that caused this delivery.",
                        "properties": {
                            "id": {
                                "type": "integer",
                                "description": "Local event subscription ID."
                            },
                            "label": {
                                "type": "string",
                                "description": "Subscription label at delivery time."
                            }
                        },
                        "required": [
                            "id",
                            "label"
                        ]
                    }
                }
            },
            "CatalogueChannel": {
                "type": "object",
                "description": "A shop's presence on one platform. A shop with no channels is complete and sells nowhere yet; publishing is something you add.",
                "required": [
                    "platform",
                    "label",
                    "is_connected"
                ],
                "properties": {
                    "platform": {
                        "type": "string",
                        "enum": [
                            "whatsapp",
                            "storefront",
                            "facebook",
                            "instagram",
                            "tiktok"
                        ],
                        "description": "Which platform this presence is on."
                    },
                    "label": {
                        "type": "string",
                        "description": "What the merchant named this connection."
                    },
                    "external_catalogue_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The platform's own id for the catalogue."
                    },
                    "external_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The account it is bound to \u2014 a WABA id for WhatsApp."
                    },
                    "public_slug": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Storefront address, when this is a hosted storefront."
                    },
                    "is_connected": {
                        "type": "boolean",
                        "description": "Whether customers can currently see it."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When products were last pushed to this platform."
                    }
                }
            },
            "ProductListing": {
                "type": "object",
                "description": "One product as one platform sees it. The same product can be live on your storefront and blocked on WhatsApp, and each row says so in its own words.",
                "required": [
                    "platform",
                    "state"
                ],
                "properties": {
                    "platform": {
                        "type": "string",
                        "description": "Which platform this listing is on."
                    },
                    "state": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "syncing",
                            "synced",
                            "failed",
                            "blocked",
                            "drifted"
                        ],
                        "description": "`blocked` is not a failure: nothing was attempted because the product is missing something this platform requires. `failed` means the platform refused a push and it will be retried. `drifted` means the platform's copy no longer matches ours \u2014 someone edited it there \u2014 and the shop's `source_of_truth` decides which copy wins."
                    },
                    "external_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The platform's own product id once it is live."
                    },
                    "problem": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why this platform will not show the product yet."
                    },
                    "review_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The platform's review verdict, where it has one."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When this listing last reached the platform."
                    },
                    "drift": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": {
                            "type": "object",
                            "properties": {
                                "ours": {
                                    "description": "The value we hold."
                                },
                                "theirs": {
                                    "description": "The value the platform holds."
                                }
                            }
                        },
                        "description": "Field by field, what differs, while the listing is `drifted`. Cleared once resolved."
                    },
                    "drift_detected_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the difference was last seen."
                    }
                }
            },
            "SyncProblem": {
                "type": "object",
                "description": "One thing that went wrong in a bulk write. `stage` is the part that matters: `ingest` means the row was not stored, anything else is the name of a platform that stored it but will not show it.",
                "required": [
                    "sku",
                    "stage",
                    "reason"
                ],
                "properties": {
                    "sku": {
                        "type": "string",
                        "description": "The product code, or the row number when the row had no code."
                    },
                    "stage": {
                        "type": "string",
                        "description": "`ingest`, or a platform name such as `whatsapp`."
                    },
                    "reason": {
                        "type": "string",
                        "description": "What is wrong, in words a merchant can act on."
                    }
                }
            },
            "CatalogueSync": {
                "type": "object",
                "description": "One bulk write and what became of every row in it. A sync is created by the batch endpoint and finishes in the background; poll it until `status` is `completed` or `failed`.",
                "required": [
                    "id",
                    "catalogue_id",
                    "status",
                    "received"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Sync id. Use it to read this report back."
                    },
                    "catalogue_id": {
                        "type": "integer",
                        "description": "The catalogue that was written to."
                    },
                    "source": {
                        "type": "string",
                        "enum": [
                            "api",
                            "feed",
                            "import",
                            "ui"
                        ],
                        "description": "Where the rows came from."
                    },
                    "mode": {
                        "type": "string",
                        "enum": [
                            "upsert",
                            "replace"
                        ],
                        "description": "`upsert` leaves products the payload did not mention alone; `replace` retires them."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "queued",
                            "running",
                            "completed",
                            "failed"
                        ],
                        "description": "Where the run has got to."
                    },
                    "idempotency_key": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The key the caller sent, if any."
                    },
                    "received": {
                        "type": "integer",
                        "description": "How many rows arrived."
                    },
                    "created": {
                        "type": "integer",
                        "description": "New products."
                    },
                    "updated": {
                        "type": "integer",
                        "description": "Products that changed."
                    },
                    "unchanged": {
                        "type": "integer",
                        "description": "Products that were already identical \u2014 nothing was re-published for these."
                    },
                    "rejected": {
                        "type": "integer",
                        "description": "Rows that could not be stored. Each one is in `problems`."
                    },
                    "retired": {
                        "type": "integer",
                        "description": "Products taken off sale, in `replace` mode only."
                    },
                    "platforms": {
                        "type": "object",
                        "additionalProperties": {
                            "type": "object",
                            "additionalProperties": {
                                "type": "integer"
                            }
                        },
                        "description": "Per platform, how many listings ended in each state \u2014 for example `{\"whatsapp\": {\"synced\": 1960, \"blocked\": 34}}`."
                    },
                    "problems": {
                        "type": "array",
                        "items": {
                            "$ref": "#/components/schemas/SyncProblem"
                        },
                        "description": "Up to 200 problems, ingest refusals first."
                    },
                    "problems_truncated": {
                        "type": "boolean",
                        "description": "True when there were more than 200 problems and the list was cut."
                    },
                    "error": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Set only when the run itself failed."
                    },
                    "started_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the run began."
                    },
                    "finished_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it finished."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was accepted."
                    }
                }
            },
            "StockLevel": {
                "type": "object",
                "description": "What we believe is on the shelf for one product. `available` is the number that decides whether a customer may buy: on hand, minus whatever pending orders are holding.",
                "required": [
                    "sku",
                    "available",
                    "tracked"
                ],
                "properties": {
                    "sku": {
                        "type": "string",
                        "description": "Your product code."
                    },
                    "inventory": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Units on hand. Null means this product is not counted at all, which is normal and not a fault."
                    },
                    "reserved": {
                        "type": "integer",
                        "description": "Units pending orders are holding."
                    },
                    "available": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "What a customer can still buy: `inventory` minus `reserved`."
                    },
                    "availability": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The word platforms show, derived from `available` unless you state one."
                    },
                    "tracked": {
                        "type": "boolean",
                        "description": "False when the product carries no count. Orders for it are never held back."
                    }
                }
            },
            "InventoryMovement": {
                "type": "object",
                "description": "One event that moved a stock count. The ledger is append-only: `inventory` and `reserved` on a product are roll-ups of these rows.",
                "required": [
                    "id",
                    "kind",
                    "quantity"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Movement id."
                    },
                    "kind": {
                        "type": "string",
                        "enum": [
                            "reserve",
                            "release",
                            "commit",
                            "adjust",
                            "sync"
                        ],
                        "description": "`reserve` a pending order holding units \u00b7 `release` that hold ending without a sale \u00b7 `commit` the sale happening \u00b7 `adjust` a person changing the count \u00b7 `sync` your own system stating the level."
                    },
                    "quantity": {
                        "type": "integer",
                        "description": "Signed. `reserve` and `release` move the held figure; the rest move the shelf count."
                    },
                    "on_hand_after": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Units on hand once this movement was applied."
                    },
                    "reserved_after": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Units held once this movement was applied."
                    },
                    "order_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The order that caused it, where there was one."
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why, for adjustments and releases."
                    },
                    "actor": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Who or what moved it \u2014 a person, `api`, `flow`, `ivr`."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it happened."
                    }
                }
            },
            "Webhook": {
                "type": "object",
                "description": "One receiver you registered. The signing secret is never included in a read \u2014 it is shown once on create and once on rotate.",
                "required": [
                    "id",
                    "url",
                    "events",
                    "is_active"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Webhook id."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Where we POST. Must be a public http(s) address."
                    },
                    "events": {
                        "type": "array",
                        "items": {
                            "type": "string"
                        },
                        "description": "The events this receiver gets."
                    },
                    "is_active": {
                        "type": "boolean",
                        "description": "Switched on by you."
                    },
                    "paused_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "Set when the platform paused it after too many failures in a row."
                    },
                    "paused_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why it was paused."
                    },
                    "consecutive_failures": {
                        "type": "integer",
                        "description": "Failures since the last successful delivery."
                    },
                    "last_delivered_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "The last time this receiver answered 2xx."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was registered."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it last changed."
                    }
                }
            },
            "WebhookDelivery": {
                "type": "object",
                "description": "One attempt-series to hand one event to one receiver. Created before the first POST, updated after every attempt.",
                "required": [
                    "id",
                    "delivery_uid",
                    "event",
                    "status",
                    "attempts"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Delivery id."
                    },
                    "delivery_uid": {
                        "type": "string",
                        "description": "The `X-Delivery-Id` the receiver saw."
                    },
                    "event": {
                        "type": "string",
                        "description": "Event name."
                    },
                    "status": {
                        "type": "string",
                        "enum": [
                            "pending",
                            "delivered",
                            "failed",
                            "skipped"
                        ],
                        "description": "`pending` is waiting for its next attempt. `failed` used every retry, or was refused with a 4xx. `skipped` was recorded while the endpoint was paused and never sent."
                    },
                    "attempts": {
                        "type": "integer",
                        "description": "How many times it was sent."
                    },
                    "next_attempt_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the next retry is due, while pending."
                    },
                    "last_attempt_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was last sent."
                    },
                    "delivered_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the receiver answered 2xx."
                    },
                    "response_code": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The last HTTP status the receiver answered."
                    },
                    "response_excerpt": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The first kilobyte of the last response body."
                    },
                    "error": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What went wrong, in words."
                    },
                    "replay_of_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "Set when this delivery is a replay of an earlier one."
                    },
                    "payload": {
                        "type": "object",
                        "description": "The body that was (or will be) sent."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When the event happened."
                    }
                }
            },
            "CatalogueFeed": {
                "type": "object",
                "description": "A product feed URL the shop pulls from on a schedule \u2014 Google Shopping or Meta product feed XML, or CSV/JSON. The connector for a store that cannot call this API but can publish a feed, which is every store platform.",
                "required": [
                    "id",
                    "catalogue_id",
                    "url",
                    "schedule",
                    "mode",
                    "is_active"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Feed id."
                    },
                    "catalogue_id": {
                        "type": "integer",
                        "description": "The shop it fills."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "Where the feed lives. Must be a public http(s) address; redirects are not followed."
                    },
                    "schedule": {
                        "type": "string",
                        "enum": [
                            "hourly",
                            "daily",
                            "manual"
                        ],
                        "description": "How often it is pulled. `manual` only on request."
                    },
                    "mode": {
                        "type": "string",
                        "enum": [
                            "upsert",
                            "replace"
                        ],
                        "description": "`replace` (the default) treats the feed as the whole catalogue and retires anything missing from it; `upsert` leaves unmentioned products alone."
                    },
                    "is_active": {
                        "type": "boolean",
                        "description": "Switched off automatically after ten failed pulls in a row; switch it back on once fixed."
                    },
                    "mapping": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "additionalProperties": {
                            "type": "integer"
                        },
                        "description": "Field key \u2192 column position. Guessed from the headers on the first pull and kept; send your own to correct it."
                    },
                    "last_pulled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was last fetched."
                    },
                    "next_pull_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it is next due."
                    },
                    "last_sync_id": {
                        "type": [
                            "integer",
                            "null"
                        ],
                        "description": "The sync report from the last pull \u2014 read it at `GET /catalogues/{catalogue}/syncs/{sync}`."
                    },
                    "last_error": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why the last pull failed, if it did."
                    },
                    "consecutive_failures": {
                        "type": "integer",
                        "description": "Failed pulls since the last good one."
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it was registered."
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "format": "date-time",
                        "description": "When it last changed."
                    }
                }
            },
            "Flow": {
                "type": "object",
                "description": "A message flow as the API reads it: the card, not the graph. Ask for the graph with include=definition on the single-flow read.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "The flow id."
                    },
                    "name": {
                        "type": "string",
                        "description": "What the workspace calls it."
                    },
                    "description": {
                        "type": "string",
                        "nullable": true,
                        "description": "The author's one-line description, when written."
                    },
                    "status": {
                        "type": "string",
                        "description": "draft, active, paused or archived. Only active flows answer customers.",
                        "enum": [
                            "draft",
                            "active",
                            "paused",
                            "archived"
                        ]
                    },
                    "priority": {
                        "type": "integer",
                        "description": "Trigger order: lower runs first when two live flows claim the same words."
                    },
                    "channels": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "description": "A channel key."
                        },
                        "description": "The channels it runs on. WhatsApp today."
                    },
                    "version": {
                        "type": "integer",
                        "description": "The DRAFT's optimistic-lock counter, incremented on every save. Send it back as expected_version when publishing."
                    },
                    "has_unpublished_changes": {
                        "type": "boolean",
                        "description": "Whether the draft differs from what is live."
                    },
                    "published_version": {
                        "type": "integer",
                        "nullable": true,
                        "description": "The number of the version customers get right now, or null when nothing is live."
                    },
                    "published_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "When the live version went live."
                    },
                    "node_count": {
                        "type": "integer",
                        "description": "How many steps the draft has."
                    },
                    "triggers": {
                        "type": "array",
                        "description": "What starts it.",
                        "items": {
                            "type": "object",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "description": "keyword, cold_start, no_session_fallback, choice_id, manual\u2026"
                                },
                                "value": {
                                    "type": "string",
                                    "nullable": true,
                                    "description": "The trigger's single value, when it has one."
                                },
                                "values": {
                                    "type": "array",
                                    "items": {
                                        "type": "string",
                                        "description": "One word."
                                    },
                                    "description": "The trigger's list of values, when it has several."
                                }
                            }
                        }
                    },
                    "keywords": {
                        "type": "array",
                        "items": {
                            "type": "string",
                            "description": "One keyword, lower-cased."
                        },
                        "description": "Every keyword the triggers claim, lower-cased."
                    },
                    "created_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the flow was created."
                    },
                    "updated_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When the draft last changed."
                    },
                    "definition": {
                        "type": "object",
                        "additionalProperties": true,
                        "description": "The draft graph (nodes, entryNodeId, defaults) with secrets redacted. Only with include=definition."
                    }
                }
            },
            "FlowSession": {
                "type": "object",
                "description": "One customer's run through a flow. Never carries variables; the single-session read does, for a key whose issuer may read them.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "The session id."
                    },
                    "flow_id": {
                        "type": "integer",
                        "description": "The flow it runs."
                    },
                    "flow_name": {
                        "type": "string",
                        "description": "The flow's name at read time."
                    },
                    "flow_version": {
                        "type": "integer",
                        "nullable": true,
                        "description": "The published version number the session is pinned to."
                    },
                    "conversation_id": {
                        "type": "integer",
                        "description": "The inbox conversation it lives in."
                    },
                    "contact_id": {
                        "type": "integer",
                        "nullable": true,
                        "description": "The contact record, when the conversation has one."
                    },
                    "contact_name": {
                        "type": "string",
                        "nullable": true,
                        "description": "The customer's name as the inbox knows it."
                    },
                    "contact_identifier": {
                        "type": "string",
                        "description": "The customer's phone (or handle) as stored on the conversation."
                    },
                    "trigger": {
                        "type": "string",
                        "description": "What started it: inbound, manual, api, schedule, automation\u2026"
                    },
                    "status": {
                        "type": "string",
                        "description": "running, waiting, completed, failed, expired, superseded_by_human or cancelled."
                    },
                    "outcome": {
                        "type": "string",
                        "description": "The eight-word reading of the status for people: in_progress, completed, abandoned, handed_over, failed, expired, cancelled, ended_by_operator."
                    },
                    "ended_reason": {
                        "type": "string",
                        "nullable": true,
                        "description": "The runtime's own word for why it ended, when it has."
                    },
                    "node_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "The step it is on, or ended on."
                    },
                    "awaiting": {
                        "type": "string",
                        "nullable": true,
                        "description": "What a waiting session waits for: text, choice, media, location, form, timer, payment\u2026"
                    },
                    "turns": {
                        "type": "integer",
                        "description": "How many customer turns it has taken."
                    },
                    "resume_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "When a timer wakes it, if one will."
                    },
                    "expires_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "When it lapses if the customer says nothing."
                    },
                    "started_at": {
                        "type": "string",
                        "format": "date-time",
                        "description": "When it started."
                    },
                    "ended_at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "When it ended, or null while live."
                    }
                }
            },
            "FlowSessionStep": {
                "type": "object",
                "description": "One row of a session's trace, redacted.",
                "properties": {
                    "seq": {
                        "type": "integer",
                        "description": "The step's sequence number within the session."
                    },
                    "node_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "The step of the flow."
                    },
                    "node_kind": {
                        "type": "string",
                        "nullable": true,
                        "description": "The step's kind (send_text, ask_text, collect_payment\u2026)."
                    },
                    "kind": {
                        "type": "string",
                        "description": "entered, emitted, awaited, resumed, branched, error, skipped or ended."
                    },
                    "payload": {
                        "type": "object",
                        "additionalProperties": true,
                        "nullable": true,
                        "description": "What the step recorded, with customer-typed values redacted."
                    },
                    "duration_ms": {
                        "type": "integer",
                        "nullable": true,
                        "description": "How long the step took."
                    },
                    "at": {
                        "type": "string",
                        "format": "date-time",
                        "nullable": true,
                        "description": "When it happened."
                    }
                }
            },
            "FlowIssue": {
                "type": "object",
                "description": "One finding from the validator or the go-live readiness check.",
                "properties": {
                    "level": {
                        "type": "string",
                        "description": "error (refuses a publish) or warning.",
                        "enum": [
                            "error",
                            "warning"
                        ]
                    },
                    "node_id": {
                        "type": "string",
                        "nullable": true,
                        "description": "The step the finding is about, when it is about one."
                    },
                    "field": {
                        "type": "string",
                        "nullable": true,
                        "description": "The step field, when the finding anchors to one."
                    },
                    "code": {
                        "type": "string",
                        "nullable": true,
                        "description": "A stable code; readiness:* names an account setting rather than the graph."
                    },
                    "message": {
                        "type": "string",
                        "description": "The finding in plain words."
                    },
                    "fix_href": {
                        "type": "string",
                        "nullable": true,
                        "description": "The page in the app that fixes a readiness finding."
                    }
                }
            },
            "MetaTemplateComponent": {
                "type": "object",
                "description": "One component in WhatsApp's own template shape \u2014 exactly what the Business Management API takes on `POST /{waba}/message_templates`. `type` is HEADER, BODY, FOOTER, BUTTONS, CAROUSEL or LIMITED_TIME_OFFER; the other keys are Meta's for that type (`format`, `text`, `example`, `buttons`, `cards`\u2026). See developers.facebook.com \u203a WhatsApp \u203a Message Templates \u203a Components.",
                "required": [
                    "type"
                ],
                "additionalProperties": true,
                "properties": {
                    "type": {
                        "type": "string",
                        "description": "Component type.",
                        "enum": [
                            "HEADER",
                            "BODY",
                            "FOOTER",
                            "BUTTONS",
                            "CAROUSEL",
                            "LIMITED_TIME_OFFER"
                        ]
                    },
                    "format": {
                        "type": "string",
                        "description": "HEADER only: `TEXT`, `IMAGE`, `VIDEO`, `DOCUMENT` or `LOCATION`."
                    },
                    "text": {
                        "type": "string",
                        "description": "HEADER (TEXT), BODY and FOOTER: the copy, with `{{1}}`-style or named placeholders."
                    },
                    "example": {
                        "type": "object",
                        "description": "Sample values for every placeholder, in the shape Meta wants: `{\"body_text\": [[\"Asha\", \"ORD-1042\"]]}`, `{\"header_text\": [\"Oda\"]}`, `{\"header_handle\": [\"<upload handle>\"]}`. Required by Meta whenever there is a placeholder or a media header.",
                        "additionalProperties": true
                    },
                    "buttons": {
                        "type": "array",
                        "description": "BUTTONS only: up to ten buttons \u2014 `QUICK_REPLY`, `URL`, `PHONE_NUMBER`, `COPY_CODE`, `FLOW`, `OTP`, `CATALOG`, `MPM`, `VOICE_CALL` \u2014 each in Meta's shape.",
                        "items": {
                            "type": "object",
                            "description": "One button.",
                            "additionalProperties": true
                        }
                    }
                }
            },
            "WhatsAppTemplateSubmission": {
                "type": "object",
                "description": "What happened when a template was submitted to Meta inside a request.",
                "properties": {
                    "submitted": {
                        "type": "boolean",
                        "description": "True when Meta accepted the submission in this request (read `whatsapp_status` and `whatsapp_template_id`)."
                    },
                    "queued": {
                        "type": "boolean",
                        "description": "True when Meta could not be reached and the submission was queued to retry; the template stays `pending` until it lands."
                    },
                    "message": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why it was not submitted, when it was not \u2014 Meta's own words for a refusal, or that it is queued."
                    }
                }
            },
            "WhatsAppTemplateDeployment": {
                "type": "object",
                "description": "One template's presence on one WhatsApp Business Account other than the one it was created on. Each account reviews it separately.",
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Deployment id."
                    },
                    "whatsapp_business_account_id": {
                        "type": "string",
                        "description": "The WhatsApp Business Account this deployment is on."
                    },
                    "whatsapp_template_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's id for the template on THAT account (each account gets its own)."
                    },
                    "whatsapp_status": {
                        "type": "string",
                        "description": "Meta's review status on that account.",
                        "enum": [
                            "pending",
                            "in_review",
                            "approved",
                            "rejected",
                            "disabled",
                            "paused"
                        ]
                    },
                    "rejection_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's reason when rejected on that account."
                    },
                    "quality_rating": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Quality score on that account: `GREEN`, `YELLOW`, `RED`, `UNKNOWN` or null."
                    },
                    "category": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The category Meta assigned on that account, when it differs from the authored one."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When Meta last told us about it on that account.",
                        "format": "date-time"
                    }
                }
            },
            "WhatsAppTemplateSummary": {
                "type": "object",
                "description": "A WhatsApp template as the list returns it.",
                "required": [
                    "id",
                    "name",
                    "language",
                    "category",
                    "status",
                    "whatsapp_status"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Local template id \u2014 what every other template endpoint takes in its path."
                    },
                    "name": {
                        "type": "string",
                        "description": "The machine handle Meta knows it by: lowercase letters, digits and underscores, e.g. `order_shipped`. This is `template.name` on `POST /api/v3/whatsapp/send`.",
                        "pattern": "^[a-z0-9_]{1,512}$"
                    },
                    "display_name": {
                        "type": "string",
                        "description": "What a person on the dashboard calls it."
                    },
                    "language": {
                        "type": "string",
                        "description": "Language code of the copy, e.g. `sw`, `en`, `en_US`. One template per language."
                    },
                    "category": {
                        "type": "string",
                        "description": "Meta's category. `utility` for transactional notices, `marketing` for promotions, `authentication` for one-time codes. Meta may reclassify a template during review.",
                        "enum": [
                            "marketing",
                            "utility",
                            "authentication"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "Its state on this platform, before Meta gets a say. Only an `active` one can be sent; `archived` rows are hidden from the default list.",
                        "enum": [
                            "draft",
                            "active",
                            "archived"
                        ]
                    },
                    "whatsapp_status": {
                        "type": "string",
                        "description": "Where Meta's review got to. `pending` = not yet submitted (or a queued submission); `in_review` = Meta has it; `approved` = usable; `rejected` = see `rejection_reason`; `paused` / `disabled` = Meta stopped it for quality.",
                        "enum": [
                            "pending",
                            "in_review",
                            "approved",
                            "rejected",
                            "disabled",
                            "paused"
                        ]
                    },
                    "approved": {
                        "type": "boolean",
                        "description": "True when `whatsapp_status` is `approved`."
                    },
                    "sendable": {
                        "type": "boolean",
                        "description": "True when it can be sent right now: `status` active AND approved by Meta."
                    },
                    "rejection_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's reason, when `whatsapp_status` is `rejected` \u2014 a review verdict such as `INVALID_FORMAT`, or the refusal it gave the submission itself (a name clash, a body that starts with a variable). Null otherwise."
                    },
                    "whatsapp_business_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The WhatsApp Business Account (WABA) id it lives on. `GET /api/v3/whatsapp/accounts` lists them."
                    },
                    "whatsapp_template_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's own id for the template on that account. Null until a submission has been accepted."
                    },
                    "quality_rating": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's quality score on this account \u2014 `GREEN`, `YELLOW`, `RED` or `UNKNOWN` \u2014 once approved and in use. Null before that."
                    },
                    "parameter_format": {
                        "type": "string",
                        "description": "How variables are written: `POSITIONAL` (`{{1}}`, `{{2}}`) or `NAMED` (`{{order_id}}`).",
                        "enum": [
                            "POSITIONAL",
                            "NAMED"
                        ]
                    },
                    "variables": {
                        "type": "array",
                        "description": "The placeholders the header and body carry, in order \u2014 what a send must supply one value each for.",
                        "items": {
                            "type": "string",
                            "description": "A placeholder: `1`, `2`\u2026 or a name."
                        }
                    },
                    "body": {
                        "type": "string",
                        "description": "The body copy with its placeholders. The full component tree is on the single-template read."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When Meta last told us anything about this template (submission, poll, webhook or refresh).",
                        "format": "date-time"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the row was created here.",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the row last changed here.",
                        "format": "date-time"
                    }
                }
            },
            "WhatsAppTemplate": {
                "type": "object",
                "description": "A WhatsApp template in full: the summary fields plus its content in both shapes and its deployments.",
                "required": [
                    "id",
                    "name",
                    "language",
                    "category",
                    "status",
                    "whatsapp_status",
                    "components",
                    "deployments"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Local template id \u2014 what every other template endpoint takes in its path."
                    },
                    "name": {
                        "type": "string",
                        "description": "The machine handle Meta knows it by: lowercase letters, digits and underscores, e.g. `order_shipped`. This is `template.name` on `POST /api/v3/whatsapp/send`.",
                        "pattern": "^[a-z0-9_]{1,512}$"
                    },
                    "display_name": {
                        "type": "string",
                        "description": "What a person on the dashboard calls it."
                    },
                    "language": {
                        "type": "string",
                        "description": "Language code of the copy, e.g. `sw`, `en`, `en_US`. One template per language."
                    },
                    "category": {
                        "type": "string",
                        "description": "Meta's category. `utility` for transactional notices, `marketing` for promotions, `authentication` for one-time codes. Meta may reclassify a template during review.",
                        "enum": [
                            "marketing",
                            "utility",
                            "authentication"
                        ]
                    },
                    "status": {
                        "type": "string",
                        "description": "Its state on this platform, before Meta gets a say. Only an `active` one can be sent; `archived` rows are hidden from the default list.",
                        "enum": [
                            "draft",
                            "active",
                            "archived"
                        ]
                    },
                    "whatsapp_status": {
                        "type": "string",
                        "description": "Where Meta's review got to. `pending` = not yet submitted (or a queued submission); `in_review` = Meta has it; `approved` = usable; `rejected` = see `rejection_reason`; `paused` / `disabled` = Meta stopped it for quality.",
                        "enum": [
                            "pending",
                            "in_review",
                            "approved",
                            "rejected",
                            "disabled",
                            "paused"
                        ]
                    },
                    "approved": {
                        "type": "boolean",
                        "description": "True when `whatsapp_status` is `approved`."
                    },
                    "sendable": {
                        "type": "boolean",
                        "description": "True when it can be sent right now: `status` active AND approved by Meta."
                    },
                    "rejection_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's reason, when `whatsapp_status` is `rejected` \u2014 a review verdict such as `INVALID_FORMAT`, or the refusal it gave the submission itself (a name clash, a body that starts with a variable). Null otherwise."
                    },
                    "whatsapp_business_account_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The WhatsApp Business Account (WABA) id it lives on. `GET /api/v3/whatsapp/accounts` lists them."
                    },
                    "whatsapp_template_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's own id for the template on that account. Null until a submission has been accepted."
                    },
                    "quality_rating": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Meta's quality score on this account \u2014 `GREEN`, `YELLOW`, `RED` or `UNKNOWN` \u2014 once approved and in use. Null before that."
                    },
                    "parameter_format": {
                        "type": "string",
                        "description": "How variables are written: `POSITIONAL` (`{{1}}`, `{{2}}`) or `NAMED` (`{{order_id}}`).",
                        "enum": [
                            "POSITIONAL",
                            "NAMED"
                        ]
                    },
                    "variables": {
                        "type": "array",
                        "description": "The placeholders the header and body carry, in order \u2014 what a send must supply one value each for.",
                        "items": {
                            "type": "string",
                            "description": "A placeholder: `1`, `2`\u2026 or a name."
                        }
                    },
                    "body": {
                        "type": "string",
                        "description": "The body copy with its placeholders. The full component tree is on the single-template read."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When Meta last told us anything about this template (submission, poll, webhook or refresh).",
                        "format": "date-time"
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the row was created here.",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the row last changed here.",
                        "format": "date-time"
                    },
                    "header_type": {
                        "type": "string",
                        "description": "The header kind: `none`, `text`, `image`, `video` or `document`.",
                        "enum": [
                            "none",
                            "text",
                            "image",
                            "video",
                            "document"
                        ]
                    },
                    "header_text": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The header copy when `header_type` is `text`."
                    },
                    "footer": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The footer copy, up to 60 characters."
                    },
                    "buttons": {
                        "type": "array",
                        "description": "The flat-field buttons, when the template was described that way. `components` is the complete picture either way.",
                        "items": {
                            "type": "object",
                            "description": "One button: `type` (quick_reply, url, phone_number), `text`, and `url` or `phone_number`.",
                            "additionalProperties": true
                        }
                    },
                    "components": {
                        "type": "array",
                        "description": "The template in Meta's `components[]` shape \u2014 what is (or would be) submitted for review. Post it back unchanged to create a twin, or edit and PATCH it.",
                        "items": {
                            "$ref": "#/components/schemas/MetaTemplateComponent"
                        }
                    },
                    "deployments": {
                        "type": "array",
                        "description": "Its review status on every OTHER WhatsApp Business Account it has been deployed to (`POST \u2026/deployments`). Empty until deployed.",
                        "items": {
                            "$ref": "#/components/schemas/WhatsAppTemplateDeployment"
                        }
                    },
                    "submission": {
                        "$ref": "#/components/schemas/WhatsAppTemplateSubmission",
                        "description": "Only on responses that submitted to Meta (create, PATCH with content, submit): what happened."
                    },
                    "refresh": {
                        "type": "object",
                        "description": "Only on `POST \u2026/refresh`: `found_on_whatsapp` says whether Meta has the template, `message` explains when it does not.",
                        "properties": {
                            "found_on_whatsapp": {
                                "type": "boolean",
                                "description": "False when Meta has no template of this name and language on the account; the row is left as it was."
                            },
                            "message": {
                                "type": [
                                    "string",
                                    "null"
                                ],
                                "description": "Explanation when not found."
                            }
                        }
                    }
                }
            },
            "WhatsAppTemplateWriteRequest": {
                "type": "object",
                "description": "What `POST /api/v3/whatsapp/templates` takes, and what `PATCH` accepts a subset of.",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The machine handle: lowercase letters, digits and underscores, at most 512. Meta refuses anything else, so this API does too rather than silently changing it. Cannot change once created.",
                        "pattern": "^[a-z0-9_]{1,512}$",
                        "maxLength": 512
                    },
                    "language": {
                        "type": "string",
                        "description": "Language code, e.g. `sw`, `en`, `en_US`. Cannot change once created \u2014 another language is another template.",
                        "maxLength": 16
                    },
                    "category": {
                        "type": "string",
                        "description": "Meta category.",
                        "enum": [
                            "marketing",
                            "utility",
                            "authentication"
                        ]
                    },
                    "display_name": {
                        "type": "string",
                        "description": "A human name for the dashboard. Defaults to the name, title-cased.",
                        "maxLength": 255
                    },
                    "waba_id": {
                        "type": "string",
                        "description": "Which WhatsApp Business Account to create it on. Required only when the workspace has more than one; `GET /api/v3/whatsapp/accounts` lists them (`waba_id`). Cannot change once created \u2014 use deployments.",
                        "maxLength": 64
                    },
                    "status": {
                        "type": "string",
                        "description": "Local state. Defaults to `active`. `archived` hides it; `draft` keeps it out of the send picker.",
                        "enum": [
                            "draft",
                            "active",
                            "archived"
                        ]
                    },
                    "parameter_format": {
                        "type": "string",
                        "description": "How placeholders are written in the copy. Defaults to `POSITIONAL`.",
                        "enum": [
                            "POSITIONAL",
                            "NAMED"
                        ]
                    },
                    "submit": {
                        "type": "boolean",
                        "description": "Whether to submit to Meta in this request. Defaults to true. On PATCH, only a content change submits.",
                        "default": true
                    },
                    "components": {
                        "type": "array",
                        "description": "The content in WhatsApp's own `components[]` shape \u2014 one entry per HEADER, BODY, FOOTER, BUTTONS, CAROUSEL or LIMITED_TIME_OFFER, with Meta's `example` values. Covers everything Meta supports. Wins over the flat fields when both are sent; on PATCH, replaces the whole content.",
                        "items": {
                            "$ref": "#/components/schemas/MetaTemplateComponent"
                        },
                        "minItems": 1,
                        "maxItems": 12
                    },
                    "body": {
                        "type": "string",
                        "description": "Flat description: the body copy, up to 1,024 characters, with `{{1}}`-style placeholders. Required unless `components` is given. On PATCH, sending `body` re-describes the whole content with the flat fields.",
                        "maxLength": 1024
                    },
                    "header_type": {
                        "type": "string",
                        "description": "Flat description: header kind \u2014 `none` or `text` (with `header_text`). A media header (image, video, document) needs the sample handle Meta issues on upload, which only `components` can carry (`{\"type\":\"HEADER\",\"format\":\"IMAGE\",\"example\":{\"header_handle\":[\"\u2026\"]}}`).",
                        "enum": [
                            "none",
                            "text"
                        ]
                    },
                    "header_text": {
                        "type": "string",
                        "description": "Flat description: a one-line text header, up to 60 characters, one placeholder at most. Implies `header_type: text`.",
                        "maxLength": 60
                    },
                    "footer": {
                        "type": "string",
                        "description": "Flat description: footer copy, up to 60 characters, no placeholders.",
                        "maxLength": 60
                    },
                    "buttons": {
                        "type": "array",
                        "description": "Flat description: up to ten buttons of type `quick_reply`, `url` (with `url`; a `{{1}}` at its end makes it dynamic and then `example` is required) or `phone_number` (with `phone_number`). For copy-code, flow or catalogue buttons use `components`.",
                        "items": {
                            "type": "object",
                            "description": "One button.",
                            "properties": {
                                "type": {
                                    "type": "string",
                                    "description": "Button type.",
                                    "enum": [
                                        "quick_reply",
                                        "url",
                                        "phone_number"
                                    ]
                                },
                                "text": {
                                    "type": "string",
                                    "description": "Button label, up to 25 characters.",
                                    "maxLength": 25
                                },
                                "url": {
                                    "type": "string",
                                    "description": "For `url`: the link, optionally ending in `{{1}}`."
                                },
                                "phone_number": {
                                    "type": "string",
                                    "description": "For `phone_number`: the number to dial, in E.164."
                                },
                                "example": {
                                    "type": "string",
                                    "description": "For a dynamic `url`: a sample value for its `{{1}}`."
                                }
                            }
                        },
                        "maxItems": 10
                    },
                    "variable_samples": {
                        "type": "object",
                        "description": "Flat description: a sample value per placeholder, keyed by the placeholder (`\"1\"`, `\"2\"` or a name). Meta requires a sample for every placeholder; missing ones get a generic sample, which Meta may reject for marketing copy.",
                        "additionalProperties": {
                            "type": "string",
                            "description": "The sample value."
                        }
                    }
                }
            },
            "WhatsAppAccount": {
                "type": "object",
                "description": "A WhatsApp Business Account (WABA) connected to this workspace, with its numbers. `phone_numbers[].id` is what `sender_id` (sends, groups) and `from` (catalogue sends, flow sessions) take; `waba_id` is what the templates endpoints take.",
                "required": [
                    "waba_id",
                    "is_active",
                    "phone_numbers"
                ],
                "properties": {
                    "waba_id": {
                        "type": "string",
                        "description": "The WhatsApp Business Account id \u2014 `waba_id` on the templates endpoints."
                    },
                    "name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The business name Meta shows for the account."
                    },
                    "is_active": {
                        "type": "boolean",
                        "description": "False once the account has been disconnected; kept so its templates and catalogues still resolve."
                    },
                    "is_default": {
                        "type": "boolean",
                        "description": "True for the account a send without `sender_id` goes out from."
                    },
                    "phone_numbers": {
                        "type": "array",
                        "description": "The business phone numbers on the account.",
                        "items": {
                            "type": "object",
                            "description": "One number.",
                            "properties": {
                                "id": {
                                    "type": "string",
                                    "description": "Meta's phone_number_id \u2014 what `sender_id` and `from` take. The number itself (`phone_number` or `display`) is accepted there too."
                                },
                                "phone_number": {
                                    "type": [
                                        "string",
                                        "null"
                                    ],
                                    "description": "The number in E.164, when the connection recorded it."
                                },
                                "display": {
                                    "type": "string",
                                    "description": "The number as displayed."
                                },
                                "is_default": {
                                    "type": "boolean",
                                    "description": "True for the number a send without `sender_id` goes out from."
                                }
                            }
                        }
                    },
                    "quality_rating": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The account's quality rating from Meta, when known."
                    },
                    "messaging_tier": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The account's messaging limit tier from Meta, when known."
                    },
                    "templates_count": {
                        "type": "integer",
                        "description": "How many templates live on this account here."
                    },
                    "catalogues_count": {
                        "type": "integer",
                        "description": "How many catalogues are connected to this account."
                    },
                    "last_synced_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the account details were last refreshed from the connection.",
                        "format": "date-time"
                    }
                }
            },
            "SmsSender": {
                "type": "object",
                "description": "One identity an SMS may go out as. `value` is exactly what `sender_id` takes on `/sms/send` and `/sms/campaign`.",
                "required": [
                    "type",
                    "value",
                    "label",
                    "status"
                ],
                "properties": {
                    "type": {
                        "type": "string",
                        "description": "What kind of identity: an approved alphanumeric sender ID, one of the workspace's own SMS-capable numbers, or an active short code.",
                        "enum": [
                            "sender_id",
                            "phone_number",
                            "short_code"
                        ]
                    },
                    "value": {
                        "type": "string",
                        "description": "Pass this as `sender_id`."
                    },
                    "label": {
                        "type": "string",
                        "description": "A human name for it: the sender ID itself, the number's label, or the short code's description."
                    },
                    "status": {
                        "type": "string",
                        "description": "`approved` for a sender ID, `active` for a number or short code \u2014 only usable identities are listed.",
                        "enum": [
                            "approved",
                            "active"
                        ]
                    }
                }
            },
            "ContactGroupField": {
                "type": "object",
                "description": "One extra field a group declares. Declaring it is what makes the dashboard show a column for it; a contact may still be given an undeclared key.",
                "required": [
                    "key"
                ],
                "properties": {
                    "key": {
                        "type": "string",
                        "description": "The key a contact carries it under, and what a campaign addresses as `{{cf:key}}`. Letters, digits, `_`, `.` and `-`.",
                        "maxLength": 64,
                        "pattern": "^[A-Za-z0-9_.-]+$"
                    },
                    "label": {
                        "type": "string",
                        "description": "What a person reading the dashboard sees. Defaults to the key.",
                        "maxLength": 120
                    },
                    "type": {
                        "type": "string",
                        "description": "How the dashboard renders and validates it. Defaults to `text`.",
                        "enum": [
                            "text",
                            "number",
                            "email",
                            "date",
                            "select"
                        ]
                    }
                }
            },
            "ContactGroup": {
                "type": "object",
                "description": "A contact group: the list every contact belongs to, and the small schema of extra fields its contacts may carry. Its `id` or `uid` is the `{group_id}` every contact path takes.",
                "required": [
                    "id",
                    "uid",
                    "name",
                    "status",
                    "contacts_count",
                    "subscribed_count",
                    "custom_fields"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "Numeric id. Accepted anywhere a group is named."
                    },
                    "uid": {
                        "type": "string",
                        "description": "Stable UUID. Accepted anywhere the numeric id is, and the one to store.",
                        "format": "uuid"
                    },
                    "name": {
                        "type": "string",
                        "description": "What the group is called."
                    },
                    "status": {
                        "type": "string",
                        "description": "`active`, or `inactive` for a group kept for its history but no longer in use.",
                        "enum": [
                            "active",
                            "inactive"
                        ]
                    },
                    "contacts_count": {
                        "type": "integer",
                        "description": "How many people are in it, subscribed or not."
                    },
                    "subscribed_count": {
                        "type": "integer",
                        "description": "How many of those still accept messages \u2014 the number a campaign would actually reach."
                    },
                    "custom_fields": {
                        "type": "array",
                        "description": "The extra fields this group declares.",
                        "items": {
                            "$ref": "#/components/schemas/ContactGroupField"
                        }
                    },
                    "created_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the group was created.",
                        "format": "date-time"
                    },
                    "updated_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it last changed.",
                        "format": "date-time"
                    }
                }
            },
            "ContactGroupWriteRequest": {
                "type": "object",
                "description": "What `POST /api/v3/contact-groups` takes, and what `PATCH` accepts a subset of.",
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "What to call the group.",
                        "maxLength": 160
                    },
                    "status": {
                        "type": "string",
                        "description": "Defaults to `active` on create.",
                        "enum": [
                            "active",
                            "inactive"
                        ]
                    },
                    "custom_fields": {
                        "type": "array",
                        "description": "The extra fields contacts in this group may carry. On PATCH this REPLACES the declaration \u2014 a schema is not a thing to merge \u2014 and removing a field does not touch values already stored on contacts, they are simply no longer declared.",
                        "items": {
                            "$ref": "#/components/schemas/ContactGroupField"
                        },
                        "maxItems": 50
                    }
                }
            },
            "ContactBatchResult": {
                "type": "object",
                "description": "What one row of a bulk import did.",
                "properties": {
                    "index": {
                        "type": "integer",
                        "description": "The row's position in the `contacts` array you sent."
                    },
                    "uid": {
                        "type": "string",
                        "description": "The contact it created or matched."
                    },
                    "outcome": {
                        "type": "string",
                        "description": "`created`, `updated`, or `skipped` when `skip_existing` was set and the number was already there.",
                        "enum": [
                            "created",
                            "updated",
                            "skipped"
                        ]
                    }
                }
            },
            "ContactWriteRequest": {
                "type": "object",
                "description": "A contact. Every field that is not one of the reserved names below is stored as a custom field, at the TOP level of the object \u2014 do not wrap them in `custom_field_values`, which would store that wrapper as a key.",
                "additionalProperties": true,
                "properties": {
                    "PHONE": {
                        "type": "string",
                        "description": "The number. Required on create; on PATCH send it only when the number itself is changing. `phone_number` is an alias and `PHONE` wins if both are sent.",
                        "maxLength": 64
                    },
                    "country_code": {
                        "type": "string",
                        "description": "The country code to split off, e.g. `255`. Send it explicitly: a `+255\u2026` prefix alone is not inferred.",
                        "maxLength": 8
                    },
                    "name": {
                        "type": "string",
                        "description": "The person's name. `NAME`, or `FIRST_NAME` + `LAST_NAME`, are accepted instead. On create, a contact with no name given is named after their number; on PATCH, a name that is not sent is left alone.",
                        "maxLength": 160
                    },
                    "is_subscribed": {
                        "type": "boolean",
                        "description": "Whether they accept messages. Defaults true on create; left alone on PATCH when not sent."
                    }
                }
            },
            "PostTarget": {
                "type": "object",
                "description": "One account a post goes to, and how far it got there.",
                "required": [
                    "id",
                    "social_account_id",
                    "platform",
                    "status"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "The target row id, for retry/delete-on-platform in the app."
                    },
                    "social_account_id": {
                        "type": "integer",
                        "description": "The connected social account."
                    },
                    "platform": {
                        "type": "string",
                        "description": "facebook, instagram, tiktok, youtube or linkedin."
                    },
                    "status": {
                        "type": "string",
                        "description": "pending, publishing, published, failed, needs_reconnect or cancelled.",
                        "enum": [
                            "pending",
                            "publishing",
                            "published",
                            "failed",
                            "needs_reconnect",
                            "cancelled"
                        ]
                    },
                    "provider_post_id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The platform's own id for the post once published."
                    },
                    "permalink": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The public link once published."
                    },
                    "error_message": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why this target failed, in the platform's words."
                    },
                    "published_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it went up on this platform, ISO-8601."
                    }
                }
            },
            "PostMediaItem": {
                "type": "object",
                "description": "A media asset attached to a post.",
                "required": [
                    "asset"
                ],
                "properties": {
                    "asset": {
                        "type": "string",
                        "description": "The media asset uid, from POST /api/v3/posts/media."
                    },
                    "alt_text": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Alt text for the picture, where the platform supports it."
                    }
                }
            },
            "PostContent": {
                "type": "object",
                "description": "What is posted.",
                "required": [
                    "body",
                    "media"
                ],
                "properties": {
                    "body": {
                        "type": "string",
                        "description": "The text."
                    },
                    "media": {
                        "type": "array",
                        "description": "Attached media, in order.",
                        "items": {
                            "$ref": "#/components/schemas/PostMediaItem",
                            "description": "An attached media item."
                        }
                    },
                    "first_comment": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A comment posted under the post right after it goes up, where the platform allows it."
                    }
                }
            },
            "Post": {
                "type": "object",
                "description": "A publication: one piece of content going to one or more accounts.",
                "required": [
                    "uid",
                    "status",
                    "targets",
                    "content"
                ],
                "properties": {
                    "uid": {
                        "type": "string",
                        "description": "The post id (pub_\u2026)."
                    },
                    "status": {
                        "type": "string",
                        "description": "draft, scheduled, publishing, published, partially_published, failed or cancelled.",
                        "enum": [
                            "draft",
                            "scheduled",
                            "publishing",
                            "published",
                            "partially_published",
                            "failed",
                            "cancelled"
                        ]
                    },
                    "schedule_status": {
                        "type": "string",
                        "description": "The scheduler's own state: none, pending, claimed, dispatched, processed."
                    },
                    "scheduled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it goes (or went) out, ISO-8601."
                    },
                    "scheduled_tz": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The timezone the schedule was given in."
                    },
                    "published_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the first target went up."
                    },
                    "completed_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When every target settled."
                    },
                    "created_at": {
                        "type": "string",
                        "description": "When the post was created here, ISO-8601."
                    },
                    "updated_at": {
                        "type": "string",
                        "description": "Last change, ISO-8601."
                    },
                    "created_by": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Who created it: {id, name}."
                    },
                    "approved_by": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Who approved sending it: {id, name}."
                    },
                    "approved_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it was approved for sending."
                    },
                    "content": {
                        "$ref": "#/components/schemas/PostContent",
                        "description": "What is posted: body, media, first comment."
                    },
                    "overrides": {
                        "type": "object",
                        "description": "Per-account content overrides, keyed by social account id."
                    },
                    "options": {
                        "type": "object",
                        "description": "Per-platform options, keyed by platform (YouTube title/privacy, TikTok privacy_level\u2026)."
                    },
                    "options_overrides": {
                        "type": "object",
                        "description": "Per-account option overrides, keyed by social account id."
                    },
                    "targets": {
                        "type": "array",
                        "description": "One row per account the post goes to.",
                        "items": {
                            "$ref": "#/components/schemas/PostTarget",
                            "description": "One target."
                        }
                    },
                    "media": {
                        "type": "array",
                        "description": "The attached assets as stored (uid, kind, url, status, probe).",
                        "items": {
                            "type": "object",
                            "description": "A stored media asset."
                        }
                    },
                    "verification": {
                        "type": "object",
                        "description": "The pre-flight: errors that block sending and warnings a person may accept by code."
                    },
                    "notes": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Internal notes."
                    },
                    "idempotency_key": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The key given on create, if any."
                    },
                    "approval": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "A pending approval hand-off (id, state, mode, at, requested_by, requested_at, expires_at, href), or null."
                    }
                }
            },
            "PostSummary": {
                "type": "object",
                "description": "A post as the list shows it.",
                "required": [
                    "uid",
                    "status",
                    "platforms"
                ],
                "properties": {
                    "uid": {
                        "type": "string",
                        "description": "The post id (pub_\u2026)."
                    },
                    "status": {
                        "type": "string",
                        "description": "draft, scheduled, publishing, published, partially_published, failed or cancelled."
                    },
                    "schedule_status": {
                        "type": "string",
                        "description": "The scheduler's own state."
                    },
                    "scheduled_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it goes out, ISO-8601."
                    },
                    "scheduled_tz": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Timezone of the schedule."
                    },
                    "published_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When it went out, ISO-8601."
                    },
                    "created_at": {
                        "type": "string",
                        "description": "When it was created, ISO-8601."
                    },
                    "body_excerpt": {
                        "type": "string",
                        "description": "The first 120 characters of the text."
                    },
                    "thumbnail": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "A thumbnail of the first media item ({url, kind}), or null."
                    },
                    "media_count": {
                        "type": "integer",
                        "description": "How many media items are attached."
                    },
                    "media_kind": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "image, video or mixed, or null for text only."
                    },
                    "platforms": {
                        "type": "array",
                        "description": "The platforms it goes to.",
                        "items": {
                            "type": "string",
                            "description": "A platform key."
                        }
                    },
                    "targets_summary": {
                        "type": "object",
                        "description": "Counts of targets by state."
                    },
                    "targets": {
                        "type": "array",
                        "description": "Per-target state, abbreviated.",
                        "items": {
                            "type": "object",
                            "description": "A target as the list shows it."
                        }
                    },
                    "comments_href": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A link into the comments desk for this post, once it has one."
                    },
                    "metrics": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "Views, likes, comments, shares, reach from the nightly insights sync."
                    },
                    "comment_count": {
                        "type": "integer",
                        "description": "Comments received across targets."
                    },
                    "unanswered_count": {
                        "type": "integer",
                        "description": "Comments still needing an answer."
                    },
                    "created_by": {
                        "type": "object",
                        "description": "Who created it: {id, name}."
                    }
                }
            },
            "PostAccount": {
                "type": "object",
                "description": "A connected account a post can go to, with its publishing state.",
                "required": [
                    "id",
                    "platform",
                    "name",
                    "publish_enabled",
                    "publish_tier"
                ],
                "properties": {
                    "id": {
                        "type": "integer",
                        "description": "The social account id to pass as a target."
                    },
                    "platform": {
                        "type": "string",
                        "description": "facebook, instagram, tiktok, youtube or linkedin."
                    },
                    "name": {
                        "type": "string",
                        "description": "The account's name."
                    },
                    "handle": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Its @handle, when it has one."
                    },
                    "avatar": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Profile picture URL."
                    },
                    "publish_enabled": {
                        "type": "boolean",
                        "description": "Whether the account holds the publishing permission."
                    },
                    "needs_reconnect": {
                        "type": "boolean",
                        "description": "Whether the login has expired or been revoked."
                    },
                    "needs_reconnect_reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why, when it does."
                    },
                    "reason_text": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "One sentence on why it cannot publish, when it cannot."
                    },
                    "publish_tier": {
                        "type": "string",
                        "description": "ready, needs_permission, waiting (platform review pending) or blocked."
                    },
                    "publish_state": {
                        "type": "string",
                        "description": "The raw grant state: on, available, missing, gated, off, not_applicable."
                    },
                    "publish_gate": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the workspace is waiting on, when gated."
                    },
                    "publish_defaults": {
                        "type": "object",
                        "description": "The options this account fills in by itself on a new post."
                    },
                    "insights_status": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "What the nightly metrics sync found: ok, scope_missing, unavailable, error."
                    },
                    "author_kind": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "LinkedIn only: person or organization."
                    },
                    "token_expires_at": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "When the login expires, if it does."
                    },
                    "health": {
                        "type": "object",
                        "description": "What the last health probe recorded."
                    }
                }
            },
            "PostMediaAsset": {
                "type": "object",
                "description": "A media file the business uploaded for posts.",
                "required": [
                    "uid",
                    "kind",
                    "status"
                ],
                "properties": {
                    "uid": {
                        "type": "string",
                        "description": "The asset uid to put in content.media."
                    },
                    "kind": {
                        "type": "string",
                        "description": "image or video."
                    },
                    "mime_type": {
                        "type": "string",
                        "description": "The served MIME type."
                    },
                    "original_name": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "The filename as uploaded."
                    },
                    "size": {
                        "type": "integer",
                        "description": "Bytes."
                    },
                    "status": {
                        "type": "string",
                        "description": "processing until probed and converted, then ready; failed when the file could not be used."
                    },
                    "url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Where the served copy lives."
                    },
                    "thumbnail_url": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A poster frame for a video."
                    },
                    "probe": {
                        "type": [
                            "object",
                            "null"
                        ],
                        "description": "width, height, duration_ms, aspect, has_audio once known."
                    },
                    "warnings": {
                        "type": "array",
                        "description": "Anything the pipeline noticed (a resize, a re-encode).",
                        "items": {
                            "type": "string",
                            "description": "A warning code."
                        }
                    }
                }
            },
            "PostWriteRequest": {
                "type": "object",
                "description": "A post to create or replace.",
                "required": [
                    "targets",
                    "content"
                ],
                "properties": {
                    "targets": {
                        "type": "array",
                        "description": "Social account ids the post goes to (GET /api/v3/posts/accounts).",
                        "items": {
                            "type": "integer",
                            "description": "A social account id."
                        },
                        "minItems": 1,
                        "maxItems": 50
                    },
                    "content": {
                        "$ref": "#/components/schemas/PostContent",
                        "description": "What to post: body, media, first comment."
                    },
                    "overrides": {
                        "type": "object",
                        "description": "Per-account content overrides keyed by social account id: {body, media, first_comment}."
                    },
                    "options": {
                        "type": "object",
                        "description": "Per-platform options keyed by platform, validated against that platform's schema (YouTube: title, privacy, made_for_kids\u2026; TikTok: privacy_level\u2026). Omitted keys take the account's saved defaults."
                    },
                    "options_overrides": {
                        "type": "object",
                        "description": "Per-account option overrides keyed by social account id."
                    },
                    "schedule": {
                        "type": "object",
                        "description": "What to do once saved.",
                        "properties": {
                            "mode": {
                                "type": "string",
                                "description": "draft (default) saves only; now publishes at once; later schedules at `at`.",
                                "enum": [
                                    "draft",
                                    "now",
                                    "later"
                                ]
                            },
                            "at": {
                                "type": "string",
                                "description": "When to publish, ISO-8601, for later."
                            },
                            "tz": {
                                "type": "string",
                                "description": "IANA timezone for `at`."
                            }
                        }
                    },
                    "accept_warnings": {
                        "type": "array",
                        "description": "Pre-flight warning codes the caller accepts, for now/later.",
                        "items": {
                            "type": "string",
                            "description": "A warning code from verification."
                        }
                    },
                    "idempotency_key": {
                        "type": "string",
                        "description": "Any string of yours; the same key again returns the same post (200) instead of creating another."
                    },
                    "notes": {
                        "type": "string",
                        "description": "An internal note on the post."
                    }
                }
            },
            "PostPage": {
                "type": "object",
                "description": "A page of posts.",
                "required": [
                    "items",
                    "pagination"
                ],
                "properties": {
                    "items": {
                        "type": "array",
                        "description": "The posts, scheduled first then newest.",
                        "items": {
                            "$ref": "#/components/schemas/PostSummary",
                            "description": "A post as the list shows it."
                        }
                    },
                    "pagination": {
                        "$ref": "#/components/schemas/Pagination",
                        "description": "Page state."
                    }
                }
            },
            "JsonRpcRequest": {
                "type": "object",
                "title": "JSON-RPC 2.0 request",
                "description": "The body of every MCP call. The **operation is `method`**, not the URL: one server answers `initialize`, `tools/list`, `tools/call`, `ping` and the notification methods on the same path.\n\nA notification (a request with no `id`) is answered with `202 Accepted` and an empty body.",
                "required": [
                    "jsonrpc",
                    "method"
                ],
                "properties": {
                    "jsonrpc": {
                        "type": "string",
                        "const": "2.0",
                        "description": "Always the string \"2.0\"."
                    },
                    "id": {
                        "type": [
                            "string",
                            "integer"
                        ],
                        "description": "Correlates the response with this request. Omit it to send a notification, which is acknowledged rather than answered."
                    },
                    "method": {
                        "type": "string",
                        "description": "The JSON-RPC method. `initialize` opens the session, `tools/list` returns what this server offers, `tools/call` runs one.",
                        "examples": [
                            "initialize",
                            "tools/list",
                            "tools/call",
                            "ping"
                        ]
                    },
                    "params": {
                        "type": "object",
                        "description": "Method arguments. For `tools/call` this is `{\"name\": \"<tool>\", \"arguments\": { \u2026 }}`, where `arguments` must satisfy that tool's `inputSchema`.",
                        "additionalProperties": true
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            },
            "JsonRpcResponse": {
                "type": "object",
                "title": "JSON-RPC 2.0 response",
                "description": "Exactly one of `result` or `error` is present.\n\nMind the two layers: a tool that fails *cleanly* answers `200` with a `result` whose `isError` is true \u2014 the model is meant to read the message and try something else. `error` means the call never reached a tool.",
                "required": [
                    "jsonrpc"
                ],
                "properties": {
                    "jsonrpc": {
                        "type": "string",
                        "const": "2.0",
                        "description": "Always the string \"2.0\"."
                    },
                    "id": {
                        "type": [
                            "string",
                            "integer",
                            "null"
                        ],
                        "description": "The `id` of the request being answered; null when the request could not be parsed."
                    },
                    "result": {
                        "type": "object",
                        "description": "The method result. Shape depends on `method` \u2014 see the examples.",
                        "additionalProperties": true
                    },
                    "error": {
                        "$ref": "#/components/schemas/JsonRpcError",
                        "description": "Present instead of `result` when the call was refused before any tool ran."
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            },
            "JsonRpcError": {
                "type": "object",
                "title": "JSON-RPC 2.0 error",
                "description": "A protocol-level failure: the request was refused before any tool ran. Refusals from this platform carry `data.reason`, which names the decision \u2014 `missing_token`, `server_not_granted`, `module_disabled` \u2014 so a client can tell \"reconnect with more access\" apart from \"log in again\".",
                "required": [
                    "code",
                    "message"
                ],
                "properties": {
                    "code": {
                        "type": "integer",
                        "description": "JSON-RPC error code. `-32700` parse error, `-32600` invalid request, `-32601` unknown method, `-32602` invalid params, `-32001` unauthenticated, `-32002` refused."
                    },
                    "message": {
                        "type": "string",
                        "description": "A sentence written for a person, not a code."
                    },
                    "data": {
                        "type": "object",
                        "description": "Extra detail. `reason` names the specific decision behind a refusal.",
                        "properties": {
                            "reason": {
                                "type": "string",
                                "description": "The specific decision \u2014 `missing_token`, `server_not_granted`, `module_disabled`, `surface_disabled`."
                            }
                        },
                        "additionalProperties": true
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            },
            "ToolDefinition": {
                "type": "object",
                "title": "Tool definition",
                "description": "One entry of a `tools/list` result. `inputSchema` is a complete JSON Schema for the tool's arguments \u2014 it is the whole argument contract, which is why tools are not modelled as REST operations here.\n\nThe same definitions, for every server at once and without a credential, are at `GET /api-docs/mcp.json`.",
                "required": [
                    "name",
                    "inputSchema"
                ],
                "properties": {
                    "name": {
                        "type": "string",
                        "description": "The value to send as `params.name` on `tools/call`.",
                        "examples": [
                            "list_ivr_flows"
                        ]
                    },
                    "title": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "A human label, when the tool sets one."
                    },
                    "description": {
                        "type": "string",
                        "description": "What the tool does and when to reach for it. This is the text a model actually chooses on."
                    },
                    "inputSchema": {
                        "type": "object",
                        "description": "JSON Schema (draft 2020-12) for `params.arguments`.",
                        "additionalProperties": true
                    },
                    "outputSchema": {
                        "type": "object",
                        "description": "Present only when the tool declares a structured result.",
                        "additionalProperties": true
                    },
                    "annotations": {
                        "type": "object",
                        "description": "Behavioural hints. `readOnlyHint` marks a tool that only reads; `destructiveHint` marks one that changes the account.\n\nTwo more are ours. `version` is a hash of this tool's contract \u2014 its name, description and argument schema \u2014 so a cached definition can be checked rather than trusted. `available` says whether THIS connection could actually call it; when it is false, `withheld_capability` names the tick or permission that is missing and `withheld_reason` is the sentence a call would come back with. The aggregate root at `/mcp` leaves a tool it cannot offer out of the list entirely and explains it on the call; the per-area URLs list their tools whatever the credential holds, so that is where an unavailable one shows up.",
                        "properties": {
                            "readOnlyHint": {
                                "type": "boolean",
                                "description": "True when the tool only reads."
                            },
                            "destructiveHint": {
                                "type": "boolean",
                                "description": "True when the tool changes the account."
                            },
                            "idempotentHint": {
                                "type": "boolean",
                                "description": "True when calling twice with the same arguments is the same as calling once."
                            },
                            "openWorldHint": {
                                "type": "boolean",
                                "description": "True when the tool reaches something outside this platform."
                            },
                            "version": {
                                "type": "string",
                                "description": "Eight hex characters over the tool's name, description and argument schema. It changes when the contract changes, and never otherwise.",
                                "examples": [
                                    "3f9c1a04"
                                ]
                            },
                            "available": {
                                "type": "boolean",
                                "description": "False when this connection was not granted what the tool needs. It is still listed, and calling it returns the reason rather than \"not found\"."
                            },
                            "withheld_capability": {
                                "type": "string",
                                "description": "Present when `available` is false: the consent-screen tick or the permission that is missing, worded as the refusal words it.",
                                "examples": [
                                    "Change tables and fields"
                                ]
                            },
                            "withheld_reason": {
                                "type": "string",
                                "description": "Present when `available` is false: what a call would come back with, in a sentence."
                            }
                        },
                        "additionalProperties": true
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            },
            "ServerInfo": {
                "type": "object",
                "title": "MCP server",
                "description": "One server as `GET /mcp/v1` reports it for the calling credential. `available` is per-credential: a capability the account holder did not grant leaves the server unreachable, not merely unauthorized.",
                "required": [
                    "key",
                    "name",
                    "url",
                    "available"
                ],
                "properties": {
                    "key": {
                        "type": "string",
                        "description": "The `{server}` path segment.",
                        "enum": [
                            "ivr",
                            "flows",
                            "data",
                            "approvals",
                            "payments",
                            "automations",
                            "alerts",
                            "operations",
                            "studio",
                            "numbers",
                            "groups",
                            "agents",
                            "orders",
                            "shop",
                            "tickets",
                            "kb",
                            "content",
                            "calls",
                            "routing",
                            "meetings",
                            "messaging",
                            "inbox",
                            "comments",
                            "posts",
                            "contacts",
                            "overview",
                            "accounts",
                            "navigate",
                            "account"
                        ]
                    },
                    "name": {
                        "type": "string",
                        "description": "Display name."
                    },
                    "description": {
                        "type": "string",
                        "description": "What the server is for."
                    },
                    "url": {
                        "type": "string",
                        "format": "uri",
                        "description": "The absolute endpoint to point a client at."
                    },
                    "available": {
                        "type": "boolean",
                        "description": "Whether this credential may reach it."
                    },
                    "reason": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "description": "Why not, when `available` is false."
                    }
                },
                "x-generated-by": "php artisan mcp:manifest"
            }
        },
        "parameters": {
            "Limit": {
                "name": "limit",
                "in": "query",
                "required": false,
                "description": "Rows per page, 1\u2013100. Defaults to 20 (25 for catalogue endpoints). Values above 100 are clamped.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100,
                    "default": 20
                },
                "example": 20
            },
            "PerPage": {
                "name": "per_page",
                "in": "query",
                "required": false,
                "description": "Alias of `limit`, for clients that already speak Laravel pagination. `limit` wins if both are sent.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 100
                },
                "example": 25
            },
            "Page": {
                "name": "page",
                "in": "query",
                "required": false,
                "description": "Page number, 1-based. Read `data.pagination.has_more_pages` to know when to stop.",
                "schema": {
                    "type": "integer",
                    "minimum": 1,
                    "default": 1
                },
                "example": 1
            },
            "MessageStatus": {
                "name": "status",
                "in": "query",
                "required": false,
                "description": "Only messages in this delivery state.",
                "schema": {
                    "type": "string",
                    "enum": [
                        "queued",
                        "processing",
                        "sent",
                        "checking_delivery",
                        "delivered",
                        "read",
                        "failed",
                        "received"
                    ]
                },
                "example": "delivered"
            },
            "MessageDirection": {
                "name": "direction",
                "in": "query",
                "required": false,
                "description": "Only messages you sent (`outbound`) or received (`inbound`).",
                "schema": {
                    "type": "string",
                    "enum": [
                        "inbound",
                        "outbound"
                    ]
                },
                "example": "outbound"
            },
            "MessageUid": {
                "name": "uid",
                "in": "path",
                "required": true,
                "description": "The message `uid` returned by the send call (or its numeric `id`).",
                "schema": {
                    "type": "string"
                },
                "example": "msg_kuutop7qhc076g316z4k"
            },
            "CampaignUid": {
                "name": "uid",
                "in": "path",
                "required": true,
                "description": "The campaign `uid` returned when the campaign was created (or its numeric `id`).",
                "schema": {
                    "type": "string"
                },
                "example": "cmp_w5aqybtpzqj79ngzqcoh"
            },
            "GroupId": {
                "name": "id",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "integer"
                },
                "description": "The platform id of the group (from the list).",
                "example": 12
            },
            "ContactUid": {
                "name": "uid",
                "in": "path",
                "required": true,
                "description": "The contact `uid` returned when it was created (or its numeric `id`).",
                "schema": {
                    "type": "string"
                },
                "example": "ctc_gz0os4at1itzvvpxvewj"
            },
            "ContactSearch": {
                "name": "search",
                "in": "query",
                "required": false,
                "description": "Match contacts whose name or phone number contains this text.",
                "schema": {
                    "type": "string"
                },
                "example": "Asha"
            },
            "CatalogueId": {
                "name": "catalogue",
                "in": "path",
                "required": true,
                "description": "Catalogue (shop) id, as returned by `GET /api/v3/catalogues`.",
                "schema": {
                    "type": "integer"
                },
                "example": 1
            },
            "ProductId": {
                "name": "product",
                "in": "path",
                "required": true,
                "description": "Product id. Not the `retailer_id` \u2014 that is your own SKU.",
                "schema": {
                    "type": "integer"
                },
                "example": 1
            },
            "OrderId": {
                "name": "order",
                "in": "path",
                "required": true,
                "description": "Order id, as returned by `GET /api/v3/catalogues/orders`.",
                "schema": {
                    "type": "integer"
                },
                "example": 1
            },
            "ProductSearch": {
                "name": "search",
                "in": "query",
                "required": false,
                "description": "Match products whose name or `retailer_id` contains this text.",
                "schema": {
                    "type": "string"
                },
                "example": "kanga"
            },
            "ProductAvailability": {
                "name": "availability",
                "in": "query",
                "required": false,
                "description": "Only products in this stock state.",
                "schema": {
                    "type": "string",
                    "enum": [
                        "in stock",
                        "out of stock",
                        "preorder",
                        "available for order",
                        "discontinued"
                    ]
                },
                "example": "in stock"
            },
            "OrderStatusFilter": {
                "name": "status",
                "in": "query",
                "required": false,
                "description": "Only orders in this fulfilment state.",
                "schema": {
                    "type": "string",
                    "enum": [
                        "pending",
                        "confirmed",
                        "processing",
                        "shipped",
                        "delivered",
                        "cancelled",
                        "refunded"
                    ]
                },
                "example": "pending"
            },
            "DataTableId": {
                "name": "table",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "string",
                    "format": "uuid"
                },
                "description": "The table id (from `GET /api/v3/data/tables`). Anything that is not a UUID, or a table belonging to another tenant, answers 404.",
                "example": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b"
            },
            "DataRecordId": {
                "name": "record",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "string",
                    "format": "uuid"
                },
                "description": "The record id (from a records page, or the `record.id` returned when it was created).",
                "example": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d"
            },
            "DataGroupId": {
                "name": "group",
                "in": "path",
                "required": true,
                "schema": {
                    "type": "string",
                    "format": "uuid"
                },
                "description": "The group id (from `GET /api/v3/data/groups`). Anything that is not a UUID, or a group belonging to another tenant, answers 404.",
                "example": "7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f"
            }
        },
        "responses": {
            "Unauthorized": {
                "description": "Missing, unknown or expired bearer token.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                        },
                        "example": {
                            "status": "error",
                            "message": "Invalid API token."
                        }
                    }
                }
            },
            "Forbidden": {
                "description": "The record exists but belongs to another tenant.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                        },
                        "example": {
                            "status": "error",
                            "message": "This catalogue belongs to another tenant."
                        }
                    }
                }
            },
            "NotFound": {
                "description": "No such record for this tenant.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                        },
                        "example": {
                            "status": "error",
                            "message": "Resource not found."
                        }
                    }
                }
            },
            "ValidationFailed": {
                "description": "The payload failed validation. `errors` maps each rejected field to its messages.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                        },
                        "example": {
                            "status": "error",
                            "message": "Validation failed.",
                            "errors": {
                                "recipient": [
                                    "Provide recipient or recipients."
                                ]
                            }
                        }
                    }
                }
            },
            "RateLimited": {
                "description": "More than 120 requests in a minute on this token. Wait for `Retry-After` seconds and retry.",
                "headers": {
                    "Retry-After": {
                        "description": "Seconds to wait before retrying.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 42
                    },
                    "X-RateLimit-Limit": {
                        "description": "Requests allowed per minute.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 120
                    },
                    "X-RateLimit-Remaining": {
                        "description": "Requests left in the current window.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 0
                    },
                    "X-RateLimit-Reset": {
                        "description": "Unix timestamp when the window resets.",
                        "schema": {
                            "type": "integer"
                        },
                        "example": 1789012345
                    }
                },
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/RateLimitError"
                        },
                        "example": {
                            "status": "error",
                            "message": "Too many requests. Retry after the number of seconds in the Retry-After header."
                        }
                    }
                }
            },
            "UpstreamFailure": {
                "description": "WhatsApp/Meta refused the call. The message repeats what they said; the record was not changed.",
                "content": {
                    "application/json": {
                        "schema": {
                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                        },
                        "example": {
                            "status": "error",
                            "message": "(#100) Invalid parameter: product image_url is not reachable."
                        }
                    }
                }
            }
        }
    },
    "paths": {
        "/api/v3/sms/send": {
            "post": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3SmsSend",
                "summary": "Send an SMS",
                "description": "Creates one record per normalized recipient and normally attempts provider delivery synchronously, sequentially. HTTP 201 can contain sent or failed records; inspect every status/error_message. Future schedules, admission deferral or fallback can return queued. Repeating this POST is not protected by a request Idempotency-Key. Use a nonempty message. SMS types plain/text/sms are supported; other types require media_url and provider media support.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "recipient": {
                                        "type": "string",
                                        "description": "Recipients separated by commas, semicolons or whitespace. Combined with recipients and deduplicated by exact string.",
                                        "maxLength": 4000
                                    },
                                    "recipients": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 191
                                        },
                                        "description": "Additional recipient strings; entries also split on commas, semicolons and whitespace. Can be used together with recipient."
                                    },
                                    "sender_id": {
                                        "type": "string",
                                        "description": "Optional approved sender ID, tenant-owned SMS-capable number, or active short code. Unknown or ambiguous identities are rejected. `GET /api/v3/sms/senders` lists every usable identity, with `value` being what to pass here.",
                                        "maxLength": 64
                                    },
                                    "type": {
                                        "type": "string",
                                        "description": "Message type (e.g. plain).",
                                        "maxLength": 60
                                    },
                                    "message": {
                                        "type": "string",
                                        "description": "Message text, maximum 4096 characters. Supply meaningful nonempty text; the current controller substitutes a generic body if absent.",
                                        "maxLength": 4096
                                    },
                                    "schedule_time": {
                                        "type": "string",
                                        "description": "Optional ISO datetime for scheduled send.",
                                        "maxLength": 100
                                    },
                                    "body": {
                                        "type": "string",
                                        "maxLength": 4096,
                                        "description": "Alias of `message`, for clients that already speak that field. `message` wins if both are sent."
                                    },
                                    "message_type": {
                                        "type": "string",
                                        "description": "Takes precedence over type. Defaults to plain for SMS and text for WhatsApp; supplied payload objects determine provider send behavior.",
                                        "maxLength": 60
                                    },
                                    "media_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "Publicly reachable media to attach. Turns the send into an MMS-style message on gateways that support one."
                                    },
                                    "media_type": {
                                        "type": "string",
                                        "maxLength": 32,
                                        "description": "Media kind (image, video, document\u2026). Defaults to the message type."
                                    }
                                },
                                "anyOf": [
                                    {
                                        "required": [
                                            "recipient"
                                        ]
                                    },
                                    {
                                        "required": [
                                            "recipients"
                                        ]
                                    }
                                ],
                                "description": "Supply recipient and/or recipients. Inputs are merged and exact duplicates removed. Message/body and payload combinations follow this endpoint description."
                            },
                            "examples": {
                                "default": {
                                    "summary": "Single recipient (most common)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "sender_id": "MyBrand",
                                        "message": "Hello from Momo Business \u2014 your verification code is 4821."
                                    }
                                },
                                "multi_recipient_csv": {
                                    "summary": "Multiple recipients (comma-separated)",
                                    "value": {
                                        "recipient": "255700111222,255700111223,255700111224",
                                        "sender_id": "MyBrand",
                                        "message": "Branch closed early today \u2014 back tomorrow at 8am."
                                    }
                                },
                                "multi_recipient_array": {
                                    "summary": "Multiple recipients (array form)",
                                    "value": {
                                        "recipients": [
                                            "255700111222",
                                            "255700111223",
                                            "255700111224"
                                        ],
                                        "sender_id": "MyBrand",
                                        "message": "Reminder: payment due tomorrow."
                                    }
                                },
                                "scheduled": {
                                    "summary": "Scheduled send (queue for later)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "sender_id": "MyBrand",
                                        "message": "Good morning! Your appointment is at 10am.",
                                        "schedule_time": "2030-10-12T09:00:00+03:00"
                                    }
                                },
                                "long_unicode": {
                                    "summary": "Long Unicode message (will be split into multiple SMS segments)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "sender_id": "MyBrand",
                                        "message": "Mteja mpendwa, asante kwa kutembelea duka letu. Tunakushukuru kwa upendeleo wako wa kuendelea kununua bidhaa zetu. Tafadhali piga 0700123456 kwa msaada zaidi."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "One message record per recipient. `data.messages[].status` is the delivery state at the moment we answered; watch the `message.*` webhooks for what happens after.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "messages"
                                            ],
                                            "properties": {
                                                "messages": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Message",
                                                        "description": "The message record."
                                                    },
                                                    "description": "One record per recipient, in the order they were given."
                                                }
                                            },
                                            "description": "The messages this call created."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "messages": [
                                                    {
                                                        "id": 101,
                                                        "uid": "msg_01JXYZSMS01",
                                                        "direction": "outbound",
                                                        "channel_type": "sms",
                                                        "sender": "MyBrand",
                                                        "recipient": "255700111222",
                                                        "body": "Hello from API v3",
                                                        "status": "sent"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Invalid API token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "At least one recipient is required.",
                                            "errors": {
                                                "recipient": [
                                                    "Provide recipient or recipients."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/sms/campaign": {
            "post": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3SmsCampaignCreate",
                "summary": "Create an SMS campaign",
                "description": "Creates one one-time SMS campaign per resolved contact group. Numeric IDs and group UUIDs may be separated by whitespace, comma or semicolon. Unknown groups are skipped when at least one resolves; no resolved groups returns 404. Campaign completed means recipient jobs were dispatched, not all messages delivered. Current dispatch skips blacklisted/missing phone numbers but does not filter is_subscribed. No recurrence or request-key idempotency is exposed here.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "contact_list_id": {
                                        "type": "string",
                                        "description": "Contact group to send to \u2014 the numeric id or the group UUID. Comma-separate several, and each one becomes its own campaign.",
                                        "maxLength": 2000
                                    },
                                    "message": {
                                        "type": "string",
                                        "description": "The message body. `{name}` and any custom field on the contact are substituted per recipient.",
                                        "maxLength": 4096
                                    },
                                    "sender_id": {
                                        "type": "string",
                                        "description": "Optional approved sender ID, tenant-owned SMS-capable number, or active short code. `GET /api/v3/sms/senders` lists every usable identity, with `value` being what to pass here.",
                                        "maxLength": 64
                                    },
                                    "schedule_time": {
                                        "type": "string",
                                        "description": "ISO 8601 datetime to start the campaign. Omit it and the campaign starts immediately.",
                                        "maxLength": 100
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "A name for the campaign in the dashboard. Defaults to \"API Campaign - <group name>\".",
                                        "maxLength": 160
                                    }
                                },
                                "required": [
                                    "contact_list_id",
                                    "message"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "contact_list_id": "grp_01JXYZABC",
                                        "message": "Campaign message",
                                        "sender_id": "Brand"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Campaigns created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "campaigns"
                                            ],
                                            "properties": {
                                                "campaigns": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Campaign",
                                                        "description": "The campaign record."
                                                    },
                                                    "description": "One campaign per contact group in `contact_list_id`."
                                                }
                                            },
                                            "description": "The campaigns this call created."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "campaigns": [
                                                    {
                                                        "id": 15,
                                                        "uid": "cmp_01JXYZ001",
                                                        "name": "API Campaign - VIP List",
                                                        "status": "draft",
                                                        "channel_type": "sms",
                                                        "message": "Campaign message"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Invalid API token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "Validation error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "contact_list_id must contain at least one group id."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/sms": {
            "get": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3SmsList",
                "summary": "List SMS messages",
                "description": "Returns tenant-scoped SMS message logs with pagination.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/MessageStatus"
                    },
                    {
                        "$ref": "#/components/parameters/MessageDirection"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "SMS collection.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Message",
                                                        "description": "The message record."
                                                    },
                                                    "description": "The messages on this page, newest first."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of messages and its page state."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "items": [
                                                    {
                                                        "id": 101,
                                                        "uid": "msg_01JXYZSMS01",
                                                        "direction": "outbound",
                                                        "channel_type": "sms",
                                                        "recipient": "255700111222",
                                                        "body": "Hello from API v3",
                                                        "status": "queued"
                                                    }
                                                ],
                                                "pagination": {
                                                    "current_page": 1,
                                                    "per_page": 20,
                                                    "last_page": 1,
                                                    "total": 1,
                                                    "has_more_pages": false
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Missing bearer token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/sms/{uid}": {
            "get": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3SmsShow",
                "summary": "Get an SMS message",
                "description": "Fetches one SMS message by public uid with numeric id fallback.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/MessageUid"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Single SMS message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Message",
                                            "description": "The message record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 101,
                                                "uid": "msg_01JXYZSMS01",
                                                "direction": "outbound",
                                                "channel_type": "sms",
                                                "recipient": "255700111222",
                                                "body": "Hello from API v3",
                                                "status": "delivered"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Message not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Message not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/campaign/{uid}/view": {
            "get": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3CampaignShow",
                "summary": "View one campaign",
                "description": "Retrieves one SMS campaign by uid.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CampaignUid"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Campaign details.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Campaign",
                                            "description": "The campaign record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 15,
                                                "uid": "cmp_01JXYZ001",
                                                "name": "API Campaign - VIP List",
                                                "status": "running",
                                                "channel_type": "sms",
                                                "message": "Campaign message"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Campaign not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Campaign not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/send": {
            "post": {
                "tags": [
                    "WhatsApp"
                ],
                "operationId": "v3WhatsAppSend",
                "summary": "Send a WhatsApp message",
                "description": "Creates one record per normalized recipient and normally attempts provider delivery synchronously, sequentially. HTTP 201 can contain sent or failed records; inspect every status/error_message. Future schedules, admission deferral or fallback can return queued. Repeating this POST is not protected by a request Idempotency-Key. Supports text, templates, media, interactive payloads and reactions. Provider validation, including conversation-window rules, can appear as a failed message in a 201 response.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "recipient": {
                                        "type": "string",
                                        "description": "Recipients separated by commas, semicolons or whitespace. Combined with recipients and deduplicated by exact string.",
                                        "maxLength": 4000
                                    },
                                    "recipients": {
                                        "type": "array",
                                        "items": {
                                            "type": "string",
                                            "maxLength": 191
                                        },
                                        "description": "Additional recipient strings; entries also split on commas, semicolons and whitespace. Can be used together with recipient."
                                    },
                                    "message": {
                                        "type": "string",
                                        "description": "Text or local preview text, maximum 4096 characters. With a template, this does not replace the approved provider template body.",
                                        "maxLength": 4096
                                    },
                                    "body": {
                                        "type": "string",
                                        "description": "Alias of `message`. `message` wins if both are sent.",
                                        "maxLength": 4096
                                    },
                                    "message_type": {
                                        "type": "string",
                                        "description": "Takes precedence over type. Defaults to plain for SMS and text for WhatsApp; supplied payload objects determine provider send behavior.",
                                        "maxLength": 60
                                    },
                                    "type": {
                                        "type": "string",
                                        "description": "Alias of `message_type`.",
                                        "maxLength": 60
                                    },
                                    "media_url": {
                                        "type": "string",
                                        "description": "Publicly reachable file to send as the message. WhatsApp fetches it directly, so it cannot sit behind authentication.",
                                        "maxLength": 2048,
                                        "format": "uri"
                                    },
                                    "media_type": {
                                        "type": "string",
                                        "description": "The kind of media at `media_url` (image, video, audio, document, sticker). Defaults to `message_type`.",
                                        "maxLength": 32
                                    },
                                    "template": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Provider template name, language and components. Requires a nonempty name. Cannot be combined with media or interactive payloads.",
                                        "required": [
                                            "name"
                                        ],
                                        "properties": {
                                            "name": {
                                                "type": "string",
                                                "maxLength": 191,
                                                "description": "Template name exactly as approved in your WhatsApp Business Account."
                                            },
                                            "language": {
                                                "type": "string",
                                                "maxLength": 20,
                                                "description": "Template language code, e.g. `en` or `sw`. Defaults to `en`."
                                            },
                                            "components": {
                                                "type": "array",
                                                "items": {
                                                    "type": "object",
                                                    "additionalProperties": true
                                                },
                                                "description": "Template variables in WhatsApp's own `components` shape \u2014 one entry per header, body or button that takes a parameter."
                                            }
                                        }
                                    },
                                    "interactive": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Provider-shaped interactive payload. Buttons and lists are normalized; other supported interactive types are passed through for provider validation. Cannot be combined with top-level media or template."
                                    },
                                    "reaction": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Requires a nonempty emoji and a target provider message ID in message_id or in_reply_to_gateway_id. Cannot be combined with text/media/template/interactive.",
                                        "required": [
                                            "emoji"
                                        ],
                                        "properties": {
                                            "emoji": {
                                                "type": "string",
                                                "maxLength": 16,
                                                "description": "Nonempty reaction emoji. Empty-emoji removal is not supported by this REST route."
                                            },
                                            "message_id": {
                                                "type": "string",
                                                "maxLength": 191,
                                                "description": "The `gateway_message_id` of the message being reacted to."
                                            }
                                        }
                                    },
                                    "in_reply_to_gateway_id": {
                                        "type": "string",
                                        "description": "Quote an earlier message: the `gateway_message_id` of the message being replied to. It shows in the chat as a reply to that bubble.",
                                        "maxLength": 191
                                    },
                                    "sender_id": {
                                        "type": "string",
                                        "maxLength": 64,
                                        "description": "WhatsApp phone number id to send from, when the account has more than one. Defaults to the account default. `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself)."
                                    },
                                    "schedule_time": {
                                        "type": "string",
                                        "description": "Optional future send time. Use ISO8601 with an explicit offset; past times do not delay.",
                                        "maxLength": 100
                                    }
                                },
                                "anyOf": [
                                    {
                                        "required": [
                                            "recipient"
                                        ]
                                    },
                                    {
                                        "required": [
                                            "recipients"
                                        ]
                                    }
                                ],
                                "description": "Supply recipient and/or recipients. Inputs are merged and exact duplicates removed. Message/body and payload combinations follow this endpoint description. Reaction excludes every other payload; template excludes top-level media/interactive; interactive excludes top-level media. Media message types require media_url."
                            },
                            "examples": {
                                "default": {
                                    "summary": "Text message",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message": "Hello from the API"
                                    }
                                },
                                "text": {
                                    "summary": "Text",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "text",
                                        "message": "Hello, this is a plain text message."
                                    }
                                },
                                "image": {
                                    "summary": "Image",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "image",
                                        "media_url": "https://example.com/image.png",
                                        "message": "Optional caption"
                                    }
                                },
                                "video": {
                                    "summary": "Video",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "video",
                                        "media_url": "https://example.com/video.mp4",
                                        "message": "Optional caption"
                                    }
                                },
                                "audio": {
                                    "summary": "Audio",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "audio",
                                        "media_url": "https://example.com/audio.ogg"
                                    }
                                },
                                "document": {
                                    "summary": "Document",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "document",
                                        "media_url": "https://example.com/file.pdf",
                                        "message": "Optional filename or caption"
                                    }
                                },
                                "sticker": {
                                    "summary": "Sticker",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "sticker",
                                        "media_url": "https://example.com/sticker.webp"
                                    }
                                },
                                "template": {
                                    "summary": "Template",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "template",
                                        "template": {
                                            "name": "welcome_template",
                                            "language": "en",
                                            "components": []
                                        }
                                    }
                                },
                                "interactive_button": {
                                    "summary": "Interactive (buttons)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "button",
                                            "body": {
                                                "text": "Choose one"
                                            },
                                            "action": {
                                                "buttons": [
                                                    {
                                                        "id": "yes",
                                                        "title": "Yes"
                                                    },
                                                    {
                                                        "id": "no",
                                                        "title": "No"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                "interactive_list": {
                                    "summary": "Interactive (list)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "list",
                                            "body": {
                                                "text": "Select an option"
                                            },
                                            "action": {
                                                "button": "View options",
                                                "sections": [
                                                    {
                                                        "title": "Section 1",
                                                        "rows": [
                                                            {
                                                                "id": "opt_1",
                                                                "title": "Option 1",
                                                                "description": "First choice"
                                                            },
                                                            {
                                                                "id": "opt_2",
                                                                "title": "Option 2",
                                                                "description": "Second choice"
                                                            }
                                                        ]
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                "reaction": {
                                    "summary": "Reaction",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "reaction",
                                        "reaction": {
                                            "emoji": "\ud83d\udc4d",
                                            "message_id": "wamid.xxxxx"
                                        }
                                    }
                                },
                                "location": {
                                    "summary": "Location pin",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "location",
                                        "location": {
                                            "latitude": -6.7924,
                                            "longitude": 39.2083,
                                            "name": "Momo Telecom HQ",
                                            "address": "Dar es Salaam, Tanzania"
                                        }
                                    }
                                },
                                "contacts_vcard": {
                                    "summary": "Contact card (vCard)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "contacts",
                                        "contacts": [
                                            {
                                                "name": {
                                                    "formatted_name": "Asha Mwita",
                                                    "first_name": "Asha",
                                                    "last_name": "Mwita"
                                                },
                                                "phones": [
                                                    {
                                                        "phone": "+255700123456",
                                                        "type": "WORK",
                                                        "wa_id": "255700123456"
                                                    }
                                                ],
                                                "emails": [
                                                    {
                                                        "email": "asha@example.com",
                                                        "type": "WORK"
                                                    }
                                                ],
                                                "org": {
                                                    "company": "Momo Telecom",
                                                    "title": "Account Manager"
                                                }
                                            }
                                        ]
                                    }
                                },
                                "interactive_cta_url": {
                                    "summary": "Interactive \u2014 call-to-action URL button",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "cta_url",
                                            "header": {
                                                "type": "text",
                                                "text": "Track your order"
                                            },
                                            "body": {
                                                "text": "Your order #4521 has shipped. Tap below to track delivery in real time."
                                            },
                                            "footer": {
                                                "text": "Powered by Momo Business"
                                            },
                                            "action": {
                                                "name": "cta_url",
                                                "parameters": {
                                                    "display_text": "Track order",
                                                    "url": "https://acme.example.com/orders/4521"
                                                }
                                            }
                                        }
                                    }
                                },
                                "interactive_flow": {
                                    "summary": "Interactive \u2014 WhatsApp Flow",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "flow",
                                            "header": {
                                                "type": "text",
                                                "text": "Book an appointment"
                                            },
                                            "body": {
                                                "text": "Pick a time slot that works for you."
                                            },
                                            "footer": {
                                                "text": "Takes 60 seconds"
                                            },
                                            "action": {
                                                "name": "flow",
                                                "parameters": {
                                                    "flow_message_version": "3",
                                                    "flow_token": "FLOW_TOKEN_FROM_BACKEND",
                                                    "flow_id": "1234567890123456",
                                                    "flow_cta": "Book now",
                                                    "flow_action": "navigate",
                                                    "flow_action_payload": {
                                                        "screen": "APPOINTMENT_SCREEN"
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "interactive_image_header": {
                                    "summary": "Interactive buttons with image header",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "button",
                                            "header": {
                                                "type": "image",
                                                "image": {
                                                    "link": "https://cdn.example.com/promo.jpg"
                                                }
                                            },
                                            "body": {
                                                "text": "Limited-time offer \u2014 30% off today only."
                                            },
                                            "action": {
                                                "buttons": [
                                                    {
                                                        "type": "reply",
                                                        "reply": {
                                                            "id": "shop_now",
                                                            "title": "Shop now"
                                                        }
                                                    },
                                                    {
                                                        "type": "reply",
                                                        "reply": {
                                                            "id": "remind_later",
                                                            "title": "Remind me later"
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                "product_single": {
                                    "summary": "Product (single item from a catalogue)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "product",
                                            "body": {
                                                "text": "Check out this laptop."
                                            },
                                            "action": {
                                                "catalog_id": "26191517010530753",
                                                "product_retailer_id": "SKU-LAPTOP-X1"
                                            }
                                        }
                                    }
                                },
                                "product_list": {
                                    "summary": "Product list (up to 30 items, 10 sections)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "product_list",
                                            "header": {
                                                "type": "text",
                                                "text": "Top picks"
                                            },
                                            "body": {
                                                "text": "Tap any item to see details and add to cart."
                                            },
                                            "footer": {
                                                "text": "Free delivery on orders over TZS 50,000"
                                            },
                                            "action": {
                                                "catalog_id": "26191517010530753",
                                                "sections": [
                                                    {
                                                        "title": "Laptops",
                                                        "product_items": [
                                                            {
                                                                "product_retailer_id": "SKU-LAPTOP-X1"
                                                            },
                                                            {
                                                                "product_retailer_id": "SKU-LAPTOP-AIR"
                                                            }
                                                        ]
                                                    },
                                                    {
                                                        "title": "Phones",
                                                        "product_items": [
                                                            {
                                                                "product_retailer_id": "SKU-PHONE-15"
                                                            }
                                                        ]
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                },
                                "catalog_message": {
                                    "summary": "Full catalogue (storefront entry point)",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "interactive",
                                        "interactive": {
                                            "type": "catalog_message",
                                            "body": {
                                                "text": "Browse our entire catalogue."
                                            },
                                            "action": {
                                                "name": "catalog_message",
                                                "parameters": {
                                                    "thumbnail_product_retailer_id": "SKU-LAPTOP-X1"
                                                }
                                            }
                                        }
                                    }
                                },
                                "template_with_components": {
                                    "summary": "Template with header image + body params + URL button",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "template",
                                        "template": {
                                            "name": "order_shipped",
                                            "language": "en_US",
                                            "components": [
                                                {
                                                    "type": "header",
                                                    "parameters": [
                                                        {
                                                            "type": "image",
                                                            "image": {
                                                                "link": "https://cdn.example.com/box.jpg"
                                                            }
                                                        }
                                                    ]
                                                },
                                                {
                                                    "type": "body",
                                                    "parameters": [
                                                        {
                                                            "type": "text",
                                                            "text": "Asha"
                                                        },
                                                        {
                                                            "type": "text",
                                                            "text": "4521"
                                                        },
                                                        {
                                                            "type": "text",
                                                            "text": "Tomorrow 9\u201311am"
                                                        }
                                                    ]
                                                },
                                                {
                                                    "type": "button",
                                                    "sub_type": "url",
                                                    "index": "0",
                                                    "parameters": [
                                                        {
                                                            "type": "text",
                                                            "text": "4521"
                                                        }
                                                    ]
                                                }
                                            ]
                                        }
                                    }
                                },
                                "reply_in_thread": {
                                    "summary": "Reply that quotes a previous message",
                                    "value": {
                                        "recipient": "255700111222",
                                        "message_type": "text",
                                        "message": "Got it \u2014 see you tomorrow!",
                                        "in_reply_to_gateway_id": "wamid.HBgMMjU1NzAwMTExMjIyFQIAERgSREYx..."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "One message record per recipient. `data.messages[].status` is the delivery state at the moment we answered; watch the `message.*` webhooks for what happens after.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "messages"
                                            ],
                                            "properties": {
                                                "messages": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Message",
                                                        "description": "The message record."
                                                    },
                                                    "description": "One record per recipient, in the order they were given."
                                                }
                                            },
                                            "description": "The messages this call created."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "messages": [
                                                    {
                                                        "id": 300,
                                                        "uid": "msg_01JXYZWA01",
                                                        "direction": "outbound",
                                                        "channel_type": "whatsapp",
                                                        "recipient": "255700111222",
                                                        "body": "Interactive message",
                                                        "status": "sent",
                                                        "metadata": {
                                                            "interactive": {
                                                                "type": "button"
                                                            }
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Invalid API token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation or payload combination error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Reaction cannot be combined with text, media, template, or interactive payload."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp": {
            "get": {
                "tags": [
                    "WhatsApp"
                ],
                "operationId": "v3WhatsAppList",
                "summary": "List WhatsApp messages",
                "description": "Returns tenant-scoped WhatsApp message logs with pagination.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/MessageStatus"
                    },
                    {
                        "$ref": "#/components/parameters/MessageDirection"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "WhatsApp collection.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Message",
                                                        "description": "The message record."
                                                    },
                                                    "description": "The messages on this page, newest first."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of messages and its page state."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "items": [
                                                    {
                                                        "id": 300,
                                                        "uid": "msg_01JXYZWA01",
                                                        "direction": "outbound",
                                                        "channel_type": "whatsapp",
                                                        "recipient": "255700111222",
                                                        "body": "Interactive message",
                                                        "status": "queued"
                                                    }
                                                ],
                                                "pagination": {
                                                    "current_page": 1,
                                                    "per_page": 20,
                                                    "last_page": 1,
                                                    "total": 1,
                                                    "has_more_pages": false
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Missing bearer token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/{uid}": {
            "get": {
                "tags": [
                    "WhatsApp"
                ],
                "operationId": "v3WhatsAppShow",
                "summary": "Get a WhatsApp message",
                "description": "Fetches one WhatsApp message by public uid.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/MessageUid"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Single WhatsApp message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Message",
                                            "description": "The message record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 300,
                                                "uid": "msg_01JXYZWA01",
                                                "direction": "outbound",
                                                "channel_type": "whatsapp",
                                                "recipient": "255700111222",
                                                "body": "Interactive message",
                                                "status": "delivered"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Message not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Message not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups": {
            "get": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsList",
                "x-permission": "communications.groups.view",
                "x-permission-scope": "controller",
                "summary": "List WhatsApp groups",
                "description": "Groups created from the account's WhatsApp numbers. Deleted groups are left out unless `status=deleted` or `status=all`.",
                "parameters": [
                    {
                        "name": "sender_id",
                        "in": "query",
                        "schema": {
                            "type": "string"
                        },
                        "description": "Only groups on this business number (phone_number_id or display number). `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself).",
                        "example": "243438852181644"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "creating",
                                "active",
                                "suspended",
                                "failed",
                                "deleted",
                                "all"
                            ]
                        },
                        "example": "active",
                        "description": "creating (waiting for WhatsApp), active, suspended (by WhatsApp, for policy), deleted, or failed (WhatsApp refused to create it; see last_error)."
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 100,
                            "default": 20
                        },
                        "example": 20,
                        "description": "limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of groups.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WhatsAppGroup"
                                                    },
                                                    "description": "The groups on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Paging information."
                                                }
                                            },
                                            "description": "A page of groups."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "items": [
                                                    {
                                                        "id": 12,
                                                        "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                        "request_id": "b5c1\u2026",
                                                        "phone_number_id": "243438852181644",
                                                        "waba_id": "1029384756",
                                                        "subject": "VIP customers \u2014 September",
                                                        "description": "Offers first.",
                                                        "join_approval_mode": "auto_approve",
                                                        "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                        "status": "active",
                                                        "participant_count": 5,
                                                        "max_participants": 8,
                                                        "seats_left": 2,
                                                        "pending_join_requests": 0,
                                                        "conversation_id": 8812,
                                                        "invite_template_id": 41,
                                                        "last_message_at": "2026-09-07T10:12:00+03:00",
                                                        "last_error": null,
                                                        "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                        "created_at": "2026-09-01T08:00:00+03:00",
                                                        "updated_at": "2026-09-07T10:12:00+03:00"
                                                    }
                                                ],
                                                "pagination": {
                                                    "current_page": 1,
                                                    "per_page": 20,
                                                    "last_page": 1,
                                                    "total": 1,
                                                    "has_more_pages": false
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsCreate",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Create a WhatsApp group",
                "description": "Creates a group from a business number. WhatsApp confirms it a moment later: the group starts as `creating` and becomes `active`, with its `meta_group_id` and `invite_link`, when the confirmation webhook arrives. Invitees, if given, are sent the invite template once it is active.\n\nNeeds an Official Business Account (the green tick); otherwise WhatsApp answers code 131215 and this endpoint returns 422. Nobody can be added to a group directly \u2014 people join by tapping the link.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "sender_id": {
                                        "type": "string",
                                        "description": "The business number; the account's default WhatsApp number when omitted. `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself)."
                                    },
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 128,
                                        "description": "The group name, up to 128 characters."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 2048,
                                        "description": "What the group is for; members see it before joining. Up to 2048 characters."
                                    },
                                    "join_approval_mode": {
                                        "type": "string",
                                        "enum": [
                                            "auto_approve",
                                            "approval_required"
                                        ],
                                        "default": "auto_approve",
                                        "description": "auto_approve: anyone with the link joins. approval_required: the business approves each request."
                                    },
                                    "invite_template": {
                                        "type": "string",
                                        "description": "Name of an approved group-invite template."
                                    },
                                    "invitees": {
                                        "type": "array",
                                        "maxItems": 7,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Phones to invite once the group is confirmed."
                                    }
                                },
                                "required": [
                                    "subject"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "subject": "VIP customers \u2014 September",
                                        "description": "Offers first.",
                                        "join_approval_mode": "auto_approve",
                                        "invite_template": "group_invite_link",
                                        "invitees": [
                                            "255711000001",
                                            "255711000002"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Group requested (or, rarely, created at once).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                            "description": "Group requested (or, rarely, created at once)."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 12,
                                                "meta_group_id": null,
                                                "request_id": "b5c1\u2026",
                                                "phone_number_id": "243438852181644",
                                                "waba_id": "1029384756",
                                                "subject": "VIP customers \u2014 September",
                                                "description": "Offers first.",
                                                "join_approval_mode": "auto_approve",
                                                "invite_link": null,
                                                "status": "creating",
                                                "participant_count": 5,
                                                "max_participants": 8,
                                                "seats_left": 2,
                                                "pending_join_requests": 0,
                                                "conversation_id": 8812,
                                                "invite_template_id": 41,
                                                "last_message_at": "2026-09-07T10:12:00+03:00",
                                                "last_error": null,
                                                "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                "created_at": "2026-09-01T08:00:00+03:00",
                                                "updated_at": "2026-09-07T10:12:00+03:00",
                                                "participants": [],
                                                "join_requests": [],
                                                "invite_template": {
                                                    "id": 41,
                                                    "name": "group_invite_link",
                                                    "language": "en",
                                                    "whatsapp_status": "approved"
                                                },
                                                "events": []
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}": {
            "get": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsShow",
                "x-permission": "communications.groups.view",
                "x-permission-scope": "controller",
                "summary": "Get a WhatsApp group",
                "description": "One group with its members, pending join requests, invite link and recent activity.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The group.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                            "description": "The group."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 12,
                                                "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                "request_id": "b5c1\u2026",
                                                "phone_number_id": "243438852181644",
                                                "waba_id": "1029384756",
                                                "subject": "VIP customers \u2014 September",
                                                "description": "Offers first.",
                                                "join_approval_mode": "auto_approve",
                                                "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                "status": "active",
                                                "participant_count": 5,
                                                "max_participants": 8,
                                                "seats_left": 2,
                                                "pending_join_requests": 0,
                                                "conversation_id": 8812,
                                                "invite_template_id": 41,
                                                "last_message_at": "2026-09-07T10:12:00+03:00",
                                                "last_error": null,
                                                "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                "created_at": "2026-09-01T08:00:00+03:00",
                                                "updated_at": "2026-09-07T10:12:00+03:00",
                                                "participants": [
                                                    {
                                                        "id": 1,
                                                        "wa_id": "255711000001",
                                                        "display_name": "Asha",
                                                        "status": "member",
                                                        "invited_at": "2026-09-01T08:05:00+03:00",
                                                        "joined_at": "2026-09-01T08:09:00+03:00",
                                                        "left_at": null,
                                                        "reason": "invite_link",
                                                        "last_error": null
                                                    }
                                                ],
                                                "join_requests": [
                                                    {
                                                        "id": 3,
                                                        "join_request_id": "JR-1",
                                                        "wa_id": "255711000005",
                                                        "status": "pending",
                                                        "requested_at": "2026-09-07T10:00:00+03:00",
                                                        "resolved_at": null
                                                    }
                                                ],
                                                "invite_template": {
                                                    "id": 41,
                                                    "name": "group_invite_link",
                                                    "language": "en",
                                                    "whatsapp_status": "approved"
                                                },
                                                "events": [
                                                    {
                                                        "id": 90,
                                                        "type": "group.participant_joined",
                                                        "actor": "participant",
                                                        "payload": {
                                                            "wa_ids": [
                                                                "255711000001"
                                                            ],
                                                            "reason": "invite_link"
                                                        },
                                                        "occurred_at": "2026-09-01T08:09:00+03:00"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsUpdate",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Update a group's subject or description",
                "description": "Applied optimistically; WhatsApp confirms through the settings webhook and the group is re-synced if it refused.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "subject": {
                                        "type": "string",
                                        "maxLength": 128,
                                        "description": "The group name, up to 128 characters."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 2048,
                                        "description": "What the group is for; members see it before joining. Up to 2048 characters."
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "subject": "VIP customers \u2014 October"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The group.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                            "description": "The group."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 12,
                                                "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                "request_id": "b5c1\u2026",
                                                "phone_number_id": "243438852181644",
                                                "waba_id": "1029384756",
                                                "subject": "VIP customers \u2014 September",
                                                "description": "Offers first.",
                                                "join_approval_mode": "auto_approve",
                                                "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                "status": "active",
                                                "participant_count": 5,
                                                "max_participants": 8,
                                                "seats_left": 2,
                                                "pending_join_requests": 0,
                                                "conversation_id": 8812,
                                                "invite_template_id": 41,
                                                "last_message_at": "2026-09-07T10:12:00+03:00",
                                                "last_error": null,
                                                "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                "created_at": "2026-09-01T08:00:00+03:00",
                                                "updated_at": "2026-09-07T10:12:00+03:00",
                                                "participants": [
                                                    {
                                                        "id": 1,
                                                        "wa_id": "255711000001",
                                                        "display_name": "Asha",
                                                        "status": "member",
                                                        "invited_at": "2026-09-01T08:05:00+03:00",
                                                        "joined_at": "2026-09-01T08:09:00+03:00",
                                                        "left_at": null,
                                                        "reason": "invite_link",
                                                        "last_error": null
                                                    }
                                                ],
                                                "join_requests": [
                                                    {
                                                        "id": 3,
                                                        "join_request_id": "JR-1",
                                                        "wa_id": "255711000005",
                                                        "status": "pending",
                                                        "requested_at": "2026-09-07T10:00:00+03:00",
                                                        "resolved_at": null
                                                    }
                                                ],
                                                "invite_template": {
                                                    "id": 41,
                                                    "name": "group_invite_link",
                                                    "language": "en",
                                                    "whatsapp_status": "approved"
                                                },
                                                "events": [
                                                    {
                                                        "id": 90,
                                                        "type": "group.participant_joined",
                                                        "actor": "participant",
                                                        "payload": {
                                                            "wa_ids": [
                                                                "255711000001"
                                                            ],
                                                            "reason": "invite_link"
                                                        },
                                                        "occurred_at": "2026-09-01T08:09:00+03:00"
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsDelete",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Delete a WhatsApp group",
                "description": "Removes everyone and closes the thread. The thread and its history stay readable.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The group, now deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppGroup",
                                            "description": "The group, now deleted."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 12,
                                                "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                "request_id": "b5c1\u2026",
                                                "phone_number_id": "243438852181644",
                                                "waba_id": "1029384756",
                                                "subject": "VIP customers \u2014 September",
                                                "description": "Offers first.",
                                                "join_approval_mode": "auto_approve",
                                                "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                "status": "deleted",
                                                "participant_count": 5,
                                                "max_participants": 8,
                                                "seats_left": 2,
                                                "pending_join_requests": 0,
                                                "conversation_id": 8812,
                                                "invite_template_id": 41,
                                                "last_message_at": "2026-09-07T10:12:00+03:00",
                                                "last_error": null,
                                                "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                "created_at": "2026-09-01T08:00:00+03:00",
                                                "updated_at": "2026-09-07T10:12:00+03:00"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/invite-link/reset": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsResetInviteLink",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Reset the invite link",
                "description": "Issues a new link; the old one stops working at once.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The new link.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "invite_link": {
                                                    "type": "string",
                                                    "description": "The chat.whatsapp.com link people tap to join. Null until WhatsApp confirms the group."
                                                },
                                                "group": {
                                                    "$ref": "#/components/schemas/WhatsAppGroup",
                                                    "description": "The group after the change."
                                                }
                                            },
                                            "description": "The new link."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "invite_link": "https://chat.whatsapp.com/NewLink9",
                                                "group": {
                                                    "id": 12,
                                                    "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                    "request_id": "b5c1\u2026",
                                                    "phone_number_id": "243438852181644",
                                                    "waba_id": "1029384756",
                                                    "subject": "VIP customers \u2014 September",
                                                    "description": "Offers first.",
                                                    "join_approval_mode": "auto_approve",
                                                    "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                    "status": "active",
                                                    "participant_count": 5,
                                                    "max_participants": 8,
                                                    "seats_left": 2,
                                                    "pending_join_requests": 0,
                                                    "conversation_id": 8812,
                                                    "invite_template_id": 41,
                                                    "last_message_at": "2026-09-07T10:12:00+03:00",
                                                    "last_error": null,
                                                    "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                    "created_at": "2026-09-01T08:00:00+03:00",
                                                    "updated_at": "2026-09-07T10:12:00+03:00"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/invites": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsInvite",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Invite people to a group",
                "description": "Sends each recipient the approved invite-link template as a normal 1:1 template message (billed as such). They join by tapping the link; the roster updates from the webhook.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "recipients": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 7,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Phone numbers in international format, without the plus sign."
                                    },
                                    "template": {
                                        "type": "string",
                                        "description": "An approved invite template name; the group's own, or the account's first matching one, when omitted."
                                    }
                                },
                                "required": [
                                    "recipients"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "recipients": [
                                            "255711000003"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Who was invited and who was not.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "sent": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Recipients the invite was queued for."
                                                },
                                                "failed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "phone": {
                                                                "type": "string",
                                                                "description": "The recipient."
                                                            },
                                                            "reason": {
                                                                "type": "string",
                                                                "description": "How they got here: invite_link, left, removed_by_business, sync, group_deleted."
                                                            }
                                                        }
                                                    },
                                                    "description": "Recipients it was not sent to, with the reason."
                                                },
                                                "group": {
                                                    "$ref": "#/components/schemas/WhatsAppGroup",
                                                    "description": "The group after the change."
                                                }
                                            },
                                            "description": "Who was invited and who was not."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "sent": [
                                                    "255711000003"
                                                ],
                                                "failed": [],
                                                "group": {
                                                    "id": 12,
                                                    "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                    "request_id": "b5c1\u2026",
                                                    "phone_number_id": "243438852181644",
                                                    "waba_id": "1029384756",
                                                    "subject": "VIP customers \u2014 September",
                                                    "description": "Offers first.",
                                                    "join_approval_mode": "auto_approve",
                                                    "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                    "status": "active",
                                                    "participant_count": 5,
                                                    "max_participants": 8,
                                                    "seats_left": 2,
                                                    "pending_join_requests": 0,
                                                    "conversation_id": 8812,
                                                    "invite_template_id": 41,
                                                    "last_message_at": "2026-09-07T10:12:00+03:00",
                                                    "last_error": null,
                                                    "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                    "created_at": "2026-09-01T08:00:00+03:00",
                                                    "updated_at": "2026-09-07T10:12:00+03:00"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/participants": {
            "delete": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsRemoveParticipants",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Remove people from a group",
                "description": "Up to 8 per call, by phone number or wa_id.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "participants": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 8,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Everyone ever invited into or seen in the group, with their current state."
                                    }
                                },
                                "required": [
                                    "participants"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "participants": [
                                            "255711000002"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Who was removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "removed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "People removed."
                                                },
                                                "failed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    },
                                                    "description": "Recipients it was not sent to, with the reason."
                                                },
                                                "group": {
                                                    "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                                    "description": "The group after the change."
                                                }
                                            },
                                            "description": "Who was removed."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "removed": [
                                                    "255711000002"
                                                ],
                                                "failed": [],
                                                "group": {
                                                    "id": 12,
                                                    "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                    "request_id": "b5c1\u2026",
                                                    "phone_number_id": "243438852181644",
                                                    "waba_id": "1029384756",
                                                    "subject": "VIP customers \u2014 September",
                                                    "description": "Offers first.",
                                                    "join_approval_mode": "auto_approve",
                                                    "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                    "status": "active",
                                                    "participant_count": 5,
                                                    "max_participants": 8,
                                                    "seats_left": 2,
                                                    "pending_join_requests": 0,
                                                    "conversation_id": 8812,
                                                    "invite_template_id": 41,
                                                    "last_message_at": "2026-09-07T10:12:00+03:00",
                                                    "last_error": null,
                                                    "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                    "created_at": "2026-09-01T08:00:00+03:00",
                                                    "updated_at": "2026-09-07T10:12:00+03:00",
                                                    "participants": [
                                                        {
                                                            "id": 1,
                                                            "wa_id": "255711000001",
                                                            "display_name": "Asha",
                                                            "status": "member",
                                                            "invited_at": "2026-09-01T08:05:00+03:00",
                                                            "joined_at": "2026-09-01T08:09:00+03:00",
                                                            "left_at": null,
                                                            "reason": "invite_link",
                                                            "last_error": null
                                                        }
                                                    ],
                                                    "join_requests": [
                                                        {
                                                            "id": 3,
                                                            "join_request_id": "JR-1",
                                                            "wa_id": "255711000005",
                                                            "status": "pending",
                                                            "requested_at": "2026-09-07T10:00:00+03:00",
                                                            "resolved_at": null
                                                        }
                                                    ],
                                                    "invite_template": {
                                                        "id": 41,
                                                        "name": "group_invite_link",
                                                        "language": "en",
                                                        "whatsapp_status": "approved"
                                                    },
                                                    "events": [
                                                        {
                                                            "id": 90,
                                                            "type": "group.participant_joined",
                                                            "actor": "participant",
                                                            "payload": {
                                                                "wa_ids": [
                                                                    "255711000001"
                                                                ],
                                                                "reason": "invite_link"
                                                            },
                                                            "occurred_at": "2026-09-01T08:09:00+03:00"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/join-requests": {
            "get": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsJoinRequests",
                "x-permission": "communications.groups.view",
                "x-permission-scope": "controller",
                "summary": "List join requests",
                "description": "Everyone who asked to join an approval-required group, newest first.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Join requests.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WhatsAppGroupJoinRequest"
                                                    },
                                                    "description": "The rows on this page."
                                                }
                                            },
                                            "description": "Join requests."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "items": [
                                                    {
                                                        "id": 3,
                                                        "join_request_id": "JR-1",
                                                        "wa_id": "255711000005",
                                                        "status": "pending",
                                                        "requested_at": "2026-09-07T10:00:00+03:00",
                                                        "resolved_at": null
                                                    }
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/join-requests/approve": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsApproveJoinRequests",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Approve join requests",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "join_requests": {
                                        "type": "array",
                                        "minItems": 1,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "join_request_id values from the list or the group.join_requested webhook."
                                    }
                                },
                                "required": [
                                    "join_requests"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "join_requests": [
                                            "JR-1"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Result per request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "approved": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Requests approved."
                                                },
                                                "failed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    },
                                                    "description": "Recipients it was not sent to, with the reason."
                                                },
                                                "group": {
                                                    "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                                    "description": "The group after the change."
                                                }
                                            },
                                            "description": "Result per request."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "approved": [
                                                    "JR-1"
                                                ],
                                                "failed": [],
                                                "group": {
                                                    "id": 12,
                                                    "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                    "request_id": "b5c1\u2026",
                                                    "phone_number_id": "243438852181644",
                                                    "waba_id": "1029384756",
                                                    "subject": "VIP customers \u2014 September",
                                                    "description": "Offers first.",
                                                    "join_approval_mode": "auto_approve",
                                                    "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                    "status": "active",
                                                    "participant_count": 5,
                                                    "max_participants": 8,
                                                    "seats_left": 2,
                                                    "pending_join_requests": 0,
                                                    "conversation_id": 8812,
                                                    "invite_template_id": 41,
                                                    "last_message_at": "2026-09-07T10:12:00+03:00",
                                                    "last_error": null,
                                                    "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                    "created_at": "2026-09-01T08:00:00+03:00",
                                                    "updated_at": "2026-09-07T10:12:00+03:00",
                                                    "participants": [
                                                        {
                                                            "id": 1,
                                                            "wa_id": "255711000001",
                                                            "display_name": "Asha",
                                                            "status": "member",
                                                            "invited_at": "2026-09-01T08:05:00+03:00",
                                                            "joined_at": "2026-09-01T08:09:00+03:00",
                                                            "left_at": null,
                                                            "reason": "invite_link",
                                                            "last_error": null
                                                        }
                                                    ],
                                                    "join_requests": [
                                                        {
                                                            "id": 3,
                                                            "join_request_id": "JR-1",
                                                            "wa_id": "255711000005",
                                                            "status": "pending",
                                                            "requested_at": "2026-09-07T10:00:00+03:00",
                                                            "resolved_at": null
                                                        }
                                                    ],
                                                    "invite_template": {
                                                        "id": 41,
                                                        "name": "group_invite_link",
                                                        "language": "en",
                                                        "whatsapp_status": "approved"
                                                    },
                                                    "events": [
                                                        {
                                                            "id": 90,
                                                            "type": "group.participant_joined",
                                                            "actor": "participant",
                                                            "payload": {
                                                                "wa_ids": [
                                                                    "255711000001"
                                                                ],
                                                                "reason": "invite_link"
                                                            },
                                                            "occurred_at": "2026-09-01T08:09:00+03:00"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Lets the people in the request into the group. Their join shows up on the group.participant_joined webhook."
            }
        },
        "/api/v3/whatsapp/groups/{id}/join-requests/reject": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsRejectJoinRequests",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Reject join requests",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "join_requests": {
                                        "type": "array",
                                        "minItems": 1,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "join_request_id values from the list or the group.join_requested webhook."
                                    }
                                },
                                "required": [
                                    "join_requests"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "join_requests": [
                                            "JR-1"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Result per request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "rejected": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Requests rejected."
                                                },
                                                "failed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "object"
                                                    },
                                                    "description": "Recipients it was not sent to, with the reason."
                                                },
                                                "group": {
                                                    "$ref": "#/components/schemas/WhatsAppGroupDetail",
                                                    "description": "The group after the change."
                                                }
                                            },
                                            "description": "Result per request."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "rejected": [
                                                    "JR-1"
                                                ],
                                                "failed": [],
                                                "group": {
                                                    "id": 12,
                                                    "meta_group_id": "Y2FwaV9ncm91cDo6MTIzNDU2",
                                                    "request_id": "b5c1\u2026",
                                                    "phone_number_id": "243438852181644",
                                                    "waba_id": "1029384756",
                                                    "subject": "VIP customers \u2014 September",
                                                    "description": "Offers first.",
                                                    "join_approval_mode": "auto_approve",
                                                    "invite_link": "https://chat.whatsapp.com/AbCdEf123",
                                                    "status": "active",
                                                    "participant_count": 5,
                                                    "max_participants": 8,
                                                    "seats_left": 2,
                                                    "pending_join_requests": 0,
                                                    "conversation_id": 8812,
                                                    "invite_template_id": 41,
                                                    "last_message_at": "2026-09-07T10:12:00+03:00",
                                                    "last_error": null,
                                                    "last_synced_at": "2026-09-07T09:00:00+03:00",
                                                    "created_at": "2026-09-01T08:00:00+03:00",
                                                    "updated_at": "2026-09-07T10:12:00+03:00",
                                                    "participants": [
                                                        {
                                                            "id": 1,
                                                            "wa_id": "255711000001",
                                                            "display_name": "Asha",
                                                            "status": "member",
                                                            "invited_at": "2026-09-01T08:05:00+03:00",
                                                            "joined_at": "2026-09-01T08:09:00+03:00",
                                                            "left_at": null,
                                                            "reason": "invite_link",
                                                            "last_error": null
                                                        }
                                                    ],
                                                    "join_requests": [
                                                        {
                                                            "id": 3,
                                                            "join_request_id": "JR-1",
                                                            "wa_id": "255711000005",
                                                            "status": "pending",
                                                            "requested_at": "2026-09-07T10:00:00+03:00",
                                                            "resolved_at": null
                                                        }
                                                    ],
                                                    "invite_template": {
                                                        "id": 41,
                                                        "name": "group_invite_link",
                                                        "language": "en",
                                                        "whatsapp_status": "approved"
                                                    },
                                                    "events": [
                                                        {
                                                            "id": 90,
                                                            "type": "group.participant_joined",
                                                            "actor": "participant",
                                                            "payload": {
                                                                "wa_ids": [
                                                                    "255711000001"
                                                                ],
                                                                "reason": "invite_link"
                                                            },
                                                            "occurred_at": "2026-09-01T08:09:00+03:00"
                                                        }
                                                    ]
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                },
                "description": "Turns the people in the request away. They can ask again with the same link."
            }
        },
        "/api/v3/whatsapp/groups/{id}/messages": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsSendMessage",
                "x-permission": "communications.groups.manage, communications.send",
                "x-permission-scope": "controller",
                "summary": "Send a message into a group",
                "description": "Text, a media link, or an approved template, to everyone in the room. Text and media need a member to have written in the last 24 hours; a template always sends. WhatsApp bills one message per member it is delivered to. Buttons, lists, products and reactions are not accepted in groups.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "message": {
                                        "type": "string",
                                        "maxLength": 4096,
                                        "description": "The text, or the caption when media_url is given."
                                    },
                                    "media_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "A public URL to an image, video, audio file or document."
                                    },
                                    "media_type": {
                                        "type": "string",
                                        "enum": [
                                            "image",
                                            "video",
                                            "audio",
                                            "document"
                                        ],
                                        "description": "What the media is; document when omitted."
                                    },
                                    "template": {
                                        "type": "object",
                                        "properties": {
                                            "name": {
                                                "type": "string",
                                                "description": "Template name."
                                            },
                                            "language": {
                                                "type": "string",
                                                "description": "Template language code."
                                            },
                                            "components": {
                                                "type": "array",
                                                "items": {
                                                    "type": "object"
                                                },
                                                "description": "Template components, exactly as for /whatsapp/send."
                                            }
                                        },
                                        "required": [
                                            "name"
                                        ],
                                        "description": "An approved template."
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "message": "Ofa ya leo: 20% off hadi saa 12."
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The queued message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Message",
                                            "description": "The queued message."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 901,
                                                "public_uid": "msg_01JXYZWG01",
                                                "conversation_id": 8812,
                                                "direction": "outbound",
                                                "body": "Ofa ya leo: 20% off hadi saa 12.",
                                                "status": "queued"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, communications.send, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/groups/{id}/pin": {
            "post": {
                "tags": [
                    "WhatsApp groups"
                ],
                "operationId": "v3WhatsAppGroupsPin",
                "x-permission": "communications.groups.manage",
                "x-permission-scope": "controller",
                "summary": "Pin or unpin a message",
                "description": "At most three pinned at a time; pinning a fourth unpins the oldest.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "message_uid": {
                                        "type": "string",
                                        "description": "The public uid of a delivered message in this group."
                                    },
                                    "pin": {
                                        "type": "boolean",
                                        "description": "true to pin, false to unpin."
                                    },
                                    "expiration_days": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 30,
                                        "description": "How long to keep it pinned; WhatsApp allows 1 to 30 days."
                                    }
                                },
                                "required": [
                                    "message_uid",
                                    "pin"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "message_uid": "msg_01JXYZWG01",
                                        "pin": true,
                                        "expiration_days": 7
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Done.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "pinned": {
                                                    "type": "boolean",
                                                    "description": "Whether the message is pinned now."
                                                }
                                            },
                                            "description": "Done."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "pinned": true
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Group not found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "WhatsApp refused the request, or the group cannot take it right now (not confirmed yet, suspended, deleted). Meta's error code, when there is one, is under errors.meta[0].code.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "WhatsApp suspended this group; nothing can be sent until the suspension clears."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold communications.groups.manage, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"communications.groups.manage\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contacts/{group_id}/store": {
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactsStore",
                "summary": "Create a contact",
                "description": "Stores one contact in a group using legacy fields and custom dynamic attributes. `POST /api/v3/contact-groups/{group}/contacts` is the same operation on the REST path, and `\u2026/contacts/batch` takes up to 500 at once.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "PHONE": {
                                        "type": "string",
                                        "description": "The phone number, with or without the country code. Combined with `country_code` and normalised for storage.",
                                        "maxLength": 64
                                    },
                                    "country_code": {
                                        "type": "string",
                                        "description": "Explicit calling code, e.g. 255. The contact parser does not infer this from a +255 PHONE value when omitted.",
                                        "maxLength": 8
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "Display name. When absent, FIRST_NAME and LAST_NAME are joined; when those are absent too, the phone number is used.",
                                        "maxLength": 160
                                    },
                                    "FIRST_NAME": {
                                        "type": "string",
                                        "description": "First name. Joined with LAST_NAME when `name` is absent."
                                    },
                                    "LAST_NAME": {
                                        "type": "string",
                                        "description": "Last name. Joined with FIRST_NAME when `name` is absent."
                                    },
                                    "is_subscribed": {
                                        "type": "boolean",
                                        "description": "Stored subscription flag. Defaults true on create and retains its value when omitted on update. Current campaign dispatch does not automatically filter this flag."
                                    },
                                    "phone_number": {
                                        "type": "string",
                                        "description": "Alias of PHONE. PHONE wins when both are supplied.",
                                        "maxLength": 64
                                    },
                                    "NAME": {
                                        "type": "string",
                                        "description": "Name alias used when name is absent."
                                    }
                                },
                                "additionalProperties": true,
                                "description": "PHONE or phone_number is required, including on PATCH. Name is recalculated and custom fields are replaced, not merged. Nonreserved top-level fields become custom_field_values. Reserved keys include PHONE, phone_number, country_code, name, NAME, FIRST_NAME, LAST_NAME, is_subscribed and _token.",
                                "anyOf": [
                                    {
                                        "required": [
                                            "PHONE"
                                        ]
                                    },
                                    {
                                        "required": [
                                            "phone_number"
                                        ]
                                    }
                                ]
                            },
                            "examples": {
                                "default": {
                                    "summary": "Minimal \u2014 only the phone number is required",
                                    "value": {
                                        "PHONE": "255700333444"
                                    }
                                },
                                "with_name": {
                                    "summary": "With name + structured first/last name",
                                    "value": {
                                        "PHONE": "255700333444",
                                        "name": "Asha Mwita",
                                        "FIRST_NAME": "Asha",
                                        "LAST_NAME": "Mwita"
                                    }
                                },
                                "with_country_code": {
                                    "summary": "Local phone format + explicit country code",
                                    "value": {
                                        "PHONE": "0700333444",
                                        "country_code": "TZ",
                                        "name": "Asha Mwita"
                                    }
                                },
                                "with_custom_fields": {
                                    "summary": "Custom merge fields (any keys you don't recognise become custom fields)",
                                    "value": {
                                        "PHONE": "255700333444",
                                        "FIRST_NAME": "Asha",
                                        "LAST_NAME": "Mwita",
                                        "CITY": "Dar es Salaam",
                                        "ACCOUNT_NUMBER": "AC-2204",
                                        "PLAN": "Pro",
                                        "RENEWAL_DATE": "2026-05-01"
                                    }
                                },
                                "opted_out": {
                                    "summary": "Mark contact as opted-out (won't receive campaigns)",
                                    "value": {
                                        "PHONE": "255700333444",
                                        "name": "Asha Mwita",
                                        "is_subscribed": false
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Contact created. Phone numbers are normalised to E.164 (international) format and de-duplicated within the group \u2014 re-posting the same PHONE returns the existing row.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 66,
                                                "uid": "ctc_01JXYZ001",
                                                "group_id": 8,
                                                "group_uid": "grp_01JXYZABC",
                                                "name": "John Doe",
                                                "country_code": "255",
                                                "phone_number": "700333444",
                                                "full_phone_number": "255700333444",
                                                "is_subscribed": true,
                                                "custom_field_values": {
                                                    "CITY": "Dar es Salaam"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Contact group not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "PHONE": [
                                                    "The PHONE field is required."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "x-permission": "contacts.create",
                "x-permission-scope": "controller"
            }
        },
        "/api/v3/contacts/{group_id}/search/{uid}": {
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactsShow",
                "summary": "Find a contact",
                "description": "Finds a single contact in a group by public uid. `GET /api/v3/contact-groups/{group}/contacts/{contact}` is the same operation on the REST path.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    },
                    {
                        "$ref": "#/components/parameters/ContactUid"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Single contact.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 66,
                                                "uid": "ctc_01JXYZ001",
                                                "group_id": 8,
                                                "group_uid": "grp_01JXYZABC",
                                                "name": "John Doe",
                                                "country_code": "255",
                                                "phone_number": "700333444",
                                                "full_phone_number": "255700333444",
                                                "is_subscribed": true,
                                                "custom_field_values": {
                                                    "CITY": "Dar es Salaam"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Contact not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Contact not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "x-permission": "contacts.view",
                "x-permission-scope": "controller"
            }
        },
        "/api/v3/contacts/{group_id}/update/{uid}": {
            "patch": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactsUpdate",
                "summary": "Update a contact",
                "description": "Changes exactly what you send. Custom fields MERGE into what is stored (send a key as `null` to remove it), and the name, number and subscription each keep their current value when the payload is silent about them; `PHONE` is required only when the number itself is changing.\n\nThis changed on 2026-09-14. Until then the endpoint replaced the whole custom-field map and renamed the contact after their phone number whenever `name` was absent, so a call meant only to flip `is_subscribed` destroyed data. A caller that followed the old advice \u2014 read, merge, send everything \u2014 is unaffected. `PATCH /api/v3/contact-groups/{group}/contacts/{contact}` is the same operation on the REST path.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    },
                    {
                        "$ref": "#/components/parameters/ContactUid"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "PHONE": {
                                        "type": "string",
                                        "description": "The phone number, with or without the country code. Combined with `country_code` and normalised for storage.",
                                        "maxLength": 64
                                    },
                                    "country_code": {
                                        "type": "string",
                                        "description": "Explicit calling code, e.g. 255. The contact parser does not infer this from a +255 PHONE value when omitted.",
                                        "maxLength": 8
                                    },
                                    "name": {
                                        "type": "string",
                                        "description": "Display name. When absent, FIRST_NAME and LAST_NAME are joined; when those are absent too, the phone number is used.",
                                        "maxLength": 160
                                    },
                                    "is_subscribed": {
                                        "type": "boolean",
                                        "description": "Stored subscription flag. Defaults true on create and retains its value when omitted on update. Current campaign dispatch does not automatically filter this flag."
                                    },
                                    "FIRST_NAME": {
                                        "type": "string",
                                        "description": "First name. Joined with LAST_NAME when `name` is absent."
                                    },
                                    "LAST_NAME": {
                                        "type": "string",
                                        "description": "Last name. Joined with FIRST_NAME when `name` is absent."
                                    },
                                    "phone_number": {
                                        "type": "string",
                                        "description": "Alias of PHONE. PHONE wins when both are supplied.",
                                        "maxLength": 64
                                    },
                                    "NAME": {
                                        "type": "string",
                                        "description": "Name alias used when name is absent."
                                    }
                                },
                                "additionalProperties": true,
                                "description": "PHONE or phone_number is required, including on PATCH. Name is recalculated and custom fields are replaced, not merged. Nonreserved top-level fields become custom_field_values. Reserved keys include PHONE, phone_number, country_code, name, NAME, FIRST_NAME, LAST_NAME, is_subscribed and _token.",
                                "anyOf": [
                                    {
                                        "required": [
                                            "PHONE"
                                        ]
                                    },
                                    {
                                        "required": [
                                            "phone_number"
                                        ]
                                    }
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "PHONE": "255700333444",
                                        "name": "John Updated"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Contact updated.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 66,
                                                "uid": "ctc_01JXYZ001",
                                                "group_id": 8,
                                                "group_uid": "grp_01JXYZABC",
                                                "name": "John Updated",
                                                "country_code": "255",
                                                "phone_number": "700333444",
                                                "full_phone_number": "255700333444",
                                                "is_subscribed": true,
                                                "custom_field_values": []
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Contact or group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Contact not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Validation error.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "PHONE": [
                                                    "The PHONE field is required."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "x-permission": "contacts.edit",
                "x-permission-scope": "controller"
            }
        },
        "/api/v3/contacts/{group_id}/delete/{uid}": {
            "delete": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactsDelete",
                "summary": "Delete a contact",
                "description": "Deletes one contact by uid within a contact group. `DELETE /api/v3/contact-groups/{group}/contacts/{contact}` is the same operation on the REST path.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    },
                    {
                        "$ref": "#/components/parameters/ContactUid"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Contact deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "deleted",
                                                "uid"
                                            ],
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true \u2014 the contact is gone."
                                                },
                                                "uid": {
                                                    "type": "string",
                                                    "description": "The uid of the deleted contact."
                                                }
                                            },
                                            "description": "What was deleted."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "deleted": true,
                                                "uid": "ctc_01JXYZ001"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Contact or group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Contact not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "x-permission": "contacts.delete",
                "x-permission-scope": "controller"
            }
        },
        "/api/v3/contacts/{group_id}/all": {
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactsList",
                "summary": "List contacts in a group",
                "description": "Lists contacts by group with optional search and pagination controls. `GET /api/v3/contact-groups/{group}/contacts` is the same operation on the REST path.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/GroupId"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "search": {
                                        "type": "string",
                                        "description": "Match contacts whose name or phone number contains this text."
                                    },
                                    "limit": {
                                        "type": "integer",
                                        "description": "Rows per page, 1\u2013100. Defaults to 20."
                                    },
                                    "per_page": {
                                        "type": "integer",
                                        "description": "Alias of `limit`."
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "summary": "Default \u2014 first 25 contacts",
                                    "value": {
                                        "limit": 25
                                    }
                                },
                                "search": {
                                    "summary": "Search by name or phone substring",
                                    "value": {
                                        "search": "Asha",
                                        "limit": 25
                                    }
                                },
                                "page_2": {
                                    "summary": "Pagination \u2014 page 2",
                                    "value": {
                                        "limit": 25,
                                        "page": 2
                                    }
                                },
                                "subscribed_only": {
                                    "summary": "Only subscribed (campaign-eligible) contacts",
                                    "value": {
                                        "is_subscribed": true,
                                        "limit": 50
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Contact collection. Phone numbers are returned in two parts: `country_code` + `phone_number` (local), and a pre-joined `full_phone_number`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Contact",
                                                        "description": "The contact record."
                                                    },
                                                    "description": "The contacts on this page, most recently updated first."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of contacts and its page state."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "items": [
                                                    {
                                                        "id": 66,
                                                        "uid": "ctc_01JXYZ001",
                                                        "group_id": 8,
                                                        "group_uid": "grp_01JXYZABC",
                                                        "name": "John Doe",
                                                        "country_code": "255",
                                                        "phone_number": "700333444",
                                                        "full_phone_number": "255700333444",
                                                        "is_subscribed": true,
                                                        "custom_field_values": {
                                                            "CITY": "Dar es Salaam"
                                                        }
                                                    }
                                                ],
                                                "pagination": {
                                                    "current_page": 1,
                                                    "per_page": 25,
                                                    "last_page": 1,
                                                    "total": 1,
                                                    "has_more_pages": false
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "404": {
                        "description": "Group not found.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Contact group not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    }
                },
                "x-permission": "contacts.view",
                "x-permission-scope": "controller"
            }
        },
        "/api/v3/me": {
            "get": {
                "tags": [
                    "Profile & Balance"
                ],
                "operationId": "v3ProfileMe",
                "summary": "Get current account",
                "description": "Returns the tenant profile represented by the bearer token.",
                "responses": {
                    "200": {
                        "description": "Tenant profile.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "id",
                                                "name",
                                                "slug"
                                            ],
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "description": "Tenant id."
                                                },
                                                "name": {
                                                    "type": "string",
                                                    "description": "Account name as it appears in the dashboard."
                                                },
                                                "slug": {
                                                    "type": "string",
                                                    "description": "URL-safe form of the account name."
                                                },
                                                "external_client_id": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Your own reference for this account, when one was set. Null otherwise."
                                                },
                                                "created_at": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "ISO 8601 timestamp of when the account was created."
                                                },
                                                "updated_at": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "ISO 8601 timestamp of the last change to it."
                                                }
                                            },
                                            "description": "The tenant this token belongs to."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "id": 12,
                                                "name": "Workspace Alpha",
                                                "slug": "workspace-alpha",
                                                "external_client_id": null
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Invalid API token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/balance": {
            "get": {
                "tags": [
                    "Profile & Balance"
                ],
                "operationId": "v3ProfileBalance",
                "summary": "Get balance",
                "description": "Returns wallet balance, currency, billing mode, and spend metadata.",
                "responses": {
                    "200": {
                        "description": "Tenant wallet balance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\" on a 2xx response."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "wallet_balance",
                                                "wallet_currency",
                                                "billing_mode"
                                            ],
                                            "properties": {
                                                "wallet_balance": {
                                                    "type": "number",
                                                    "description": "Spendable balance in `wallet_currency`, in major units (973093.57 is TZS 973,093.57)."
                                                },
                                                "wallet_currency": {
                                                    "type": "string",
                                                    "description": "ISO 4217 currency the wallet is held in."
                                                },
                                                "billing_mode": {
                                                    "type": "string",
                                                    "description": "prepaid (sends draw down this balance) or postpaid (sends are invoiced)."
                                                },
                                                "cumulative_spend_cents": {
                                                    "type": "integer",
                                                    "description": "Lifetime spend in cents, which is what moves the account between pricing tiers. Null before the first charge."
                                                },
                                                "tier_override": {
                                                    "type": "boolean",
                                                    "description": "True when an operator pinned this account to a tier instead of letting spend decide it."
                                                },
                                                "last_updated_at": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "ISO 8601 timestamp of the last wallet movement."
                                                }
                                            },
                                            "description": "The wallet behind this account."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "wallet_balance": 12000.5,
                                                "wallet_currency": "TZS",
                                                "billing_mode": "prepaid",
                                                "cumulative_spend_cents": 0,
                                                "tier_override": false
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "Unauthorized.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Missing bearer token."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueList",
                "summary": "List catalogues",
                "description": "Every shop belonging to the token's tenant, newest first, each with its product and order counts.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of catalogues.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Catalogue",
                                                        "description": "The catalogue record."
                                                    },
                                                    "description": "The catalogues on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of rows and its page state."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "name": "Acme Duka",
                                                "description": null,
                                                "vertical": "commerce",
                                                "default_currency": "TZS",
                                                "meta_catalogue_id": null,
                                                "is_connected_to_waba": false,
                                                "is_catalogue_visible": false,
                                                "is_cart_enabled": true,
                                                "products_count": 1,
                                                "orders_count": 1,
                                                "last_synced_at": null,
                                                "created_at": "2026-09-04T19:19:55+00:00",
                                                "updated_at": "2026-09-04T19:19:55+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueCreate",
                "summary": "Create a catalogue",
                "description": "Make a shop from your own system, so an integration can finish its setup without anyone opening the dashboard. Connecting the shop to WhatsApp stays a dashboard step: it needs a consent a bearer token cannot give on a person's behalf.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 120,
                                        "description": "Shop name."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 2000,
                                        "description": "What this shop sells."
                                    },
                                    "vertical": {
                                        "type": "string",
                                        "maxLength": 40,
                                        "description": "Commerce vertical, defaults to `commerce`."
                                    },
                                    "default_currency": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 3,
                                        "description": "Currency for products that do not name one."
                                    },
                                    "sku_prefix": {
                                        "type": "string",
                                        "maxLength": 8,
                                        "description": "Prefix for codes the shop issues itself. Accepted on create only."
                                    },
                                    "stock_policy": {
                                        "type": "string",
                                        "enum": [
                                            "external",
                                            "momo"
                                        ],
                                        "description": "Who owns the stock count. Defaults to `external` here."
                                    },
                                    "source_of_truth": {
                                        "type": "string",
                                        "enum": [
                                            "api",
                                            "momo",
                                            "platform"
                                        ],
                                        "description": "Who wins on product fields. Defaults to `api` here."
                                    },
                                    "allow_backorder": {
                                        "type": "boolean",
                                        "description": "Sell past zero."
                                    },
                                    "reservation_ttl_hours": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 720,
                                        "description": "How long a pending order holds stock."
                                    },
                                    "low_stock_threshold": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 0,
                                        "description": "Raise `stock.low` at or below this count."
                                    }
                                },
                                "required": [
                                    "name"
                                ]
                            },
                            "example": {
                                "name": "Mango Electronics",
                                "default_currency": "TZS",
                                "sku_prefix": "MNG",
                                "stock_policy": "external"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The created catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Catalogue",
                                            "description": "The catalogue record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "name": "Mango Electronics",
                                        "description": null,
                                        "vertical": "commerce",
                                        "default_currency": "TZS",
                                        "sku_prefix": "MNG",
                                        "stock_policy": "external",
                                        "source_of_truth": "api",
                                        "allow_backorder": false,
                                        "reservation_ttl_hours": 48,
                                        "low_stock_threshold": null,
                                        "meta_catalogue_id": null,
                                        "is_connected_to_waba": false,
                                        "is_catalogue_visible": false,
                                        "is_cart_enabled": true,
                                        "channels": [
                                            {
                                                "platform": "whatsapp",
                                                "label": "Mango Electronics",
                                                "external_catalogue_id": "1122334455",
                                                "external_account_id": "998877",
                                                "public_slug": null,
                                                "is_connected": true,
                                                "last_synced_at": "2026-09-11T02:00:41+00:00"
                                            }
                                        ],
                                        "products_count": 1994,
                                        "orders_count": 12,
                                        "last_synced_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueShow",
                "summary": "Read one catalogue",
                "description": "One shop with its product and order counts.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Catalogue",
                                            "description": "The catalogue record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 1,
                                        "name": "Acme Duka",
                                        "description": null,
                                        "vertical": "commerce",
                                        "default_currency": "TZS",
                                        "meta_catalogue_id": null,
                                        "is_connected_to_waba": false,
                                        "is_catalogue_visible": false,
                                        "is_cart_enabled": true,
                                        "products_count": 1,
                                        "orders_count": 1,
                                        "last_synced_at": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueUpdate",
                "summary": "Change a catalogue",
                "description": "Change a shop's name, currency or stock policy. `sku_prefix` is ignored: it is stamped into every code the shop has already issued.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "name": {
                                        "type": "string",
                                        "maxLength": 120,
                                        "description": "Shop name."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 2000,
                                        "description": "What this shop sells."
                                    },
                                    "vertical": {
                                        "type": "string",
                                        "maxLength": 40,
                                        "description": "Commerce vertical, defaults to `commerce`."
                                    },
                                    "default_currency": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 3,
                                        "description": "Currency for products that do not name one."
                                    },
                                    "sku_prefix": {
                                        "type": "string",
                                        "maxLength": 8,
                                        "description": "Prefix for codes the shop issues itself. Accepted on create only."
                                    },
                                    "stock_policy": {
                                        "type": "string",
                                        "enum": [
                                            "external",
                                            "momo"
                                        ],
                                        "description": "Who owns the stock count. Defaults to `external` here."
                                    },
                                    "source_of_truth": {
                                        "type": "string",
                                        "enum": [
                                            "api",
                                            "momo",
                                            "platform"
                                        ],
                                        "description": "Who wins on product fields. Defaults to `api` here."
                                    },
                                    "allow_backorder": {
                                        "type": "boolean",
                                        "description": "Sell past zero."
                                    },
                                    "reservation_ttl_hours": {
                                        "type": "integer",
                                        "minimum": 1,
                                        "maximum": 720,
                                        "description": "How long a pending order holds stock."
                                    },
                                    "low_stock_threshold": {
                                        "type": [
                                            "integer",
                                            "null"
                                        ],
                                        "minimum": 0,
                                        "description": "Raise `stock.low` at or below this count."
                                    }
                                }
                            },
                            "example": {
                                "stock_policy": "momo",
                                "low_stock_threshold": 3
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Catalogue",
                                            "description": "The catalogue record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "name": "Mango Electronics",
                                        "description": null,
                                        "vertical": "commerce",
                                        "default_currency": "TZS",
                                        "sku_prefix": "MNG",
                                        "stock_policy": "external",
                                        "source_of_truth": "api",
                                        "allow_backorder": false,
                                        "reservation_ttl_hours": 48,
                                        "low_stock_threshold": null,
                                        "meta_catalogue_id": null,
                                        "is_connected_to_waba": false,
                                        "is_catalogue_visible": false,
                                        "is_cart_enabled": true,
                                        "channels": [
                                            {
                                                "platform": "whatsapp",
                                                "label": "Mango Electronics",
                                                "external_catalogue_id": "1122334455",
                                                "external_account_id": "998877",
                                                "public_slug": null,
                                                "is_connected": true,
                                                "last_synced_at": "2026-09-11T02:00:41+00:00"
                                            }
                                        ],
                                        "products_count": 1994,
                                        "orders_count": 12,
                                        "last_synced_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/products": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductList",
                "summary": "List products in a catalogue",
                "description": "Products in the shop, ordered by name. Filter with `search` (name or SKU) and `availability`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "$ref": "#/components/parameters/ProductSearch"
                    },
                    {
                        "$ref": "#/components/parameters/ProductAvailability"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of products.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Product",
                                                        "description": "The product record."
                                                    },
                                                    "description": "The products on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of rows and its page state."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "catalogue_id": 1,
                                                "retailer_id": "ACME-001",
                                                "meta_product_id": null,
                                                "name": "Kanga Print",
                                                "description": null,
                                                "url": null,
                                                "price": 25000,
                                                "currency": "TZS",
                                                "sale_price": null,
                                                "image_url": "https://cdn.acme.co.tz/kanga.jpg",
                                                "availability": "in stock",
                                                "condition": "new",
                                                "brand": null,
                                                "category": null,
                                                "product_type": null,
                                                "inventory": null,
                                                "visibility": "published",
                                                "review_status": null,
                                                "last_synced_at": null,
                                                "created_at": "2026-09-04T19:19:55+00:00",
                                                "updated_at": "2026-09-04T19:19:55+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductCreate",
                "summary": "Add a product to a catalogue",
                "description": "Add one product. `sku` is optional \u2014 the shop issues `AMY-00042` style codes when you send none. The product is stored first and pushed to every platform the shop is on afterwards, so a 201 means it is saved, and `listings` says where it is live.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "name",
                                    "price"
                                ],
                                "description": "A product. Only a name and a price are required here; an image, a non-zero price and the rest are what individual PLATFORMS require, and a product missing them is stored and reported as `blocked` on that platform rather than refused.",
                                "properties": {
                                    "sku": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "Your product code. Left out, the shop issues one."
                                    },
                                    "retailer_id": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "The older name for `sku`."
                                    },
                                    "name": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Product name as customers see it."
                                    },
                                    "price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Price in the minor unit of `currency` \u2014 25000 is TZS 250.00 for a 2-decimal currency."
                                    },
                                    "currency": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 3,
                                        "description": "ISO 4217 code. Left out, the shop's own currency is used."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 9000,
                                        "description": "Long description."
                                    },
                                    "sale_price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Optional sale price in the minor unit. Ignored when it is higher than `price`."
                                    },
                                    "image_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "Publicly reachable image. Platforms fetch it themselves, so it cannot sit behind a login."
                                    },
                                    "additional_image_urls": {
                                        "type": "array",
                                        "maxItems": 10,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "description": "Up to ten more images."
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "The product page on your own site."
                                    },
                                    "availability": {
                                        "type": "string",
                                        "enum": [
                                            "in stock",
                                            "out of stock",
                                            "preorder",
                                            "available for order",
                                            "discontinued"
                                        ],
                                        "description": "Left out, it is derived from `inventory`: a count of zero means `out of stock` unless the shop allows backorders. Sent explicitly, what you send wins."
                                    },
                                    "condition": {
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "refurbished",
                                            "used"
                                        ],
                                        "description": "Item condition."
                                    },
                                    "brand": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Brand name. Becomes a brand record on first use."
                                    },
                                    "category": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Category name. Becomes a category record on first use."
                                    },
                                    "product_type": {
                                        "type": "string",
                                        "maxLength": 750,
                                        "description": "Your own taxonomy path."
                                    },
                                    "inventory": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Units on hand."
                                    },
                                    "visibility": {
                                        "type": "string",
                                        "enum": [
                                            "staging",
                                            "published"
                                        ],
                                        "description": "Whether customers may see it."
                                    },
                                    "custom_labels": {
                                        "type": "array",
                                        "maxItems": 5,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Up to five free labels for your own segmentation."
                                    }
                                }
                            },
                            "example": {
                                "sku": "MNG-45W",
                                "name": "Charger Mango 45W",
                                "price": 4500000,
                                "currency": "TZS",
                                "image_url": "https://cdn.example.com/mng45.jpg",
                                "inventory": 12
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The created product.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 2,
                                        "catalogue_id": 1,
                                        "retailer_id": "ACME-002",
                                        "meta_product_id": null,
                                        "name": "Kitenge 6 yards",
                                        "description": "Wax print, 6 yards.",
                                        "url": null,
                                        "price": 45000,
                                        "currency": "TZS",
                                        "sale_price": null,
                                        "image_url": "https://cdn.acme.co.tz/kitenge.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": null,
                                        "category": null,
                                        "product_type": null,
                                        "inventory": null,
                                        "visibility": "published",
                                        "review_status": null,
                                        "last_synced_at": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "Validation failed, or the `retailer_id` is already used in this catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "missing_fields": {
                                        "summary": "Required fields missing",
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "retailer_id": [
                                                    "The retailer id field is required."
                                                ],
                                                "price": [
                                                    "The price field is required."
                                                ],
                                                "currency": [
                                                    "The currency field is required."
                                                ],
                                                "image_url": [
                                                    "The image url field is required."
                                                ]
                                            }
                                        }
                                    },
                                    "duplicate_sku": {
                                        "summary": "Duplicate retailer_id",
                                        "value": {
                                            "status": "error",
                                            "message": "Retailer ID already exists in this catalogue.",
                                            "errors": {
                                                "retailer_id": [
                                                    "This retailer_id is already used by another product in this catalogue."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/products/batch": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductBatch",
                "summary": "Sync products in bulk",
                "description": "The endpoint a store integration lives on. Send up to 5,000 products; every field in the product schema is stored, not just the identity ones. The call returns **202** with a sync id and the work happens in the background, because pushing a catalogue to a platform takes longer than an HTTP request should.\n\nRead the outcome from `GET /catalogues/{catalogue}/syncs/{sync}`: it names every row that was refused and every product a platform will not show, with the reason for each.\n\nSend an `Idempotency-Key` header on scheduled runs. A repeat of the same key returns the run that already owns it with `replayed: true` and imports nothing, so a cron that times out is safe to retry.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "maxLength": 190,
                            "example": "nightly-2026-09-11"
                        },
                        "description": "Your own name for this run, for example `nightly-2026-09-11`. Repeating it never imports twice."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "products"
                                ],
                                "properties": {
                                    "mode": {
                                        "type": "string",
                                        "enum": [
                                            "upsert",
                                            "replace"
                                        ],
                                        "default": "upsert",
                                        "description": "`upsert` leaves products the payload does not mention alone. `replace` says this payload IS the catalogue and retires everything missing from it \u2014 use it only when you are sending your whole product list."
                                    },
                                    "products": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 5000,
                                        "items": {
                                            "type": "object",
                                            "required": [
                                                "name",
                                                "price"
                                            ],
                                            "description": "A product. Only a name and a price are required here; an image, a non-zero price and the rest are what individual PLATFORMS require, and a product missing them is stored and reported as `blocked` on that platform rather than refused.",
                                            "properties": {
                                                "sku": {
                                                    "type": "string",
                                                    "maxLength": 100,
                                                    "description": "Your product code. Left out, the shop issues one."
                                                },
                                                "retailer_id": {
                                                    "type": "string",
                                                    "maxLength": 100,
                                                    "description": "The older name for `sku`."
                                                },
                                                "name": {
                                                    "type": "string",
                                                    "maxLength": 200,
                                                    "description": "Product name as customers see it."
                                                },
                                                "price": {
                                                    "type": "integer",
                                                    "minimum": 0,
                                                    "description": "Price in the minor unit of `currency` \u2014 25000 is TZS 250.00 for a 2-decimal currency."
                                                },
                                                "currency": {
                                                    "type": "string",
                                                    "minLength": 3,
                                                    "maxLength": 3,
                                                    "description": "ISO 4217 code. Left out, the shop's own currency is used."
                                                },
                                                "description": {
                                                    "type": "string",
                                                    "maxLength": 9000,
                                                    "description": "Long description."
                                                },
                                                "sale_price": {
                                                    "type": "integer",
                                                    "minimum": 0,
                                                    "description": "Optional sale price in the minor unit. Ignored when it is higher than `price`."
                                                },
                                                "image_url": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048,
                                                    "description": "Publicly reachable image. Platforms fetch it themselves, so it cannot sit behind a login."
                                                },
                                                "additional_image_urls": {
                                                    "type": "array",
                                                    "maxItems": 10,
                                                    "items": {
                                                        "type": "string",
                                                        "format": "uri"
                                                    },
                                                    "description": "Up to ten more images."
                                                },
                                                "url": {
                                                    "type": "string",
                                                    "format": "uri",
                                                    "maxLength": 2048,
                                                    "description": "The product page on your own site."
                                                },
                                                "availability": {
                                                    "type": "string",
                                                    "enum": [
                                                        "in stock",
                                                        "out of stock",
                                                        "preorder",
                                                        "available for order",
                                                        "discontinued"
                                                    ],
                                                    "description": "Left out, it is derived from `inventory`: a count of zero means `out of stock` unless the shop allows backorders. Sent explicitly, what you send wins."
                                                },
                                                "condition": {
                                                    "type": "string",
                                                    "enum": [
                                                        "new",
                                                        "refurbished",
                                                        "used"
                                                    ],
                                                    "description": "Item condition."
                                                },
                                                "brand": {
                                                    "type": "string",
                                                    "maxLength": 255,
                                                    "description": "Brand name. Becomes a brand record on first use."
                                                },
                                                "category": {
                                                    "type": "string",
                                                    "maxLength": 255,
                                                    "description": "Category name. Becomes a category record on first use."
                                                },
                                                "product_type": {
                                                    "type": "string",
                                                    "maxLength": 750,
                                                    "description": "Your own taxonomy path."
                                                },
                                                "inventory": {
                                                    "type": "integer",
                                                    "minimum": 0,
                                                    "description": "Units on hand."
                                                },
                                                "visibility": {
                                                    "type": "string",
                                                    "enum": [
                                                        "staging",
                                                        "published"
                                                    ],
                                                    "description": "Whether customers may see it."
                                                },
                                                "custom_labels": {
                                                    "type": "array",
                                                    "maxItems": 5,
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Up to five free labels for your own segmentation."
                                                }
                                            }
                                        },
                                        "description": "The products. A row that cannot be stored is reported in the sync report as one rejected row; it does not refuse the rest of the file."
                                    }
                                }
                            },
                            "example": {
                                "mode": "upsert",
                                "products": [
                                    {
                                        "sku": "MNG-45W",
                                        "name": "Charger Mango 45W",
                                        "description": "USB-C PD, 1 m cable",
                                        "price": 4500000,
                                        "currency": "TZS",
                                        "sale_price": 3900000,
                                        "image_url": "https://cdn.example.com/mng45.jpg",
                                        "inventory": 12,
                                        "availability": "in stock",
                                        "brand": "Mango",
                                        "category": "Chargers"
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "The sync was accepted. Poll it for the outcome.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CatalogueSync",
                                            "description": "The sync that was accepted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 812,
                                        "catalogue_id": 42,
                                        "source": "api",
                                        "mode": "upsert",
                                        "status": "queued",
                                        "idempotency_key": "nightly-2026-09-11",
                                        "received": 2000,
                                        "created": 0,
                                        "updated": 0,
                                        "unchanged": 0,
                                        "rejected": 0,
                                        "retired": 0,
                                        "platforms": {
                                            "whatsapp": {
                                                "pending": 0
                                            }
                                        },
                                        "problems": [],
                                        "problems_truncated": false,
                                        "error": null,
                                        "started_at": null,
                                        "finished_at": null,
                                        "created_at": "2026-09-11T02:00:04+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/products/{product}": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductShow",
                "summary": "Read one product",
                "description": "One product from a catalogue. A product that exists but sits in a different catalogue answers `404`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The product.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 1,
                                        "catalogue_id": 1,
                                        "retailer_id": "ACME-001",
                                        "meta_product_id": null,
                                        "name": "Kanga Print",
                                        "description": null,
                                        "url": null,
                                        "price": 25000,
                                        "currency": "TZS",
                                        "sale_price": null,
                                        "image_url": "https://cdn.acme.co.tz/kanga.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": null,
                                        "category": null,
                                        "product_type": null,
                                        "inventory": null,
                                        "visibility": "published",
                                        "review_status": null,
                                        "last_synced_at": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "put": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductUpdate",
                "summary": "Update a product",
                "description": "Change one product. Only the fields you send are touched, so sending `{\"inventory\": 0}` is a stock update and nothing else. The product code cannot be changed here \u2014 it is the identity platforms know the item by.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [],
                                "description": "A product. Only a name and a price are required here; an image, a non-zero price and the rest are what individual PLATFORMS require, and a product missing them is stored and reported as `blocked` on that platform rather than refused.",
                                "properties": {
                                    "sku": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "Your product code. Left out, the shop issues one."
                                    },
                                    "retailer_id": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "The older name for `sku`."
                                    },
                                    "name": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Product name as customers see it."
                                    },
                                    "price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Price in the minor unit of `currency` \u2014 25000 is TZS 250.00 for a 2-decimal currency."
                                    },
                                    "currency": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 3,
                                        "description": "ISO 4217 code. Left out, the shop's own currency is used."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 9000,
                                        "description": "Long description."
                                    },
                                    "sale_price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Optional sale price in the minor unit. Ignored when it is higher than `price`."
                                    },
                                    "image_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "Publicly reachable image. Platforms fetch it themselves, so it cannot sit behind a login."
                                    },
                                    "additional_image_urls": {
                                        "type": "array",
                                        "maxItems": 10,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "description": "Up to ten more images."
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "The product page on your own site."
                                    },
                                    "availability": {
                                        "type": "string",
                                        "enum": [
                                            "in stock",
                                            "out of stock",
                                            "preorder",
                                            "available for order",
                                            "discontinued"
                                        ],
                                        "description": "Left out, it is derived from `inventory`: a count of zero means `out of stock` unless the shop allows backorders. Sent explicitly, what you send wins."
                                    },
                                    "condition": {
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "refurbished",
                                            "used"
                                        ],
                                        "description": "Item condition."
                                    },
                                    "brand": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Brand name. Becomes a brand record on first use."
                                    },
                                    "category": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Category name. Becomes a category record on first use."
                                    },
                                    "product_type": {
                                        "type": "string",
                                        "maxLength": 750,
                                        "description": "Your own taxonomy path."
                                    },
                                    "inventory": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Units on hand."
                                    },
                                    "visibility": {
                                        "type": "string",
                                        "enum": [
                                            "staging",
                                            "published"
                                        ],
                                        "description": "Whether customers may see it."
                                    },
                                    "custom_labels": {
                                        "type": "array",
                                        "maxItems": 5,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Up to five free labels for your own segmentation."
                                    }
                                }
                            },
                            "example": {
                                "price": 4200000,
                                "inventory": 7
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated product.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 1,
                                        "catalogue_id": 1,
                                        "retailer_id": "ACME-001",
                                        "meta_product_id": null,
                                        "name": "Kanga Print",
                                        "description": null,
                                        "url": null,
                                        "price": 27000,
                                        "currency": "TZS",
                                        "sale_price": null,
                                        "image_url": "https://cdn.acme.co.tz/kanga.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": null,
                                        "category": null,
                                        "product_type": null,
                                        "inventory": null,
                                        "visibility": "published",
                                        "review_status": null,
                                        "last_synced_at": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueProductDelete",
                "summary": "Delete a product",
                "description": "Removes the product from the catalogue, and from Meta first when it was mirrored there.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "$ref": "#/components/parameters/ProductId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The product was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "deleted",
                                                "id"
                                            ],
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true."
                                                },
                                                "id": {
                                                    "type": "integer",
                                                    "description": "Id of the deleted product."
                                                },
                                                "retailer_id": {
                                                    "type": "string",
                                                    "description": "SKU of the deleted product, free to reuse now."
                                                }
                                            },
                                            "description": "What was deleted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "id": 1,
                                        "retailer_id": "ACME-001"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/orders": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueOrderList",
                "summary": "List orders",
                "description": "Orders customers submitted from a WhatsApp cart, newest first. Filter by `status`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/OrderStatusFilter"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/PerPage"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "example": "2026-09-11T02:00:00+00:00"
                        },
                        "description": "Only orders changed at or after this moment, newest change first. This is how you recover from a webhook you missed."
                    },
                    {
                        "name": "platform",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "whatsapp"
                        },
                        "description": "Only orders that arrived through this platform."
                    },
                    {
                        "name": "catalogue_id",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "example": 42
                        },
                        "description": "Only orders against this shop."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of orders.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items",
                                                "pagination"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Order",
                                                        "description": "The order record."
                                                    },
                                                    "description": "The orders on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state for this list: where you are and whether more pages follow."
                                                }
                                            },
                                            "description": "A page of rows and its page state."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 1,
                                                "catalogue_id": 1,
                                                "catalogue": {
                                                    "id": 1,
                                                    "name": "Acme Duka"
                                                },
                                                "customer_wa_id": "255700111222",
                                                "customer_name": "Asha Mrisho",
                                                "customer_phone": null,
                                                "customer_note": null,
                                                "product_items": [
                                                    {
                                                        "product_retailer_id": "ACME-001",
                                                        "quantity": 2,
                                                        "item_price": 25000,
                                                        "currency": "TZS"
                                                    }
                                                ],
                                                "total_amount": 50000,
                                                "total_currency": "TZS",
                                                "status": "pending",
                                                "gateway_message_id": null,
                                                "created_at": "2026-09-04T19:19:55+00:00",
                                                "updated_at": "2026-09-04T19:19:55+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/orders/{order}": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueOrderShow",
                "summary": "Read one order",
                "description": "One order with its cart lines and the catalogue it came from.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/OrderId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The order.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Order",
                                            "description": "The order record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 1,
                                        "catalogue_id": 1,
                                        "catalogue": {
                                            "id": 1,
                                            "name": "Acme Duka"
                                        },
                                        "customer_wa_id": "255700111222",
                                        "customer_name": "Asha Mrisho",
                                        "customer_phone": null,
                                        "customer_note": null,
                                        "product_items": [
                                            {
                                                "product_retailer_id": "ACME-001",
                                                "quantity": 2,
                                                "item_price": 25000,
                                                "currency": "TZS"
                                            }
                                        ],
                                        "total_amount": 50000,
                                        "total_currency": "TZS",
                                        "status": "pending",
                                        "gateway_message_id": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/orders/{order}/status": {
            "put": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueOrderStatusUpdate",
                "summary": "Move an order to another status",
                "description": "Records a fulfilment transition. Each move is appended to the order history, and when the shop has status templates configured the customer is notified on WhatsApp.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/OrderId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "status"
                                ],
                                "properties": {
                                    "status": {
                                        "type": "string",
                                        "enum": [
                                            "pending",
                                            "confirmed",
                                            "processing",
                                            "shipped",
                                            "delivered",
                                            "cancelled",
                                            "refunded"
                                        ],
                                        "description": "The status to move to."
                                    }
                                }
                            },
                            "examples": {
                                "confirm": {
                                    "summary": "Confirm a new order",
                                    "value": {
                                        "status": "confirmed"
                                    }
                                },
                                "ship": {
                                    "summary": "Mark shipped",
                                    "value": {
                                        "status": "shipped"
                                    }
                                },
                                "cancel": {
                                    "summary": "Cancel",
                                    "value": {
                                        "status": "cancelled"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The order in its new status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Order",
                                            "description": "The order record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 1,
                                        "catalogue_id": 1,
                                        "catalogue": {
                                            "id": 1,
                                            "name": "Acme Duka"
                                        },
                                        "customer_wa_id": "255700111222",
                                        "customer_name": "Asha Mrisho",
                                        "customer_phone": null,
                                        "customer_note": null,
                                        "product_items": [
                                            {
                                                "product_retailer_id": "ACME-001",
                                                "quantity": 2,
                                                "item_price": 25000,
                                                "currency": "TZS"
                                            }
                                        ],
                                        "total_amount": 50000,
                                        "total_currency": "TZS",
                                        "status": "confirmed",
                                        "gateway_message_id": null,
                                        "created_at": "2026-09-04T19:19:55+00:00",
                                        "updated_at": "2026-09-04T19:19:55+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "description": "Unknown status value.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Validation failed.",
                                    "errors": {
                                        "status": [
                                            "The selected status is invalid."
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/send-product": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueSendProduct",
                "summary": "Send one product into a chat, on any platform",
                "description": "With `platform: whatsapp` (the default) this is Meta's interactive product message: the customer sees a card and can add to cart. It needs `to`, the provider `catalogue_id` and `product_retailer_id`.\n\nWith any other platform the honest answer is a **link**. The response carries the product's address on that platform and the endpoint to send it with \u2014 one send path for every platform, rather than one per platform. A product that is not published there, or a platform with nowhere to point at, is refused with a 422 that says so.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "product_retailer_id"
                                ],
                                "properties": {
                                    "platform": {
                                        "type": "string",
                                        "enum": [
                                            "whatsapp",
                                            "storefront",
                                            "facebook",
                                            "instagram",
                                            "tiktok"
                                        ],
                                        "default": "whatsapp",
                                        "description": "Where the product should be shown. Defaults to WhatsApp."
                                    },
                                    "to": {
                                        "type": "string",
                                        "description": "Customer's WhatsApp number in E.164 without +. Required on WhatsApp only."
                                    },
                                    "catalogue_id": {
                                        "type": "string",
                                        "description": "Meta catalogue id of the connected shop. Required on WhatsApp only."
                                    },
                                    "product_retailer_id": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "SKU of the product to show."
                                    },
                                    "body": {
                                        "type": "string",
                                        "maxLength": 1024,
                                        "description": "Message text above the product card."
                                    },
                                    "footer": {
                                        "type": "string",
                                        "maxLength": 60,
                                        "description": "Small footer text."
                                    },
                                    "from": {
                                        "type": "string",
                                        "description": "Send from this WhatsApp number when the tenant has several. Defaults to the account default. `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself)."
                                    }
                                }
                            },
                            "example": {
                                "to": "255700111222",
                                "catalogue_id": "1234567890",
                                "product_retailer_id": "ACME-001",
                                "body": "Here is the kanga you asked about.",
                                "footer": "Acme Duka"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "On WhatsApp, the gateway message id. On any other platform, the link to send.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "oneOf": [
                                                {
                                                    "type": "object",
                                                    "properties": {
                                                        "message_id": {
                                                            "type": "string",
                                                            "description": "The gateway message id, on WhatsApp."
                                                        }
                                                    }
                                                },
                                                {
                                                    "type": "object",
                                                    "properties": {
                                                        "platform": {
                                                            "type": "string",
                                                            "description": "The platform asked for."
                                                        },
                                                        "sku": {
                                                            "type": "string",
                                                            "description": "The product code."
                                                        },
                                                        "link": {
                                                            "type": "string",
                                                            "format": "uri",
                                                            "description": "Where the product lives on that platform."
                                                        },
                                                        "state": {
                                                            "type": "string",
                                                            "description": "The listing state there."
                                                        },
                                                        "send_with": {
                                                            "type": "string",
                                                            "description": "The endpoint to send the link with."
                                                        }
                                                    }
                                                }
                                            ],
                                            "description": "A message id on WhatsApp; a link everywhere else."
                                        }
                                    }
                                },
                                "examples": {
                                    "whatsapp": {
                                        "summary": "Sent as an interactive message",
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "message_id": "wamid.HBgL\u2026"
                                            }
                                        }
                                    },
                                    "storefront": {
                                        "summary": "A link to send",
                                        "value": {
                                            "status": "success",
                                            "data": {
                                                "platform": "storefront",
                                                "sku": "MNG-45W",
                                                "link": "https://business.momo.tz/shop/mango/p/MNG-45W",
                                                "state": "synced",
                                                "send_with": "/api/v3/whatsapp/send"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "description": "Validation failed, or the tenant has no active WhatsApp channel.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "no_channel": {
                                        "summary": "No WhatsApp channel connected",
                                        "value": {
                                            "status": "error",
                                            "message": "No WhatsApp channel configured."
                                        }
                                    },
                                    "validation": {
                                        "summary": "Missing fields",
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "to": [
                                                    "The to field is required."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            }
        },
        "/api/v3/catalogues/send-product-list": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueSendProductList",
                "summary": "Send a multi-product list to a customer",
                "description": "Sends a multi-product message: up to 10 sections of products the customer can browse and add to a cart.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "to",
                                    "catalogue_id",
                                    "header_text",
                                    "body",
                                    "sections"
                                ],
                                "properties": {
                                    "to": {
                                        "type": "string",
                                        "description": "Customer's WhatsApp number in E.164 without +."
                                    },
                                    "catalogue_id": {
                                        "type": "string",
                                        "description": "Meta catalogue id of the connected shop."
                                    },
                                    "header_text": {
                                        "type": "string",
                                        "maxLength": 60,
                                        "description": "Bold header above the list."
                                    },
                                    "body": {
                                        "type": "string",
                                        "maxLength": 1024,
                                        "description": "Message text."
                                    },
                                    "footer": {
                                        "type": "string",
                                        "maxLength": 60,
                                        "description": "Small footer text."
                                    },
                                    "sections": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 10,
                                        "description": "Product groups, in display order.",
                                        "items": {
                                            "type": "object",
                                            "required": [
                                                "title",
                                                "product_items"
                                            ],
                                            "properties": {
                                                "title": {
                                                    "type": "string",
                                                    "maxLength": 24,
                                                    "description": "Section heading."
                                                },
                                                "product_items": {
                                                    "type": "array",
                                                    "minItems": 1,
                                                    "description": "Products in the section.",
                                                    "items": {
                                                        "type": "object",
                                                        "required": [
                                                            "product_retailer_id"
                                                        ],
                                                        "properties": {
                                                            "product_retailer_id": {
                                                                "type": "string",
                                                                "maxLength": 100,
                                                                "description": "SKU to include."
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                    },
                                    "from": {
                                        "type": "string",
                                        "description": "Send from this WhatsApp number when the tenant has several. `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself)."
                                    }
                                }
                            },
                            "example": {
                                "to": "255700111222",
                                "catalogue_id": "1234567890",
                                "header_text": "New this week",
                                "body": "Pick what you like and add it to your cart.",
                                "footer": "Acme Duka",
                                "sections": [
                                    {
                                        "title": "Kanga",
                                        "product_items": [
                                            {
                                                "product_retailer_id": "ACME-001"
                                            },
                                            {
                                                "product_retailer_id": "ACME-002"
                                            }
                                        ]
                                    },
                                    {
                                        "title": "Vitenge",
                                        "product_items": [
                                            {
                                                "product_retailer_id": "ACME-101"
                                            }
                                        ]
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "WhatsApp accepted the message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "message_id"
                                            ],
                                            "properties": {
                                                "message_id": {
                                                    "type": "string",
                                                    "description": "The WhatsApp message id (`wamid.\u2026`) to match against later message.* webhooks."
                                                }
                                            },
                                            "description": "The message WhatsApp accepted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "message_id": "wamid.HBgLMjU1NzAwMTExMjIyFQIAERgSN0YzNzhBQTQ5MzBBM0YwQzE2AA=="
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "description": "Validation failed, or the tenant has no active WhatsApp channel.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "no_channel": {
                                        "summary": "No WhatsApp channel connected",
                                        "value": {
                                            "status": "error",
                                            "message": "No WhatsApp channel configured."
                                        }
                                    },
                                    "validation": {
                                        "summary": "Missing fields",
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "to": [
                                                    "The to field is required."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            }
        },
        "/api/v3/catalogues/send-catalogue": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueSendCatalogue",
                "summary": "Send the whole catalogue to a customer",
                "description": "Sends a catalogue message: an invitation to browse the full shop, optionally showing one product as the thumbnail.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "to",
                                    "body"
                                ],
                                "properties": {
                                    "to": {
                                        "type": "string",
                                        "description": "Customer's WhatsApp number in E.164 without +."
                                    },
                                    "body": {
                                        "type": "string",
                                        "maxLength": 1024,
                                        "description": "Message text."
                                    },
                                    "thumbnail_product_retailer_id": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "SKU to use as the cover image. Defaults to the first product."
                                    },
                                    "footer": {
                                        "type": "string",
                                        "maxLength": 60,
                                        "description": "Small footer text."
                                    },
                                    "from": {
                                        "type": "string",
                                        "description": "Send from this WhatsApp number when the tenant has several. `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself)."
                                    }
                                }
                            },
                            "example": {
                                "to": "255700111222",
                                "body": "Karibu! Browse our full catalogue here.",
                                "thumbnail_product_retailer_id": "ACME-001",
                                "footer": "Acme Duka"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "WhatsApp accepted the message.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "message_id"
                                            ],
                                            "properties": {
                                                "message_id": {
                                                    "type": "string",
                                                    "description": "The WhatsApp message id (`wamid.\u2026`) to match against later message.* webhooks."
                                                }
                                            },
                                            "description": "The message WhatsApp accepted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "message_id": "wamid.HBgLMjU1NzAwMTExMjIyFQIAERgSN0YzNzhBQTQ5MzBBM0YwQzE2AA=="
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "422": {
                        "description": "Validation failed, or the tenant has no active WhatsApp channel.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "no_channel": {
                                        "summary": "No WhatsApp channel connected",
                                        "value": {
                                            "status": "error",
                                            "message": "No WhatsApp channel configured."
                                        }
                                    },
                                    "validation": {
                                        "summary": "Missing fields",
                                        "value": {
                                            "status": "error",
                                            "message": "Validation failed.",
                                            "errors": {
                                                "to": [
                                                    "The to field is required."
                                                ]
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            }
        },
        "/api/v3/data/tables": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataTablesList",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "List data tables",
                "description": "Every table this tenant has defined, by name. Take the `id` into the other endpoints; the schema endpoint tells you what each table holds.",
                "responses": {
                    "200": {
                        "description": "The tables.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "tables"
                                    ],
                                    "properties": {
                                        "tables": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DataTable"
                                            },
                                            "description": "The tables, ordered by name."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "tables": [
                                                {
                                                    "id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                    "name": "Customers",
                                                    "slug": "customers",
                                                    "description": "Everyone who has bought from us.",
                                                    "icon": "users",
                                                    "records_count": 1286,
                                                    "columns_count": 6,
                                                    "updated_at": "2026-09-07T14:02:31+00:00"
                                                },
                                                {
                                                    "id": "4e8d9c0b-1a2f-4b3c-8d4e-5f6a7b8c9d0e",
                                                    "name": "Deliveries",
                                                    "slug": "deliveries",
                                                    "description": null,
                                                    "icon": null,
                                                    "records_count": 52014,
                                                    "columns_count": 9,
                                                    "updated_at": "2026-09-08T06:15:00+00:00"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/tables/{table}/schema": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataTableSchema",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "Read a table's schema",
                "description": "The columns of a table \u2014 key, type, whether required or unique, the validation rules a write runs and the operators a filter may use \u2014 plus what every type can do, the system columns, quota usage and what this key is allowed to do. Read it once before writing records, and again after a column changes in the dashboard.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The schema.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataSchema"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "table": {
                                                "id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                "name": "Customers",
                                                "slug": "customers",
                                                "description": "Everyone who has bought from us.",
                                                "icon": "users",
                                                "records_count": 1286,
                                                "storage_bytes": 418304,
                                                "title_column": "name",
                                                "created_at": "2026-08-30T09:00:00+00:00",
                                                "updated_at": "2026-09-07T14:02:31+00:00"
                                            },
                                            "columns": [
                                                {
                                                    "id": "6a1b2c3d-0000-4000-8000-000000000001",
                                                    "key": "name",
                                                    "label": "Name",
                                                    "type": "text",
                                                    "position": 0,
                                                    "required": true,
                                                    "unique": false,
                                                    "indexed": false,
                                                    "index_status": null,
                                                    "index_error": null,
                                                    "config": {
                                                        "ui": {
                                                            "is_title_field": true
                                                        }
                                                    },
                                                    "rules": [
                                                        "required",
                                                        "string",
                                                        "max:255"
                                                    ],
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "contains",
                                                        "starts_with",
                                                        "is_empty",
                                                        "is_not_empty",
                                                        "in"
                                                    ],
                                                    "ui": {
                                                        "is_title_field": true,
                                                        "cell": "text",
                                                        "input": "text",
                                                        "filter": "text",
                                                        "width": 200
                                                    }
                                                },
                                                {
                                                    "id": "6a1b2c3d-0000-4000-8000-000000000002",
                                                    "key": "phone",
                                                    "label": "Simu",
                                                    "type": "phone",
                                                    "position": 1,
                                                    "required": true,
                                                    "unique": true,
                                                    "indexed": true,
                                                    "index_status": "ready",
                                                    "index_error": null,
                                                    "config": {
                                                        "region": "TZ"
                                                    },
                                                    "rules": [
                                                        "required",
                                                        "phone:TZ"
                                                    ],
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "starts_with",
                                                        "contains",
                                                        "is_empty",
                                                        "is_not_empty",
                                                        "in"
                                                    ],
                                                    "ui": {
                                                        "cell": "phone",
                                                        "input": "phone",
                                                        "filter": "text",
                                                        "width": 160
                                                    }
                                                },
                                                {
                                                    "id": "6a1b2c3d-0000-4000-8000-000000000003",
                                                    "key": "region",
                                                    "label": "Region",
                                                    "type": "select",
                                                    "position": 2,
                                                    "required": false,
                                                    "unique": false,
                                                    "indexed": false,
                                                    "index_status": null,
                                                    "index_error": null,
                                                    "config": {
                                                        "options": [
                                                            {
                                                                "key": "dar",
                                                                "label": "Dar es Salaam"
                                                            },
                                                            {
                                                                "key": "arusha",
                                                                "label": "Arusha"
                                                            }
                                                        ]
                                                    },
                                                    "rules": [
                                                        "in:dar,arusha"
                                                    ],
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "is_empty",
                                                        "is_not_empty",
                                                        "in"
                                                    ],
                                                    "ui": {
                                                        "cell": "select",
                                                        "input": "select",
                                                        "filter": "select",
                                                        "width": 140
                                                    }
                                                },
                                                {
                                                    "id": "6a1b2c3d-0000-4000-8000-000000000004",
                                                    "key": "opt_in",
                                                    "label": "Opted in",
                                                    "type": "boolean",
                                                    "position": 3,
                                                    "required": false,
                                                    "unique": false,
                                                    "indexed": false,
                                                    "index_status": null,
                                                    "index_error": null,
                                                    "config": [],
                                                    "rules": [
                                                        "boolean"
                                                    ],
                                                    "operators": [
                                                        "equals",
                                                        "is_empty",
                                                        "is_not_empty"
                                                    ],
                                                    "ui": {
                                                        "cell": "boolean",
                                                        "input": "checkbox",
                                                        "filter": "boolean",
                                                        "width": 100
                                                    }
                                                },
                                                {
                                                    "id": "6a1b2c3d-0000-4000-8000-000000000005",
                                                    "key": "balance",
                                                    "label": "Balance",
                                                    "type": "currency",
                                                    "position": 4,
                                                    "required": false,
                                                    "unique": false,
                                                    "indexed": false,
                                                    "index_status": null,
                                                    "index_error": null,
                                                    "config": {
                                                        "currency": "TZS"
                                                    },
                                                    "rules": [
                                                        "numeric"
                                                    ],
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "greater_than",
                                                        "less_than",
                                                        "between",
                                                        "is_empty",
                                                        "is_not_empty"
                                                    ],
                                                    "ui": {
                                                        "cell": "currency",
                                                        "input": "number",
                                                        "filter": "number",
                                                        "width": 140
                                                    }
                                                }
                                            ],
                                            "types": {
                                                "text": {
                                                    "label": "Text",
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "contains",
                                                        "starts_with",
                                                        "is_empty",
                                                        "is_not_empty",
                                                        "in"
                                                    ],
                                                    "ui": {
                                                        "cell": "text",
                                                        "input": "text",
                                                        "filter": "text",
                                                        "width": 200
                                                    },
                                                    "numeric": false,
                                                    "temporal": false
                                                },
                                                "phone": {
                                                    "label": "Phone",
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "starts_with",
                                                        "contains",
                                                        "is_empty",
                                                        "is_not_empty",
                                                        "in"
                                                    ],
                                                    "ui": {
                                                        "cell": "phone",
                                                        "input": "phone",
                                                        "filter": "text",
                                                        "width": 160
                                                    },
                                                    "numeric": false,
                                                    "temporal": false
                                                },
                                                "datetime": {
                                                    "label": "Date & time",
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "greater_than",
                                                        "less_than",
                                                        "between",
                                                        "is_empty",
                                                        "is_not_empty"
                                                    ],
                                                    "ui": {
                                                        "cell": "datetime",
                                                        "input": "datetime",
                                                        "filter": "date",
                                                        "width": 180
                                                    },
                                                    "numeric": false,
                                                    "temporal": true
                                                }
                                            },
                                            "system_columns": [
                                                {
                                                    "key": "$id",
                                                    "label": "ID",
                                                    "type": "relation",
                                                    "operators": [
                                                        "equals",
                                                        "in"
                                                    ]
                                                },
                                                {
                                                    "key": "$created_at",
                                                    "label": "Created",
                                                    "type": "datetime",
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "greater_than",
                                                        "less_than",
                                                        "between"
                                                    ]
                                                },
                                                {
                                                    "key": "$updated_at",
                                                    "label": "Updated",
                                                    "type": "datetime",
                                                    "operators": [
                                                        "equals",
                                                        "not_equals",
                                                        "greater_than",
                                                        "less_than",
                                                        "between"
                                                    ]
                                                },
                                                {
                                                    "key": "$source",
                                                    "label": "Source",
                                                    "type": "text",
                                                    "operators": [
                                                        "equals",
                                                        "in",
                                                        "starts_with"
                                                    ]
                                                }
                                            ],
                                            "limits": {
                                                "columns": {
                                                    "used": 5,
                                                    "max": 40
                                                },
                                                "indexes": {
                                                    "used": 1,
                                                    "max": 5
                                                },
                                                "records": {
                                                    "used": 1286,
                                                    "max": 500000
                                                },
                                                "storage": {
                                                    "used_bytes": 418304,
                                                    "max_bytes": 2147483648
                                                }
                                            },
                                            "sort_index_threshold": 20000,
                                            "can": {
                                                "manage": true,
                                                "edit_records": true,
                                                "manage_reports": true
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No table with that id for this tenant (or the id is not a UUID).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/tables/{table}/records": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordsList",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "List records",
                "description": "Returns a keyset page, default limit 50 and maximum 200, with optional JSON condition-tree filter and q text search. Preserve filter/q/sort/dir when sending next_cursor back as cursor. Invalid cursor text restarts at page one. Count is null unless with_count is enabled. At or above sort_index_threshold, user-column sorts need an index; unsupported sorts/operators return 501 not_supported.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    },
                    {
                        "name": "filter",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "URL-encoded JSON condition tree, with all/any groups or column/op/value leaves. Malformed filters/unknown columns return 422; unsupported field operators return 501.",
                        "example": "{\"all\":[{\"column\":\"opt_in\",\"op\":\"equals\",\"value\":true},{\"any\":[{\"column\":\"region\",\"op\":\"in\",\"value\":[\"dar\",\"arusha\"]},{\"column\":\"$created_at\",\"op\":\"greater_than\",\"value\":{\"relative\":\"last_7_days\"}}]}]}"
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Free-text search, case-insensitive, over up to six text-like columns (text, long_text, phone, email). Ignored on a table with none.",
                        "example": "asha"
                    },
                    {
                        "name": "sort",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "$created_at"
                        },
                        "description": "Column key to sort on, or `$created_at` / `$updated_at`. Nulls sort last. Omit for newest first.",
                        "example": "balance"
                    },
                    {
                        "name": "dir",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "asc",
                                "desc"
                            ],
                            "default": "desc"
                        },
                        "description": "Sort direction. Anything else answers 422.",
                        "example": "desc"
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string"
                        },
                        "description": "The `next_cursor` of the previous page. Send the same `filter`, `q`, `sort` and `dir` with it. Opaque: a cursor that does not decode starts again from the first page rather than failing.",
                        "example": "eyJjIjoiMjAyNi0wOS0wOFQwNzo0MToxMi40MTgyMDZaIiwiaSI6IjJjN2UxYTliLTNkNGYtNGE1Yi04YzZkLTdlOGY5YTBiMWMyZCJ9"
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 200,
                            "default": 50
                        },
                        "description": "Records per page, 1\u2013200. Values above 200 are clamped, not refused.",
                        "example": 50
                    },
                    {
                        "name": "with_count",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false
                        },
                        "description": "Also count every record matching `filter` and `q`, into `count`. Costs a second query \u2014 ask on the first page only.",
                        "example": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of records.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataRecordPage"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "records": [
                                                {
                                                    "id": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                                    "data": {
                                                        "name": "Asha Mwinyi",
                                                        "phone": "+255712345678",
                                                        "region": "dar",
                                                        "opt_in": true,
                                                        "balance": 15000
                                                    },
                                                    "source": "api",
                                                    "created_at": "2026-09-08T07:41:12.418206Z",
                                                    "updated_at": "2026-09-08T07:41:12.418206Z",
                                                    "title": "Asha Mwinyi"
                                                },
                                                {
                                                    "id": "7f3a2b1c-9d8e-4f7a-b6c5-d4e3f2a1b0c9",
                                                    "data": {
                                                        "name": "Juma Hassan",
                                                        "phone": "+255754000111",
                                                        "region": "arusha",
                                                        "opt_in": true,
                                                        "balance": 2500
                                                    },
                                                    "source": "ui",
                                                    "created_at": "2026-09-06T11:03:44.902113Z",
                                                    "updated_at": "2026-09-07T08:20:01.117650Z",
                                                    "title": "Juma Hassan"
                                                }
                                            ],
                                            "next_cursor": "eyJjIjoiMjAyNi0wOS0wNlQxMTowMzo0NC45MDIxMTNaIiwiaSI6IjdmM2EyYjFjLTlkOGUtNGY3YS1iNmM1LWQ0ZTNmMmExYjBjOSJ9",
                                            "has_more": true,
                                            "count": 1286,
                                            "served_at": "2026-09-08T07:45:00Z"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No table with that id for this tenant (or the id is not a UUID).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Malformed query or invalid record value. Missing request data may use the standard v3 envelope; expected data refusals use DataError.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        },
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "validation_error",
                                                "message": "The supplied data or query is invalid.",
                                                "retryable": false
                                            },
                                            "message": "The supplied data or query is invalid.",
                                            "code": "validation_error"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "501": {
                        "description": "The field type does not support the operator, or this sort needs an index.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "not_supported",
                                                "message": "Refused (sort_needs_index): Index the column 'region' to sort on it.",
                                                "retryable": false,
                                                "field": "region",
                                                "details": {
                                                    "reason": "sort_needs_index"
                                                }
                                            },
                                            "message": "Refused (sort_needs_index): Index the column 'region' to sort on it.",
                                            "code": "not_supported"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "post": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordsCreate",
                "x-permission": "data.records.edit",
                "x-permission-scope": "controller",
                "summary": "Create a record",
                "description": "Adds one record. Every key in `data` is validated and coerced through its column's type (a phone becomes E.164, a number becomes a number), required columns must be present, unique columns must not collide, and the whole record must fit in 8 KB. The record is stamped `source: \"api\"`.\n\nKeys that are not columns of the table are refused, so read the schema first.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "data"
                                ],
                                "properties": {
                                    "data": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "The values, keyed by column key. Every required column must be present; other columns may be omitted."
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "data": {
                                            "name": "Asha Mwinyi",
                                            "phone": "0712345678",
                                            "region": "dar",
                                            "opt_in": true,
                                            "balance": 15000
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "Created. The record as stored, values coerced.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "record"
                                    ],
                                    "properties": {
                                        "record": {
                                            "$ref": "#/components/schemas/DataRecord",
                                            "description": "The record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "record": {
                                                "id": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                                "data": {
                                                    "name": "Asha Mwinyi",
                                                    "phone": "+255712345678",
                                                    "region": "dar",
                                                    "opt_in": true,
                                                    "balance": 15000
                                                },
                                                "source": "api",
                                                "created_at": "2026-09-08T07:41:12.418206Z",
                                                "updated_at": "2026-09-08T07:41:12.418206Z",
                                                "title": "Asha Mwinyi"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key issuer or table grant forbids the write, or a state transition requires a permission the caller lacks.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        },
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        }
                                    ]
                                },
                                "example": {
                                    "status": "error",
                                    "message": "You do not have permission to perform this action."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No table with that id for this tenant (or the id is not a UUID).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Malformed query or invalid record value. Missing request data may use the standard v3 envelope; expected data refusals use DataError.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        },
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "validation_error",
                                                "message": "The supplied data or query is invalid.",
                                                "retryable": false
                                            },
                                            "message": "The supplied data or query is invalid.",
                                            "code": "validation_error"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "402": {
                        "description": "Table/account quota prevents storage; error.details names the quota and allowance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "quota_exceeded",
                                                "message": "The table has reached its record allowance.",
                                                "retryable": false,
                                                "details": {
                                                    "quota": "quota_records",
                                                    "limit": 500000,
                                                    "used": 500000
                                                }
                                            },
                                            "message": "The table has reached its record allowance.",
                                            "code": "quota_exceeded"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "A unique-value or status-transition conflict prevented the write.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "conflict",
                                                "message": "The record was refused. A unique value or state transition conflicts with current data.",
                                                "retryable": false
                                            },
                                            "message": "The record was refused. A unique value or state transition conflicts with current data.",
                                            "code": "conflict"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v3/data/tables/{table}/records/{record}": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordsGet",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "Read a record",
                "description": "One record by id. A deleted record is a 404.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    },
                    {
                        "$ref": "#/components/parameters/DataRecordId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "record"
                                    ],
                                    "properties": {
                                        "record": {
                                            "$ref": "#/components/schemas/DataRecord",
                                            "description": "The record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "record": {
                                                "id": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                                "data": {
                                                    "name": "Asha Mwinyi",
                                                    "phone": "+255712345678",
                                                    "region": "dar",
                                                    "opt_in": true,
                                                    "balance": 15000
                                                },
                                                "source": "api",
                                                "created_at": "2026-09-08T07:41:12.418206Z",
                                                "updated_at": "2026-09-08T07:41:12.418206Z",
                                                "title": "Asha Mwinyi"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown/hidden table uses the standard v3 envelope; unknown or deleted record uses the data error envelope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        },
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "not_found",
                                                "message": "No such record in this table.",
                                                "retryable": false,
                                                "field": "$id"
                                            },
                                            "message": "No such record in this table.",
                                            "code": "not_found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordsUpdate",
                "x-permission": "data.records.edit",
                "x-permission-scope": "controller",
                "summary": "Update a record",
                "description": "Changes only the keys you send; everything else keeps its value. A key set to `null` is cleared \u2014 unless the column is required, which answers 422. Values go through the same validation and coercion as a create. `source` is fixed at create and does not change here.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    },
                    {
                        "$ref": "#/components/parameters/DataRecordId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "data"
                                ],
                                "properties": {
                                    "data": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Only the keys to change. `null` clears a key."
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "data": {
                                            "region": "arusha",
                                            "balance": 12500
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Updated. The whole record as it now stands.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "record"
                                    ],
                                    "properties": {
                                        "record": {
                                            "$ref": "#/components/schemas/DataRecord",
                                            "description": "The record."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "record": {
                                                "id": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                                "data": {
                                                    "name": "Asha Mwinyi",
                                                    "phone": "+255712345678",
                                                    "region": "arusha",
                                                    "opt_in": true,
                                                    "balance": 12500
                                                },
                                                "source": "api",
                                                "created_at": "2026-09-08T07:41:12.418206Z",
                                                "updated_at": "2026-09-08T09:12:40.006511Z",
                                                "title": "Asha Mwinyi"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key issuer or table grant forbids the write, or a state transition requires a permission the caller lacks.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        },
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        }
                                    ]
                                },
                                "example": {
                                    "status": "error",
                                    "message": "You do not have permission to perform this action."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown/hidden table uses the standard v3 envelope; unknown or deleted record uses the data error envelope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        },
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "not_found",
                                                "message": "No such record in this table.",
                                                "retryable": false,
                                                "field": "$id"
                                            },
                                            "message": "No such record in this table.",
                                            "code": "not_found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Malformed query or invalid record value. Missing request data may use the standard v3 envelope; expected data refusals use DataError.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        },
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "validation_error",
                                                "message": "The supplied data or query is invalid.",
                                                "retryable": false
                                            },
                                            "message": "The supplied data or query is invalid.",
                                            "code": "validation_error"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "402": {
                        "description": "Table/account quota prevents storage; error.details names the quota and allowance.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "quota_exceeded",
                                                "message": "The table has reached its record allowance.",
                                                "retryable": false,
                                                "details": {
                                                    "quota": "quota_records",
                                                    "limit": 500000,
                                                    "used": 500000
                                                }
                                            },
                                            "message": "The table has reached its record allowance.",
                                            "code": "quota_exceeded"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "A unique-value or status-transition conflict prevented the write.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "conflict",
                                                "message": "The record was refused. A unique value or state transition conflicts with current data.",
                                                "retryable": false
                                            },
                                            "message": "The record was refused. A unique value or state transition conflicts with current data.",
                                            "code": "conflict"
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            },
            "delete": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordsDelete",
                "x-permission": "data.records.edit",
                "x-permission-scope": "controller",
                "summary": "Delete a record",
                "description": "Soft-deletes one record: it leaves every list and read from now on and stops counting against the records quota. Deleting it twice is a 404.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    },
                    {
                        "$ref": "#/components/parameters/DataRecordId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "deleted"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "enum": [
                                                true
                                            ],
                                            "description": "Always true on success."
                                        },
                                        "deleted": {
                                            "type": "integer",
                                            "enum": [
                                                1
                                            ],
                                            "description": "How many records were deleted \u2014 always 1 here."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "ok": true,
                                            "deleted": 1
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.records.edit, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.records.edit\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Unknown/hidden table uses the standard v3 envelope; unknown or deleted record uses the data error envelope.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        },
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "not_found",
                                                "message": "No such record in this table.",
                                                "retryable": false,
                                                "field": "$id"
                                            },
                                            "message": "No such record in this table.",
                                            "code": "not_found"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/tables/{table}/records/{record}/history": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataRecordHistory",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "Read a record's history",
                "description": "Every change made to one record, newest first: what was created, updated or deleted, which fields moved and from what to what, who did it and through which surface (the web app, an API key, an MCP connection, a message flow, an IVR call or a schedule), and the reason when one was given. Pages 50 at a time; pass the timestamp returned as next_before back as the before query parameter to read the page after it. A record nobody has changed answers with an empty list, not a 404.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    },
                    {
                        "$ref": "#/components/parameters/DataRecordId"
                    },
                    {
                        "name": "before",
                        "in": "query",
                        "required": false,
                        "description": "Read the page older than this timestamp \u2014 the next_before value from the previous page.",
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "example": "2026-09-08 14:31:07.812345+03:00"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The record's history.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "history",
                                        "has_more"
                                    ],
                                    "properties": {
                                        "history": {
                                            "type": "array",
                                            "description": "The changes, newest first.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "description": "The history entry's id."
                                                    },
                                                    "action": {
                                                        "type": "string",
                                                        "enum": [
                                                            "create",
                                                            "update",
                                                            "delete",
                                                            "restore",
                                                            "bulk_delete"
                                                        ],
                                                        "description": "What happened to the record."
                                                    },
                                                    "changes": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "Per field, the value before and after. A create lists every field from null; a delete lists every field to null."
                                                    },
                                                    "actor": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "Who made the change: kind (user, api, mcp, flow, ivr, schedule, system), id and a label."
                                                    },
                                                    "source": {
                                                        "type": "string",
                                                        "description": "The surface the write came through."
                                                    },
                                                    "reason": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "Why, when the caller gave a reason."
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "description": "When the change was made."
                                                    },
                                                    "record_id": {
                                                        "type": "string",
                                                        "description": "Record UUID described by this audit entry.",
                                                        "format": "uuid"
                                                    },
                                                    "changed": {
                                                        "type": "array",
                                                        "description": "Keys changed in this entry.",
                                                        "items": {
                                                            "type": "string"
                                                        }
                                                    }
                                                }
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether an older page exists."
                                        },
                                        "next_before": {
                                            "type": "string",
                                            "format": "date-time",
                                            "nullable": true,
                                            "description": "Pass back as before to read the next page."
                                        },
                                        "columns": {
                                            "type": "object",
                                            "additionalProperties": true,
                                            "description": "Field key to its label, so a change can be shown with the field's name."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "history": [
                                                {
                                                    "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
                                                    "action": "update",
                                                    "changes": {
                                                        "status": {
                                                            "from": "pending",
                                                            "to": "paid"
                                                        }
                                                    },
                                                    "actor": {
                                                        "kind": "mcp",
                                                        "id": 41,
                                                        "label": "Claude"
                                                    },
                                                    "source": "mcp",
                                                    "reason": null,
                                                    "created_at": "2026-09-08T14:31:07.812345+03:00"
                                                }
                                            ],
                                            "has_more": false,
                                            "next_before": null,
                                            "columns": {
                                                "status": "Status"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Invalid UUID or unknown/hidden table. A valid record UUID with no history returns an empty history list, including after deletion.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/groups": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataGroupsList",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "List table groups",
                "description": "Every group this tenant has defined, in display order. A group is a named folder of related tables (customers, orders, payments) with a report layer across them; a table belongs to at most one group.",
                "responses": {
                    "200": {
                        "description": "The groups.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "groups"
                                    ],
                                    "properties": {
                                        "groups": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DataTableGroup"
                                            },
                                            "description": "The groups, in display order (position, then name)."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "groups": [
                                                {
                                                    "id": "7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                                                    "name": "Mauzo",
                                                    "slug": "mauzo",
                                                    "description": "Wateja na oda zao.",
                                                    "icon": "\ud83d\uded2",
                                                    "color": "amber",
                                                    "position": 0,
                                                    "tables_count": 2,
                                                    "records_count": 61234,
                                                    "created_at": "2026-09-08T09:00:00+00:00",
                                                    "updated_at": "2026-09-08T09:00:00+00:00"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/groups/{group}": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataGroupGet",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "Read a group",
                "description": "The group, its member tables (each with its columns, headline total and records created in the last 30 days) and its saved cross-table reports.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataGroupId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The group.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "group",
                                        "tables",
                                        "reports"
                                    ],
                                    "properties": {
                                        "group": {
                                            "$ref": "#/components/schemas/DataTableGroup",
                                            "description": "The group."
                                        },
                                        "tables": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DataGroupTableCard"
                                            },
                                            "description": "Member tables in the group's order, each with its columns and its last-30-days card."
                                        },
                                        "reports": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/DataGroupReport"
                                            },
                                            "description": "Saved cross-table reports, pinned first."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "group": {
                                                "id": "7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                                                "name": "Mauzo",
                                                "slug": "mauzo",
                                                "description": "Wateja na oda zao.",
                                                "icon": "\ud83d\uded2",
                                                "color": "amber",
                                                "position": 0,
                                                "tables_count": 2,
                                                "records_count": 61234,
                                                "created_at": "2026-09-08T09:00:00+00:00",
                                                "updated_at": "2026-09-08T09:00:00+00:00"
                                            },
                                            "tables": [
                                                {
                                                    "id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                    "name": "Oda",
                                                    "slug": "orders",
                                                    "icon": "\ud83e\uddfe",
                                                    "records_count": 52014,
                                                    "columns_count": 4,
                                                    "headline": {
                                                        "label": "Total Kiasi (TZS)",
                                                        "fn": "sum",
                                                        "column": "amount",
                                                        "value": 5466022000,
                                                        "unit": "TZS"
                                                    },
                                                    "created_last_range": 812,
                                                    "drill": {
                                                        "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                        "filter": {
                                                            "all": [
                                                                {
                                                                    "column": "$created_at",
                                                                    "op": "between",
                                                                    "value": [
                                                                        "2026-08-10T00:00:00Z",
                                                                        "2026-09-09T00:00:00Z"
                                                                    ]
                                                                }
                                                            ]
                                                        },
                                                        "range": {
                                                            "from": "2026-08-10T00:00:00Z",
                                                            "to": "2026-09-09T00:00:00Z"
                                                        }
                                                    },
                                                    "columns": []
                                                }
                                            ],
                                            "reports": [
                                                {
                                                    "id": "b2c3d4e5-f6a7-4b8c-9d0e-1f2a3b4c5d6e",
                                                    "group_id": "7c1e2d3f-4a5b-4c6d-8e7f-9a0b1c2d3e4f",
                                                    "name": "Mauzo kwa wiki",
                                                    "description": null,
                                                    "definition": {
                                                        "series": [
                                                            {
                                                                "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                                "metric": {
                                                                    "fn": "sum",
                                                                    "column": "amount"
                                                                },
                                                                "filters": null,
                                                                "label": "Oda"
                                                            },
                                                            {
                                                                "table_id": "4e8d9c0b-1a2f-4b3c-8d4e-5f6a7b8c9d0e",
                                                                "metric": {
                                                                    "fn": "count"
                                                                },
                                                                "filters": null,
                                                                "label": "Wateja"
                                                            }
                                                        ],
                                                        "dimension": {
                                                            "column": "$created_at",
                                                            "bucket": "week"
                                                        },
                                                        "date_range": {
                                                            "relative": "last_90_days"
                                                        },
                                                        "chart": "line"
                                                    },
                                                    "is_pinned": true,
                                                    "is_default": false,
                                                    "created_at": "2026-09-08T09:00:00+00:00",
                                                    "updated_at": "2026-09-08T09:00:00+00:00"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No group with that id for this tenant (or the id is not a UUID).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/groups/{group}/overview": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataGroupOverview",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "summary": "Read a group's overview",
                "description": "Totals, one card per member table, records over time stacked by table, every amount-like column totalled, and the relations between member tables \u2014 for a range. Every card carries a `drill` you can pass to the records endpoint as `filter`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataGroupId"
                    },
                    {
                        "name": "range",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "default": "last_30_days"
                        },
                        "description": "A relative preset (today, yesterday, last_7_days, last_30_days, last_90_days, this_month, last_month) or a JSON period `{\"from\":\"YYYY-MM-DD\",\"to\":\"YYYY-MM-DD\"}`. `from`/`to` query parameters are accepted too.",
                        "example": "last_30_days"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The overview.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataGroupOverview"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "totals": {
                                                "tables": 2,
                                                "records": 61234,
                                                "storage_bytes": 12345678
                                            },
                                            "tables": [
                                                {
                                                    "id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                    "name": "Oda",
                                                    "slug": "orders",
                                                    "icon": "\ud83e\uddfe",
                                                    "records_count": 52014,
                                                    "columns_count": 4,
                                                    "headline": {
                                                        "label": "Total Kiasi (TZS)",
                                                        "fn": "sum",
                                                        "column": "amount",
                                                        "value": 5466022000,
                                                        "unit": "TZS"
                                                    },
                                                    "created_last_range": 812,
                                                    "drill": {
                                                        "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                        "filter": {
                                                            "all": [
                                                                {
                                                                    "column": "$created_at",
                                                                    "op": "between",
                                                                    "value": [
                                                                        "2026-08-10T00:00:00Z",
                                                                        "2026-09-09T00:00:00Z"
                                                                    ]
                                                                }
                                                            ]
                                                        },
                                                        "range": {
                                                            "from": "2026-08-10T00:00:00Z",
                                                            "to": "2026-09-09T00:00:00Z"
                                                        }
                                                    }
                                                }
                                            ],
                                            "over_time": {
                                                "bucket": "day",
                                                "rows": [
                                                    {
                                                        "bucket": "2026-09-01",
                                                        "total": 42,
                                                        "by_table": {
                                                            "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b": 30,
                                                            "4e8d9c0b-1a2f-4b3c-8d4e-5f6a7b8c9d0e": 12
                                                        },
                                                        "drill": {
                                                            "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b": {
                                                                "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                                "filter": {
                                                                    "all": [
                                                                        {
                                                                            "column": "$created_at",
                                                                            "op": "between",
                                                                            "value": [
                                                                                "2026-09-01T00:00:00Z",
                                                                                "2026-09-02T00:00:00Z"
                                                                            ]
                                                                        }
                                                                    ]
                                                                },
                                                                "range": {
                                                                    "from": "2026-09-01T00:00:00Z",
                                                                    "to": "2026-09-02T00:00:00Z"
                                                                }
                                                            }
                                                        }
                                                    }
                                                ]
                                            },
                                            "headlines": [
                                                {
                                                    "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                    "table": "Oda",
                                                    "label": "Total Kiasi (TZS)",
                                                    "fn": "sum",
                                                    "column": "amount",
                                                    "value": 5466022000,
                                                    "unit": "TZS",
                                                    "chart": "number",
                                                    "drill": {
                                                        "table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                        "filter": {
                                                            "all": [
                                                                {
                                                                    "column": "$created_at",
                                                                    "op": "between",
                                                                    "value": [
                                                                        "2026-08-10T00:00:00Z",
                                                                        "2026-09-09T00:00:00Z"
                                                                    ]
                                                                }
                                                            ]
                                                        },
                                                        "range": {
                                                            "from": "2026-08-10T00:00:00Z",
                                                            "to": "2026-09-09T00:00:00Z"
                                                        }
                                                    }
                                                }
                                            ],
                                            "relations": [
                                                {
                                                    "from_table_id": "9d2f4c1e-7b8a-4e0f-9a3b-5c6d7e8f9a0b",
                                                    "from_column": "customer",
                                                    "to_table_id": "4e8d9c0b-1a2f-4b3c-8d4e-5f6a7b8c9d0e"
                                                }
                                            ],
                                            "range": {
                                                "from": "2026-08-10T00:00:00Z",
                                                "to": "2026-09-09T00:00:00Z",
                                                "relative": "last_30_days"
                                            },
                                            "computed_at": "2026-09-08T10:11:12Z"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold data.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"data.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No group with that id for this tenant (or the id is not a UUID).",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Malformed query or invalid record value. Missing request data may use the standard v3 envelope; expected data refusals use DataError.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/DataError"
                                        },
                                        {
                                            "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                        }
                                    ]
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "error": {
                                                "code": "validation_error",
                                                "message": "The supplied data or query is invalid.",
                                                "retryable": false
                                            },
                                            "message": "The supplied data or query is invalid.",
                                            "code": "validation_error"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/payments": {
            "get": {
                "tags": [
                    "Payments"
                ],
                "operationId": "v3PaymentsIndex",
                "x-permission": "payments.view",
                "x-permission-scope": "controller",
                "summary": "List payments",
                "description": "Read tenant payment intents newest first. Requires payments.view on the key issuer. The native response is {data:[...],meta:{current_page,per_page,total,last_page}}; pagination defaults to 25 and caps at 100. state=open selects draft, pending and authorised; unknown state input currently leaves results unfiltered. amount_minor and refunded_minor are integers on a fixed 100-minor-units-per-major-unit scale, including TZS. Use formatted amount for display. paid, partly_refunded and refunded mean funds settled at some point; inspect refunded_minor to determine what has been returned. This REST surface provides reads only.",
                "parameters": [
                    {
                        "name": "state",
                        "in": "query",
                        "required": false,
                        "description": "Filter by state. open means draft, pending or authorised; omitted/all means no filter. Unknown input also currently leaves the list unfiltered.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "all",
                                "open",
                                "draft",
                                "pending",
                                "authorised",
                                "paid",
                                "failed",
                                "expired",
                                "cancelled",
                                "refunded",
                                "partly_refunded"
                            ],
                            "example": "open"
                        }
                    },
                    {
                        "name": "subject_id",
                        "in": "query",
                        "required": false,
                        "description": "Only payments raised for this record \u2014 an order id, a Daftari record id, an invoice number.",
                        "schema": {
                            "type": "string",
                            "example": "1214"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/PerPage",
                        "description": "Page size, default 25 and maximum 100. limit is also accepted and takes precedence over per_page."
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The page of payments.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data",
                                        "meta"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "description": "The payments on this page, newest first.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "description": "The payment's id. Time-ordered, so sorting by it sorts by when it was raised."
                                                    },
                                                    "reference": {
                                                        "type": "string",
                                                        "description": "The human reference, unique in this workspace: PAY-YYYYMMDD-NNNN. This is what a person quotes down a phone line."
                                                    },
                                                    "state": {
                                                        "type": "string",
                                                        "enum": [
                                                            "draft",
                                                            "pending",
                                                            "authorised",
                                                            "paid",
                                                            "failed",
                                                            "expired",
                                                            "cancelled",
                                                            "refunded",
                                                            "partly_refunded"
                                                        ],
                                                        "description": "Where the ask got to. Only paid, partly_refunded and refunded mean money actually arrived."
                                                    },
                                                    "state_label": {
                                                        "type": "string",
                                                        "description": "The state written for a person to read."
                                                    },
                                                    "is_open": {
                                                        "type": "boolean",
                                                        "description": "Whether the payment is still waiting on the customer."
                                                    },
                                                    "is_settled": {
                                                        "type": "boolean",
                                                        "description": "Whether money arrived, whatever has since been given back."
                                                    },
                                                    "amount_minor": {
                                                        "type": "integer",
                                                        "description": "Integer minor units at a fixed scale of 100 per major unit, including TZS: 40000 represents TZS 400. Use amount for formatted display."
                                                    },
                                                    "amount": {
                                                        "type": "string",
                                                        "description": "The same amount formatted with its currency code, for showing to a person."
                                                    },
                                                    "currency": {
                                                        "type": "string",
                                                        "description": "ISO 4217 code."
                                                    },
                                                    "refunded_minor": {
                                                        "type": "integer",
                                                        "description": "How much of the amount has already been given back, in minor units."
                                                    },
                                                    "refunded": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The refunded total formatted, or null when nothing has been refunded."
                                                    },
                                                    "refundable_minor": {
                                                        "type": "integer",
                                                        "description": "How much could still be refunded, in minor units."
                                                    },
                                                    "payer": {
                                                        "type": "object",
                                                        "nullable": true,
                                                        "additionalProperties": true,
                                                        "description": "Who is paying: name, phone and email, only as far as they were given."
                                                    },
                                                    "method": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "How the customer was asked: ussd_push, link or lipa."
                                                    },
                                                    "provider": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The gateway the request went to."
                                                    },
                                                    "subject_type": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "What is being paid for \u2014 an order, a data table, an invoice."
                                                    },
                                                    "subject_id": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The id of the thing being paid for."
                                                    },
                                                    "is_refund": {
                                                        "type": "boolean",
                                                        "description": "Whether this payment is itself a refund of another one."
                                                    },
                                                    "refund_of": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "nullable": true,
                                                        "description": "The payment this one gives money back for."
                                                    },
                                                    "refund_reason": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "Why the refund was raised."
                                                    },
                                                    "attempts": {
                                                        "type": "integer",
                                                        "description": "How many times the provider has been asked."
                                                    },
                                                    "last_error": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "What went wrong last time, in plain words. Never carries a credential."
                                                    },
                                                    "expires_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When the ask stops being answerable."
                                                    },
                                                    "settled_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When the money arrived."
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "description": "When the payment was raised."
                                                    },
                                                    "next_states": {
                                                        "type": "array",
                                                        "items": {
                                                            "type": "string"
                                                        },
                                                        "description": "The states this payment may legally move to next."
                                                    },
                                                    "checkout_url": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The page to send the customer to, when the method produced one."
                                                    },
                                                    "payment_token": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The short lipa number the customer pays from any wallet app."
                                                    },
                                                    "token_expires_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When that lipa number stops working."
                                                    }
                                                }
                                            }
                                        },
                                        "meta": {
                                            "type": "object",
                                            "description": "Where this page sits in the whole set.",
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer",
                                                    "description": "The page returned."
                                                },
                                                "per_page": {
                                                    "type": "integer",
                                                    "description": "How many rows a page holds."
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "description": "How many payments match in total."
                                                },
                                                "last_page": {
                                                    "type": "integer",
                                                    "description": "The highest page number available."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": [
                                                {
                                                    "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
                                                    "reference": "PAY-20260908-0042",
                                                    "state": "paid",
                                                    "state_label": "Paid",
                                                    "is_open": false,
                                                    "is_settled": true,
                                                    "amount_minor": 4000000,
                                                    "amount": "TZS 40,000",
                                                    "currency": "TZS",
                                                    "refunded_minor": 0,
                                                    "refunded": null,
                                                    "refundable_minor": 4000000,
                                                    "payer": {
                                                        "name": "Asha Mushi",
                                                        "phone": "255712345678"
                                                    },
                                                    "method": "ussd_push",
                                                    "provider": "selcom",
                                                    "subject_type": "App\\Models\\WaOrder",
                                                    "subject_id": "1214",
                                                    "is_refund": false,
                                                    "refund_of": null,
                                                    "refund_reason": null,
                                                    "attempts": 1,
                                                    "last_error": null,
                                                    "expires_at": "2026-09-08T17:31:07+03:00",
                                                    "settled_at": "2026-09-08T14:34:52+03:00",
                                                    "created_at": "2026-09-08T14:31:07+03:00",
                                                    "next_states": [
                                                        "partly_refunded",
                                                        "refunded"
                                                    ],
                                                    "checkout_url": null,
                                                    "payment_token": null,
                                                    "token_expires_at": null
                                                }
                                            ],
                                            "meta": {
                                                "current_page": 1,
                                                "per_page": 25,
                                                "total": 1,
                                                "last_page": 1
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold payments.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"payments.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such workspace for this token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/payments/{payment}": {
            "get": {
                "tags": [
                    "Payments"
                ],
                "operationId": "v3PaymentShow",
                "x-permission": "payments.view",
                "x-permission-scope": "controller",
                "summary": "Read one payment",
                "description": "One payment in full: the amount, who was asked, where it got to, everything that has happened to it in order, what it wrote in the books, and any refunds raised against it. The timeline is the answer to \"the customer says they paid and the record says otherwise\", and it is append-only \u2014 nothing in it is ever edited. Accepts the payment id or its human reference.",
                "parameters": [
                    {
                        "name": "payment",
                        "in": "path",
                        "required": true,
                        "description": "The payment id, or its human reference (PAY-YYYYMMDD-NNNN). A payment belonging to another tenant answers 404.",
                        "schema": {
                            "type": "string",
                            "example": "PAY-20260908-0042"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The payment, its timeline, its ledger entries and its refunds.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "description": "The payment with its whole story.",
                                            "properties": {
                                                "id": {
                                                    "type": "string",
                                                    "format": "uuid",
                                                    "description": "The payment's id. Time-ordered, so sorting by it sorts by when it was raised."
                                                },
                                                "reference": {
                                                    "type": "string",
                                                    "description": "The human reference, unique in this workspace: PAY-YYYYMMDD-NNNN. This is what a person quotes down a phone line."
                                                },
                                                "state": {
                                                    "type": "string",
                                                    "enum": [
                                                        "draft",
                                                        "pending",
                                                        "authorised",
                                                        "paid",
                                                        "failed",
                                                        "expired",
                                                        "cancelled",
                                                        "refunded",
                                                        "partly_refunded"
                                                    ],
                                                    "description": "Where the ask got to. Only paid, partly_refunded and refunded mean money actually arrived."
                                                },
                                                "state_label": {
                                                    "type": "string",
                                                    "description": "The state written for a person to read."
                                                },
                                                "is_open": {
                                                    "type": "boolean",
                                                    "description": "Whether the payment is still waiting on the customer."
                                                },
                                                "is_settled": {
                                                    "type": "boolean",
                                                    "description": "Whether money arrived, whatever has since been given back."
                                                },
                                                "amount_minor": {
                                                    "type": "integer",
                                                    "description": "Integer minor units at a fixed scale of 100 per major unit, including TZS: 40000 represents TZS 400. Use amount for formatted display."
                                                },
                                                "amount": {
                                                    "type": "string",
                                                    "description": "The same amount formatted with its currency code, for showing to a person."
                                                },
                                                "currency": {
                                                    "type": "string",
                                                    "description": "ISO 4217 code."
                                                },
                                                "refunded_minor": {
                                                    "type": "integer",
                                                    "description": "How much of the amount has already been given back, in minor units."
                                                },
                                                "refunded": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The refunded total formatted, or null when nothing has been refunded."
                                                },
                                                "refundable_minor": {
                                                    "type": "integer",
                                                    "description": "How much could still be refunded, in minor units."
                                                },
                                                "payer": {
                                                    "type": "object",
                                                    "nullable": true,
                                                    "additionalProperties": true,
                                                    "description": "Who is paying: name, phone and email, only as far as they were given."
                                                },
                                                "method": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "How the customer was asked: ussd_push, link or lipa."
                                                },
                                                "provider": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The gateway the request went to."
                                                },
                                                "subject_type": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "What is being paid for \u2014 an order, a data table, an invoice."
                                                },
                                                "subject_id": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The id of the thing being paid for."
                                                },
                                                "is_refund": {
                                                    "type": "boolean",
                                                    "description": "Whether this payment is itself a refund of another one."
                                                },
                                                "refund_of": {
                                                    "type": "string",
                                                    "format": "uuid",
                                                    "nullable": true,
                                                    "description": "The payment this one gives money back for."
                                                },
                                                "refund_reason": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "Why the refund was raised."
                                                },
                                                "attempts": {
                                                    "type": "integer",
                                                    "description": "How many times the provider has been asked."
                                                },
                                                "last_error": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "What went wrong last time, in plain words. Never carries a credential."
                                                },
                                                "expires_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "nullable": true,
                                                    "description": "When the ask stops being answerable."
                                                },
                                                "settled_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "nullable": true,
                                                    "description": "When the money arrived."
                                                },
                                                "created_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "description": "When the payment was raised."
                                                },
                                                "next_states": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "The states this payment may legally move to next."
                                                },
                                                "checkout_url": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The page to send the customer to, when the method produced one."
                                                },
                                                "payment_token": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The short lipa number the customer pays from any wallet app."
                                                },
                                                "token_expires_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "nullable": true,
                                                    "description": "When that lipa number stops working."
                                                },
                                                "created_by": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "The person who raised the payment, when a person did."
                                                },
                                                "timeline": {
                                                    "type": "array",
                                                    "description": "Everything that has happened to this payment, oldest first. Append-only: nothing here is ever edited.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "id": {
                                                                "type": "string",
                                                                "format": "uuid",
                                                                "description": "The event's id."
                                                            },
                                                            "type": {
                                                                "type": "string",
                                                                "description": "created, collect_requested, state_changed, refund_requested, reconciled or drift."
                                                            },
                                                            "from_state": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The state before this event."
                                                            },
                                                            "to_state": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "The state after it."
                                                            },
                                                            "source": {
                                                                "type": "string",
                                                                "description": "Which door caused it: api, webhook, reconciler, flow, mcp, client or system."
                                                            },
                                                            "message": {
                                                                "type": "string",
                                                                "nullable": true,
                                                                "description": "What happened, in plain words."
                                                            },
                                                            "occurred_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "description": "When."
                                                            }
                                                        }
                                                    }
                                                },
                                                "ledger": {
                                                    "type": "array",
                                                    "description": "What this payment wrote in the books. Append-only and always balanced: every posting moves the same amount out of one account as into another.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "entry_no": {
                                                                "type": "integer",
                                                                "description": "The ledger's own sequence number."
                                                            },
                                                            "kind": {
                                                                "type": "string",
                                                                "description": "payment, refund, payout, fee, adjustment, charge, hold or release."
                                                            },
                                                            "direction": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "debit",
                                                                    "credit"
                                                                ],
                                                                "description": "Which way the money went. The amount is always positive; this carries the sign."
                                                            },
                                                            "account": {
                                                                "type": "string",
                                                                "enum": [
                                                                    "customer",
                                                                    "business",
                                                                    "platform",
                                                                    "provider"
                                                                ],
                                                                "description": "Whose position moved."
                                                            },
                                                            "amount_minor": {
                                                                "type": "integer",
                                                                "description": "Integer amount on the payment layer fixed scale of 100 minor units per major currency unit."
                                                            },
                                                            "amount": {
                                                                "type": "string",
                                                                "description": "The same amount formatted."
                                                            },
                                                            "occurred_at": {
                                                                "type": "string",
                                                                "format": "date-time",
                                                                "description": "When the money moved."
                                                            }
                                                        }
                                                    }
                                                },
                                                "refunds": {
                                                    "type": "array",
                                                    "description": "Refunds raised against this payment. Each is a payment in its own right, linked back by refund_of.",
                                                    "items": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "A refund, in the same shape as any other payment."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e6f",
                                                "reference": "PAY-20260908-0042",
                                                "state": "paid",
                                                "state_label": "Paid",
                                                "is_open": false,
                                                "is_settled": true,
                                                "amount_minor": 4000000,
                                                "amount": "TZS 40,000",
                                                "currency": "TZS",
                                                "refunded_minor": 0,
                                                "refunded": null,
                                                "refundable_minor": 4000000,
                                                "payer": {
                                                    "name": "Asha Mushi",
                                                    "phone": "255712345678"
                                                },
                                                "method": "ussd_push",
                                                "provider": "selcom",
                                                "subject_type": "App\\Models\\WaOrder",
                                                "subject_id": "1214",
                                                "is_refund": false,
                                                "refund_of": null,
                                                "refund_reason": null,
                                                "attempts": 1,
                                                "last_error": null,
                                                "expires_at": "2026-09-08T17:31:07+03:00",
                                                "settled_at": "2026-09-08T14:34:52+03:00",
                                                "created_at": "2026-09-08T14:31:07+03:00",
                                                "next_states": [
                                                    "partly_refunded",
                                                    "refunded"
                                                ],
                                                "checkout_url": null,
                                                "payment_token": null,
                                                "token_expires_at": null,
                                                "created_by": "Neema Kimaro",
                                                "timeline": [
                                                    {
                                                        "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e70",
                                                        "type": "created",
                                                        "from_state": null,
                                                        "to_state": "draft",
                                                        "source": "api",
                                                        "message": "TZS 40,000 asked for, for App\\Models\\WaOrder 1214.",
                                                        "occurred_at": "2026-09-08T14:31:07+03:00"
                                                    },
                                                    {
                                                        "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e71",
                                                        "type": "collect_requested",
                                                        "from_state": "draft",
                                                        "to_state": "pending",
                                                        "source": "api",
                                                        "message": "Asked the provider for the money.",
                                                        "occurred_at": "2026-09-08T14:31:08+03:00"
                                                    },
                                                    {
                                                        "id": "0192f3c4-5a6b-7c8d-9e0f-1a2b3c4d5e72",
                                                        "type": "state_changed",
                                                        "from_state": "pending",
                                                        "to_state": "paid",
                                                        "source": "webhook",
                                                        "message": "",
                                                        "occurred_at": "2026-09-08T14:34:52+03:00"
                                                    }
                                                ],
                                                "ledger": [
                                                    {
                                                        "entry_no": 8121,
                                                        "kind": "payment",
                                                        "direction": "debit",
                                                        "account": "customer",
                                                        "amount_minor": 4000000,
                                                        "amount": "TZS 40,000",
                                                        "occurred_at": "2026-09-08T14:34:52+03:00"
                                                    },
                                                    {
                                                        "entry_no": 8122,
                                                        "kind": "payment",
                                                        "direction": "credit",
                                                        "account": "business",
                                                        "amount_minor": 4000000,
                                                        "amount": "TZS 40,000",
                                                        "occurred_at": "2026-09-08T14:34:52+03:00"
                                                    }
                                                ],
                                                "refunds": []
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold payments.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"payments.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No payment with that id or reference in this workspace.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/data/tables/{table}/states": {
            "get": {
                "tags": [
                    "Data tables"
                ],
                "operationId": "v3DataTableStates",
                "summary": "Read a table\u2019s status fields and legal transitions",
                "description": "Read state keys and allowed transitions before creating or changing a status value. Every status field includes its initial states and next moves with permission-aware allowed flags. Use ordinary record PATCH to apply a state value; this read does not reserve a transition.",
                "x-permission": "data.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/DataTableId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Status state machines visible to this caller.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/DataTableStates"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "table": {
                                                "id": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                                "name": "Orders",
                                                "slug": "orders"
                                            },
                                            "fields": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "Key issuer lacks data.view.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "You do not have permission to perform this action."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Invalid UUID, unknown table or table hidden from this caller.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Resource not found."
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/automations/events": {
            "get": {
                "tags": [
                    "Automations"
                ],
                "operationId": "v3AutomationEvents",
                "x-permission": "automations.view",
                "x-permission-scope": "controller",
                "summary": "Read the business event log",
                "description": "Read business events newest first in the native {events,has_more,next_before,event_keys} envelope. Requires automations.view. The event_keys catalog declares publisher availability with live; keys marked false do not currently publish. delivered_at records fan-out processing, and delivered_count counts successful dispatch outcomes, including queued webhook/agent jobs whose external work may still be pending. limit defaults to 50 and clamps to 1\u201350. Pass next_before as before for a strict older-than timestamp filter. A full page sets has_more=true without proving another row exists. Invalid before values restart at the newest page. The timestamp cursor has no ID tie-breaker and is not a lossless high-volume export cursor.",
                "parameters": [
                    {
                        "name": "key",
                        "in": "query",
                        "required": false,
                        "description": "Only this event. One of the platform's closed list; anything else is refused with a 422 naming the ones that exist.",
                        "schema": {
                            "type": "string",
                            "example": "record.transitioned"
                        }
                    },
                    {
                        "name": "subject_id",
                        "in": "query",
                        "required": false,
                        "description": "Everything that ever happened to one thing \u2014 a record id, an approval id.",
                        "schema": {
                            "type": "string",
                            "example": "9f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f"
                        }
                    },
                    {
                        "name": "before",
                        "in": "query",
                        "required": false,
                        "description": "Read the page older than this timestamp \u2014 the next_before value from the previous page.",
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "example": "2026-09-08T09:14:22+03:00"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "How many events to return, 1 to 50.",
                        "schema": {
                            "type": "integer",
                            "minimum": 1,
                            "maximum": 50,
                            "default": 50
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The event log, newest first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "events",
                                        "has_more"
                                    ],
                                    "properties": {
                                        "events": {
                                            "type": "array",
                                            "description": "The events, newest first.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "description": "The event's id \u2014 a uuid v7, so sorting by it is sorting by time."
                                                    },
                                                    "key": {
                                                        "type": "string",
                                                        "description": "What happened, from the platform's closed list, e.g. record.transitioned.",
                                                        "enum": [
                                                            "record.created",
                                                            "record.updated",
                                                            "record.deleted",
                                                            "record.transitioned",
                                                            "payment.paid",
                                                            "payment.failed",
                                                            "payment.refunded",
                                                            "order.completed",
                                                            "approval.requested",
                                                            "approval.settled",
                                                            "booking.confirmed",
                                                            "ticket.opened",
                                                            "ticket.closed",
                                                            "call.completed",
                                                            "message.received"
                                                        ]
                                                    },
                                                    "label": {
                                                        "type": "string",
                                                        "description": "The same thing in a sentence, e.g. \"A record moved to a new state\"."
                                                    },
                                                    "subject_type": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "What the event is about, e.g. data_record or approval."
                                                    },
                                                    "subject_id": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "The id of that thing, so every event about one record can be read together."
                                                    },
                                                    "payload": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "What happened, in full. For a record event: the table, the record id, the record itself, and the fields that moved."
                                                    },
                                                    "actor": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "Who did it: kind (user, api, mcp, flow, ivr, schedule, system), id and a label."
                                                    },
                                                    "occurred_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "description": "When it happened, not when it was written."
                                                    },
                                                    "delivered_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When the fan-out finished with it. Null means it has not been processed yet."
                                                    },
                                                    "delivered_count": {
                                                        "type": "integer",
                                                        "description": "How many subscriptions acted on it. Zero with a delivered_at means nothing was listening \u2014 the usual reason an automation \"did not run\"."
                                                    }
                                                }
                                            }
                                        },
                                        "has_more": {
                                            "type": "boolean",
                                            "description": "Whether there is an older page."
                                        },
                                        "next_before": {
                                            "type": "string",
                                            "format": "date-time",
                                            "nullable": true,
                                            "description": "Pass this back as before to read the next page."
                                        },
                                        "event_keys": {
                                            "type": "array",
                                            "description": "The closed list of events this platform publishes, so a caller never has to guess one.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "key": {
                                                        "type": "string",
                                                        "description": "The event key."
                                                    },
                                                    "label": {
                                                        "type": "string",
                                                        "description": "What it means, in a sentence."
                                                    },
                                                    "group": {
                                                        "type": "string",
                                                        "description": "Which part of the business it belongs to."
                                                    },
                                                    "subject": {
                                                        "type": "string",
                                                        "description": "What kind of thing the event is about."
                                                    },
                                                    "publisher": {
                                                        "type": "string",
                                                        "description": "Which part of the platform publishes it."
                                                    },
                                                    "live": {
                                                        "type": "boolean",
                                                        "description": "Whether that publisher has shipped yet. A key that is not live is part of the contract but never fires."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "events": [
                                                {
                                                    "id": "01a08270-0000-7000-8000-2a3b4c5d6e7f",
                                                    "key": "record.transitioned",
                                                    "label": "A record moved to a new state",
                                                    "subject_type": "data_record",
                                                    "subject_id": "9f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                                                    "payload": {
                                                        "table": {
                                                            "id": "1b2c3d4e-5f60-4718-9a2b-3c4d5e6f7a8b",
                                                            "name": "Orders",
                                                            "slug": "orders"
                                                        },
                                                        "record_id": "9f1c2d3e-4a5b-4c6d-8e9f-0a1b2c3d4e5f",
                                                        "record": {
                                                            "customer": "Asha Mwinyi",
                                                            "status": "paid",
                                                            "total": 45000
                                                        },
                                                        "changes": {
                                                            "status": {
                                                                "from": "confirmed",
                                                                "to": "paid"
                                                            }
                                                        },
                                                        "moved": [
                                                            "status"
                                                        ],
                                                        "source": "ui"
                                                    },
                                                    "actor": {
                                                        "kind": "user",
                                                        "id": 42,
                                                        "label": "Asha Mwinyi"
                                                    },
                                                    "occurred_at": "2026-09-08T09:14:22+03:00",
                                                    "delivered_at": "2026-09-08T09:14:23+03:00",
                                                    "delivered_count": 2
                                                }
                                            ],
                                            "has_more": false,
                                            "next_before": null,
                                            "event_keys": [
                                                {
                                                    "key": "record.transitioned",
                                                    "label": "A record moved to a new state",
                                                    "group": "Records",
                                                    "subject": "data_record",
                                                    "publisher": "Daftari",
                                                    "live": true
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold automations.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"automations.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The automations module is switched off for this workspace.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The key query parameter named an event this platform does not publish.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Unknown event key. The ones this platform publishes are: record.created, record.updated, record.deleted, record.transitioned, payment.paid, payment.failed, payment.refunded, order.completed, approval.requested, approval.settled, booking.confirmed, ticket.opened, ticket.closed, call.completed, message.received."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/automations/subscriptions": {
            "get": {
                "tags": [
                    "Automations"
                ],
                "operationId": "v3AutomationSubscriptions",
                "x-permission": "automations.view",
                "x-permission-scope": "controller",
                "summary": "List the event subscriptions",
                "description": "What this workspace has arranged to happen when something occurs: start a flow, tell a team, call a URL, or hand it to an assistant. Read this to find out whether an integration is already set up, and to see whether one has been failing \u2014 last_error carries the platform's own sentence, and a subscription that has failed ten times in a row switches itself off and says so. Signing secrets are never returned; signed only says whether a webhook's deliveries carry one. Returns at most 200 rows, ordered by key and label, without pagination. A key filter includes wildcard subscriptions. Intermediate webhook retries do not each increment the consecutive failure counter; the terminal failed delivery does.",
                "parameters": [
                    {
                        "name": "key",
                        "in": "query",
                        "required": false,
                        "description": "Only subscriptions listening for this event. Wildcard subscriptions are always included, because they do listen for it.",
                        "schema": {
                            "type": "string",
                            "example": "payment.paid"
                        }
                    },
                    {
                        "name": "enabled_only",
                        "in": "query",
                        "required": false,
                        "description": "Leave out the ones that are switched off.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The subscriptions on this account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "subscriptions"
                                    ],
                                    "properties": {
                                        "subscriptions": {
                                            "type": "array",
                                            "description": "The subscriptions, by event then name.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "integer",
                                                        "description": "The subscription's id."
                                                    },
                                                    "key": {
                                                        "type": "string",
                                                        "description": "The event it listens for, or * for every event."
                                                    },
                                                    "key_label": {
                                                        "type": "string",
                                                        "description": "That event in a sentence."
                                                    },
                                                    "kind": {
                                                        "type": "string",
                                                        "enum": [
                                                            "flow",
                                                            "notification",
                                                            "webhook",
                                                            "agent"
                                                        ],
                                                        "description": "What it does when the event happens."
                                                    },
                                                    "target": {
                                                        "type": "string",
                                                        "description": "What it does it to: a flow id, who to tell, a URL, or an assistant id."
                                                    },
                                                    "label": {
                                                        "type": "string",
                                                        "description": "What a person calls it."
                                                    },
                                                    "filter": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "nullable": true,
                                                        "description": "A condition over the event; null means it fires on every one."
                                                    },
                                                    "config": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "nullable": true,
                                                        "description": "Per-kind extras \u2014 a notification's title and body, an assistant's instruction, a flow's variables."
                                                    },
                                                    "signed": {
                                                        "type": "boolean",
                                                        "description": "Whether a webhook's deliveries carry a signature. The secret itself is never returned by this API."
                                                    },
                                                    "enabled": {
                                                        "type": "boolean",
                                                        "description": "Whether it is switched on. Ten failures in a row switch one off."
                                                    },
                                                    "last_fired_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When it last acted on an event."
                                                    },
                                                    "fire_count": {
                                                        "type": "integer",
                                                        "description": "How many times it has acted."
                                                    },
                                                    "last_error": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "Why the last attempt failed, in the platform's own words."
                                                    },
                                                    "last_failed_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When that failure was."
                                                    },
                                                    "failure_count": {
                                                        "type": "integer",
                                                        "description": "How many failures in a row. Any success resets it to zero."
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When it was set up."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "subscriptions": [
                                                {
                                                    "id": 7,
                                                    "key": "payment.paid",
                                                    "key_label": "A payment settled",
                                                    "kind": "webhook",
                                                    "target": "https://orders.example.co.tz/hooks/momo",
                                                    "label": "Paid orders to the warehouse",
                                                    "filter": {
                                                        "all": [
                                                            {
                                                                "column": "amount",
                                                                "op": "greater_than",
                                                                "value": 10000
                                                            }
                                                        ]
                                                    },
                                                    "config": null,
                                                    "signed": true,
                                                    "enabled": true,
                                                    "last_fired_at": "2026-09-08T09:14:23+03:00",
                                                    "fire_count": 412,
                                                    "last_error": null,
                                                    "last_failed_at": null,
                                                    "failure_count": 0,
                                                    "created_at": "2026-08-01T11:02:00+03:00"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold automations.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"automations.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The automations module is switched off for this workspace.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/automations/schedules": {
            "get": {
                "tags": [
                    "Automations"
                ],
                "operationId": "v3AutomationSchedules",
                "x-permission": "automations.view",
                "x-permission-scope": "controller",
                "summary": "List the schedules",
                "description": "Read recurring schedules in the native {schedules:[...]} envelope. Requires automations.view. At most 300 rows are returned, ordered by name, without pagination. kind and enabled_only narrow the list. describes is the readable rhythm; spec retains its timezone and recurrence rules. A null next_run_at can indicate a disabled, exhausted or invalid schedule. last_result describes execution, with optional misfire details; follow any resulting resource reference for final delivery. run_once runs one late occurrence, skip advances without firing missed occurrences, and run_all replays at most 12 missed slots per runner tick. Lateness of up to 90 seconds is within the grace period.",
                "parameters": [
                    {
                        "name": "kind",
                        "in": "query",
                        "required": false,
                        "description": "Only this kind of schedule.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "flow",
                                "report",
                                "record",
                                "call",
                                "message"
                            ],
                            "example": "report"
                        }
                    },
                    {
                        "name": "enabled_only",
                        "in": "query",
                        "required": false,
                        "description": "Leave out the ones that are switched off.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The schedules on this account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "schedules"
                                    ],
                                    "properties": {
                                        "schedules": {
                                            "type": "array",
                                            "description": "The schedules, by name.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "id": {
                                                        "type": "string",
                                                        "format": "uuid",
                                                        "description": "The schedule's id."
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "description": "What a person calls it."
                                                    },
                                                    "kind": {
                                                        "type": "string",
                                                        "enum": [
                                                            "flow",
                                                            "report",
                                                            "record",
                                                            "call",
                                                            "message"
                                                        ],
                                                        "description": "What it does each time it runs."
                                                    },
                                                    "spec": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "The rhythm: every, unit, at, weekdays, day_of_month, timezone, until, count."
                                                    },
                                                    "describes": {
                                                        "type": "string",
                                                        "description": "The same rhythm as one checkable sentence, e.g. \"Every week on Monday at 09:00 (Africa/Dar_es_Salaam)\"."
                                                    },
                                                    "target": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "What it acts on: a table id, a phone number, a flow id, a contact group id."
                                                    },
                                                    "payload": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "The kind's own arguments \u2014 the export spec, the record to write, the message body."
                                                    },
                                                    "misfire_policy": {
                                                        "type": "string",
                                                        "enum": [
                                                            "run_once",
                                                            "skip",
                                                            "run_all"
                                                        ],
                                                        "description": "What happens to runs missed while the platform was down. run_once fires once and carries on; skip fires not at all; run_all catches up, capped."
                                                    },
                                                    "enabled": {
                                                        "type": "boolean",
                                                        "description": "Whether it runs."
                                                    },
                                                    "next_run_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "The next slot, in UTC. Null when it is switched off or has run out."
                                                    },
                                                    "last_run_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When it last ran."
                                                    },
                                                    "last_result": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "nullable": true,
                                                        "description": "What the last run produced: ok, ref (the export, message or record it made), message, and a misfire block when slots were missed."
                                                    },
                                                    "last_error": {
                                                        "type": "string",
                                                        "nullable": true,
                                                        "description": "Why the last run failed."
                                                    },
                                                    "run_count": {
                                                        "type": "integer",
                                                        "description": "How many times it has run."
                                                    },
                                                    "created_at": {
                                                        "type": "string",
                                                        "format": "date-time",
                                                        "nullable": true,
                                                        "description": "When it was set up."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "schedules": [
                                                {
                                                    "id": "3f2a1b0c-9d8e-4f70-8a1b-2c3d4e5f6a7b",
                                                    "name": "Monday sales report",
                                                    "kind": "report",
                                                    "spec": {
                                                        "every": 1,
                                                        "unit": "weeks",
                                                        "at": "09:00",
                                                        "weekdays": [
                                                            1
                                                        ],
                                                        "timezone": "Africa/Dar_es_Salaam"
                                                    },
                                                    "describes": "Every week on Monday at 09:00 (Africa/Dar_es_Salaam)",
                                                    "target": null,
                                                    "payload": {
                                                        "export": {
                                                            "kind": "records",
                                                            "table_id": "1b2c3d4e-5f60-4718-9a2b-3c4d5e6f7a8b",
                                                            "format": "xlsx"
                                                        },
                                                        "deliver": {
                                                            "via": "email",
                                                            "to": "owner@example.co.tz"
                                                        }
                                                    },
                                                    "misfire_policy": "run_once",
                                                    "enabled": true,
                                                    "next_run_at": "2026-09-14T06:00:00+00:00",
                                                    "last_run_at": "2026-09-07T06:00:00+00:00",
                                                    "last_result": {
                                                        "ok": true,
                                                        "ref": "7a8b9c0d-1e2f-4304-8516-27384950a6b7",
                                                        "message": "Export queued."
                                                    },
                                                    "last_error": null,
                                                    "run_count": 6,
                                                    "created_at": "2026-07-20T08:11:00+03:00"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold automations.view, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"automations.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "The automations module is switched off for this workspace.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/engine/tasks": {
            "post": {
                "tags": [
                    "Agent tasks"
                ],
                "operationId": "engineTasksCreate",
                "summary": "Submit a task to an account agent",
                "description": "Submit a prompt and context to an enabled agent available for API execution. Mode defaults sync; queued mode returns a run for polling. Idempotency-Key reuses the tenant/trigger run for the same fingerprint and conflicts on a changed request. The API ceiling is 60 seconds, reduced by profile/request budgets. A successful HTTP response can contain failed/denied/timed_out domain status.",
                "parameters": [
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Optional stable key for this business request. Same request reuses the run; different fingerprint returns 409. Unlike messaging sends, this endpoint implements request-key deduplication.",
                        "schema": {
                            "type": "string",
                            "minLength": 1,
                            "maxLength": 191
                        },
                        "example": "order-1042-summary-v1"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "agent_id": {
                                        "type": "integer",
                                        "description": "Agent ID belonging to this account."
                                    },
                                    "prompt": {
                                        "type": "string",
                                        "description": "Task instruction.",
                                        "maxLength": 20000
                                    },
                                    "context": {
                                        "type": [
                                            "object",
                                            "array",
                                            "null"
                                        ],
                                        "description": "Additional task context.",
                                        "additionalProperties": true,
                                        "items": []
                                    },
                                    "mode": {
                                        "type": "string",
                                        "description": "Wait synchronously or enqueue for polling.",
                                        "enum": [
                                            "sync",
                                            "queued"
                                        ],
                                        "default": "sync"
                                    },
                                    "max_duration_ms": {
                                        "type": "integer",
                                        "description": "Requested maximum duration; cannot extend the API/profile ceiling.",
                                        "minimum": 1
                                    }
                                },
                                "required": [
                                    "agent_id",
                                    "prompt"
                                ]
                            },
                            "examples": {
                                "default": {
                                    "value": {
                                        "agent_id": 42,
                                        "prompt": "Summarize this order and suggest the next action.",
                                        "context": {
                                            "order_reference": "ORD-1042"
                                        },
                                        "mode": "queued",
                                        "max_duration_ms": 30000
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Synchronous outcome; inspect status rather than assuming successful execution.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineTaskResult"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "succeeded",
                                            "run_uuid": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                            "output": {
                                                "summary": "Order summary."
                                            },
                                            "denial_reason": null,
                                            "usage": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "Accepted for background execution. Poll status_url using the same REST credential.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineTaskAccepted"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "queued",
                                            "run_uuid": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                            "execution_state": "queued",
                                            "delivery_state": "none",
                                            "deadline_at": "2030-10-12T06:00:30+00:00",
                                            "status_url": "https://business.momo.tz/api/engine/runs/2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                            "denial_reason": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "REST credential failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Invalid API token."
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Suspended/inactive account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Account is suspended."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "Agent not found in this account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Agent not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Idempotency key already identifies a different request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineAdmissionError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "conflict",
                                            "message": "Idempotency-Key was already used for a different request."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Invalid request fields, or a queued task denied/timed out on submission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "oneOf": [
                                        {
                                            "$ref": "#/components/schemas/EngineRequestError"
                                        },
                                        {
                                            "$ref": "#/components/schemas/EngineTaskAccepted"
                                        }
                                    ]
                                },
                                "examples": {
                                    "invalidPrompt": {
                                        "summary": "Request validation failed before a run was created",
                                        "value": {
                                            "message": "The prompt field is required.",
                                            "errors": {
                                                "prompt": [
                                                    "The prompt field is required."
                                                ]
                                            }
                                        }
                                    },
                                    "deniedRun": {
                                        "summary": "Queued submission could not execute",
                                        "value": {
                                            "status": "denied",
                                            "run_uuid": "01953b60-4ce0-7000-8000-000000000001",
                                            "execution_state": "denied",
                                            "delivery_state": "none",
                                            "deadline_at": "2030-10-12T06:01:00+00:00",
                                            "status_url": "https://business.momo.tz/api/engine/runs/01953b60-4ce0-7000-8000-000000000001",
                                            "denial_reason": "surface_disabled"
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Pending capacity exceeded. Retry-After is 5 seconds.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineAdmissionError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "denied",
                                            "run_uuid": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d",
                                            "denial_reason": "tenant_pending_capacity",
                                            "retryable": true,
                                            "retry_after": 5,
                                            "status_url": "https://business.momo.tz/api/engine/runs/2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d"
                                        }
                                    }
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds to wait before attempting a safe retry.",
                                "schema": {
                                    "type": "integer",
                                    "example": 5
                                }
                            },
                            "Cache-Control": {
                                "description": "Admission response must not be cached.",
                                "schema": {
                                    "type": "string",
                                    "example": "no-store"
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "Temporary ingress contention. Retry-After is 1 second.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineAdmissionError"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "busy",
                                            "reason": "ingress_busy",
                                            "message": "Task ingress is busy.",
                                            "retryable": true,
                                            "retry_after": 1
                                        }
                                    }
                                }
                            }
                        },
                        "headers": {
                            "Retry-After": {
                                "description": "Seconds to wait before attempting a safe retry.",
                                "schema": {
                                    "type": "integer",
                                    "example": 1
                                }
                            },
                            "Cache-Control": {
                                "description": "Admission response must not be cached.",
                                "schema": {
                                    "type": "string",
                                    "example": "no-store"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/engine/runs/{uuid}": {
            "get": {
                "tags": [
                    "Agent tasks"
                ],
                "operationId": "engineRunsGet",
                "summary": "Read an agent run, children and trace steps",
                "description": "Tenant-scoped polling and inspection. Response contains run outcome, execution/delivery state, output, model usage, costs, child runs and trace steps. Sent with Cache-Control: no-store. Treat trace arguments/results as sensitive business data.",
                "parameters": [
                    {
                        "name": "uuid",
                        "in": "path",
                        "required": true,
                        "description": "Run UUID returned by task submission.",
                        "schema": {
                            "type": "string",
                            "format": "uuid"
                        },
                        "example": "2c7e1a9b-3d4f-4a5b-8c6d-7e8f9a0b1c2d"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Run and available trace. Cache-Control: no-store.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/EngineRunDetail"
                                },
                                "example": {
                                    "run": {
                                        "uuid": "01953b60-4ce0-7000-8000-000000000001",
                                        "trigger": "api",
                                        "status": "succeeded",
                                        "execution_state": "succeeded",
                                        "delivery_state": "none",
                                        "deadline_at": "2030-10-12T06:01:00+00:00",
                                        "denial_reason": null,
                                        "output": {
                                            "answer": "The report is ready."
                                        },
                                        "provider": "example-provider",
                                        "model_name": "configured-model",
                                        "prompt_tokens": 120,
                                        "completion_tokens": 45,
                                        "cost_wallet": 0.01,
                                        "cost_currency": "TZS",
                                        "duration_ms": 840,
                                        "created_at": "2030-10-12T06:00:00+00:00"
                                    },
                                    "children": [],
                                    "steps": []
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "REST credential failure.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Invalid API token."
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "Suspended/inactive account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "Account is suspended."
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No run with this UUID in the authenticated account.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Run not found."
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api/v3/operations/{key}": {
            "post": {
                "tags": [
                    "Operations"
                ],
                "operationId": "v3OperationRun",
                "x-permission": "operations.run",
                "x-permission-scope": "controller",
                "summary": "Run a named operation",
                "description": "Do one of this workspace's named operations and get back what it produced.\n\nSend the values it asks for either as a top-level object or wrapped in `inputs`; both are read. Every value is validated first, by the same rules a chat flow and an assistant are held to, and a refusal names the field and changes nothing \u2014 `status` is then `invalid` and `steps` is empty, which is how you tell \"we did not start\" from \"we started and stopped\".\n\nSet `Idempotency-Key` on anything you might retry. A repeat of a key whose call SUCCEEDED replays the identical response with `X-Idempotent-Replay: 1`, so a request that timed out can be sent again without creating a second booking or a second bill. A key whose call was refused is not spent \u2014 fix the value and send it again under the same key. A key whose run failed part-way replays that failure rather than redoing half of it, because steps before the break really happened.\n\nWhen a step fails part-way, the record writes made before it are undone and `rolled_back` says how many went back, how many were left alone because somebody else had changed them, and how many could not be found. `not_undone` says what stayed done \u2014 a message already sent, money already asked for. Nothing outside the data store is reversible, and this endpoint says so rather than implying otherwise.\n\nAn operation never waits. If one of its steps raises an approval, the answer comes back as soon as the approvers are notified: it means they were asked, not that they said yes.",
                "parameters": [
                    {
                        "name": "key",
                        "in": "path",
                        "required": true,
                        "description": "The operation's key, in snake_case, as it appears on the Operations page. An unknown key answers 404 \u2014 and so does one belonging to another workspace.",
                        "schema": {
                            "type": "string",
                            "example": "create_booking"
                        }
                    },
                    {
                        "name": "Idempotency-Key",
                        "in": "header",
                        "required": false,
                        "description": "Any string you choose. A repeat of a key whose call succeeded replays the identical response with X-Idempotent-Replay: 1. A refused call does not spend its key.",
                        "schema": {
                            "type": "string",
                            "example": "booking-2026-09-09-0042"
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "description": "The values the operation asks for. Either wrapped in `inputs` or at the top level.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "inputs": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "The values the operation asks for, keyed by its own input names. Leave it out and the top level of the body is read instead."
                                    },
                                    "idempotency_key": {
                                        "type": "string",
                                        "description": "The same thing as the Idempotency-Key header, for clients that cannot set one. The header wins."
                                    }
                                }
                            },
                            "example": {
                                "inputs": {
                                    "customer_phone": "0712345678",
                                    "seats": 2,
                                    "day": "2026-09-14"
                                },
                                "idempotency_key": "booking-2026-09-09-0042"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The operation ran. Every step succeeded and `outputs` is what it promised.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "ok",
                                        "status",
                                        "outputs"
                                    ],
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "description": "True only when every step ran."
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "ok",
                                                "failed",
                                                "invalid"
                                            ],
                                            "description": "ok \u2014 it ran. invalid \u2014 the inputs were refused and nothing ran. failed \u2014 a step broke part-way."
                                        },
                                        "run_id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "This run's id. Time-ordered, and what the Operations page's run log is keyed by."
                                        },
                                        "outputs": {
                                            "type": "object",
                                            "additionalProperties": true,
                                            "description": "What the operation promised back \u2014 a booking reference, a record id, an amount."
                                        },
                                        "steps": {
                                            "type": "array",
                                            "description": "One entry per step that ran, in order.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "step": {
                                                        "type": "string",
                                                        "description": "The step's id, as the definition names it."
                                                    },
                                                    "type": {
                                                        "type": "string",
                                                        "description": "What kind of step it was: data_save, rule, payment_intent, send\u2026"
                                                    },
                                                    "ok": {
                                                        "type": "boolean",
                                                        "description": "Whether that step succeeded."
                                                    },
                                                    "ms": {
                                                        "type": "integer",
                                                        "description": "How long that step took, in milliseconds. This is the number that answers \"why was it slow\"."
                                                    },
                                                    "detail": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "What the step produced \u2014 the record it wrote, the rule's answer, the payment reference."
                                                    },
                                                    "not_undone": {
                                                        "type": "string",
                                                        "description": "Present when this step did something a rollback cannot take back."
                                                    }
                                                }
                                            }
                                        },
                                        "replayed": {
                                            "type": "boolean",
                                            "description": "Present and true when this answer was replayed for a repeated idempotency key rather than run again."
                                        },
                                        "message": {
                                            "type": "string",
                                            "description": "Absent on success. Present on a refusal, carrying the same sentence as error.message for older v3 clients."
                                        }
                                    }
                                },
                                "example": {
                                    "ok": true,
                                    "status": "ok",
                                    "run_id": "0192f3b8-6c2a-7c31-9f2e-5b1c0a7d4e11",
                                    "outputs": {
                                        "booking_ref": "BKG-0042",
                                        "record_id": "9a1c0c7e-1f8c-4a41-9b1e-0d2f7c9b3a55"
                                    },
                                    "steps": [
                                        {
                                            "step": "check_limit",
                                            "type": "rule",
                                            "ok": true,
                                            "ms": 12,
                                            "detail": {
                                                "passed": true,
                                                "value": 2
                                            }
                                        },
                                        {
                                            "step": "booking",
                                            "type": "data_save",
                                            "ok": true,
                                            "ms": 41,
                                            "detail": {
                                                "record_id": "9a1c0c7e-1f8c-4a41-9b1e-0d2f7c9b3a55"
                                            }
                                        }
                                    ]
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold operations.run, or the key has no issuer on record.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"operations.run\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No operation with that key in this workspace.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "No operation with that key on this account."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The inputs were refused, or a step failed. `status` says which: `invalid` means nothing ran, `failed` means a step broke and the record writes before it were undone.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "ok": {
                                            "type": "boolean",
                                            "description": "False."
                                        },
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "invalid",
                                                "failed"
                                            ],
                                            "description": "invalid \u2014 the inputs were refused before step one. failed \u2014 a step broke part-way."
                                        },
                                        "run_id": {
                                            "type": "string",
                                            "format": "uuid",
                                            "description": "The run this refusal was recorded against; it is in the run log either way."
                                        },
                                        "outputs": {
                                            "type": "object",
                                            "additionalProperties": true,
                                            "description": "Empty on a refusal: an operation promises nothing it did not finish."
                                        },
                                        "error": {
                                            "type": "object",
                                            "description": "The platform error envelope: a machine code, a sentence a person can act on, and the field at fault.",
                                            "properties": {
                                                "code": {
                                                    "type": "string",
                                                    "description": "validation_error, conflict, not_found, quota_exceeded, rate_limited, temporary_failure, permission_denied, not_supported or provider_failure."
                                                },
                                                "message": {
                                                    "type": "string",
                                                    "description": "What went wrong, written for a person to read."
                                                },
                                                "field": {
                                                    "type": "string",
                                                    "description": "The input or the step at fault."
                                                }
                                            }
                                        },
                                        "rolled_back": {
                                            "type": "object",
                                            "description": "Present on a `failed` run: what the compensating rollback managed to put back.",
                                            "properties": {
                                                "attempted": {
                                                    "type": "integer",
                                                    "description": "How many record writes had inverses to replay."
                                                },
                                                "restored": {
                                                    "type": "integer",
                                                    "description": "How many went back."
                                                },
                                                "conflicts": {
                                                    "type": "integer",
                                                    "description": "How many were left alone because somebody else had changed them since. A rollback never overwrites another person's work."
                                                },
                                                "missing": {
                                                    "type": "integer",
                                                    "description": "How many rows could no longer be found."
                                                },
                                                "failed": {
                                                    "type": "integer",
                                                    "description": "How many inverses could not be applied at all."
                                                },
                                                "not_journalled": {
                                                    "type": "boolean",
                                                    "description": "True when the operation wrote more than the journal holds, so later writes are not reversible."
                                                }
                                            }
                                        },
                                        "not_undone": {
                                            "type": "array",
                                            "description": "What stayed done: a message already sent, money already asked for, an approval already raised. Nothing outside the data store comes back.",
                                            "items": {
                                                "type": "string",
                                                "description": "One sentence per irreversible thing that happened."
                                            }
                                        },
                                        "steps": {
                                            "type": "array",
                                            "description": "The steps that ran before it stopped, with their timing. Empty when the status is `invalid`.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "step": {
                                                        "type": "string",
                                                        "description": "The step's id, as the definition names it."
                                                    },
                                                    "type": {
                                                        "type": "string",
                                                        "description": "What kind of step it was: data_save, rule, payment_intent, send\u2026"
                                                    },
                                                    "ok": {
                                                        "type": "boolean",
                                                        "description": "Whether that step succeeded."
                                                    },
                                                    "ms": {
                                                        "type": "integer",
                                                        "description": "How long that step took, in milliseconds. This is the number that answers \"why was it slow\"."
                                                    },
                                                    "detail": {
                                                        "type": "object",
                                                        "additionalProperties": true,
                                                        "description": "What the step produced \u2014 the record it wrote, the rule's answer, the payment reference."
                                                    },
                                                    "not_undone": {
                                                        "type": "string",
                                                        "description": "Present when this step did something a rollback cannot take back."
                                                    }
                                                }
                                            }
                                        },
                                        "message": {
                                            "type": "string",
                                            "description": "The same sentence as error.message, for older v3 clients."
                                        }
                                    }
                                },
                                "examples": {
                                    "refused": {
                                        "value": {
                                            "ok": false,
                                            "status": "invalid",
                                            "run_id": "0192f3b8-6c2a-7c31-9f2e-5b1c0a7d4e11",
                                            "outputs": [],
                                            "steps": [],
                                            "error": {
                                                "code": "validation_error",
                                                "message": "Customer phone: That does not look like a phone number. Send it as 0712 345 678.",
                                                "field": "customer_phone"
                                            },
                                            "message": "Customer phone: That does not look like a phone number. Send it as 0712 345 678."
                                        }
                                    },
                                    "failed_partway": {
                                        "value": {
                                            "ok": false,
                                            "status": "failed",
                                            "run_id": "0192f3b8-7a10-7bd2-8c44-2e9f1a6b0c93",
                                            "outputs": [],
                                            "error": {
                                                "code": "conflict",
                                                "message": "There is nothing left to give out just now.",
                                                "field": "seat"
                                            },
                                            "rolled_back": {
                                                "attempted": 1,
                                                "restored": 1,
                                                "conflicts": 0,
                                                "missing": 0,
                                                "failed": 0,
                                                "not_journalled": false
                                            },
                                            "not_undone": [
                                                "A sms message was sent to 255712345678."
                                            ],
                                            "message": "There is nothing left to give out just now."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/products/by-sku/{sku}": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3ProductShowBySku",
                "summary": "Read a product by your own code",
                "description": "The same product as `GET /products/{product}`, addressed by the code your system already knows it by, so a sync never has to keep a map of our numeric ids.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sku",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 100,
                            "example": "MNG-45W"
                        },
                        "description": "Your own product code \u2014 `sku`, or the older `retailer_id`."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The product.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9301,
                                        "catalogue_id": 42,
                                        "sku": "MNG-45W",
                                        "retailer_id": "MNG-45W",
                                        "meta_product_id": "7766554433",
                                        "name": "Charger Mango 45W",
                                        "description": "USB-C PD, 1 m cable",
                                        "url": "https://shop.example.com/mng45",
                                        "price": 4500000,
                                        "currency": "TZS",
                                        "sale_price": 3900000,
                                        "image_url": "https://cdn.example.com/mng45.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": "Mango",
                                        "category": "Chargers",
                                        "product_type": "Electronics > Chargers",
                                        "inventory": 12,
                                        "visibility": "published",
                                        "review_status": "approved",
                                        "sync_status": "synced",
                                        "listings": [
                                            {
                                                "platform": "whatsapp",
                                                "state": "synced",
                                                "external_id": "7766554433",
                                                "problem": null,
                                                "review_status": "approved",
                                                "last_synced_at": "2026-09-11T02:00:41+00:00"
                                            }
                                        ],
                                        "last_synced_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-01T08:20:00+00:00",
                                        "updated_at": "2026-09-11T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "put": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3ProductUpsertBySku",
                "summary": "Create or update a product by your own code",
                "description": "Changes the product with this code, or creates it when there is none \u2014 so a store that has just added an item does not have to know whether we have seen it before. Only the fields you send are touched.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sku",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 100,
                            "example": "MNG-45W"
                        },
                        "description": "Your own product code \u2014 `sku`, or the older `retailer_id`."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [],
                                "description": "A product. Only a name and a price are required here; an image, a non-zero price and the rest are what individual PLATFORMS require, and a product missing them is stored and reported as `blocked` on that platform rather than refused.",
                                "properties": {
                                    "sku": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "Your product code. Left out, the shop issues one."
                                    },
                                    "retailer_id": {
                                        "type": "string",
                                        "maxLength": 100,
                                        "description": "The older name for `sku`."
                                    },
                                    "name": {
                                        "type": "string",
                                        "maxLength": 200,
                                        "description": "Product name as customers see it."
                                    },
                                    "price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Price in the minor unit of `currency` \u2014 25000 is TZS 250.00 for a 2-decimal currency."
                                    },
                                    "currency": {
                                        "type": "string",
                                        "minLength": 3,
                                        "maxLength": 3,
                                        "description": "ISO 4217 code. Left out, the shop's own currency is used."
                                    },
                                    "description": {
                                        "type": "string",
                                        "maxLength": 9000,
                                        "description": "Long description."
                                    },
                                    "sale_price": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Optional sale price in the minor unit. Ignored when it is higher than `price`."
                                    },
                                    "image_url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "Publicly reachable image. Platforms fetch it themselves, so it cannot sit behind a login."
                                    },
                                    "additional_image_urls": {
                                        "type": "array",
                                        "maxItems": 10,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "description": "Up to ten more images."
                                    },
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "The product page on your own site."
                                    },
                                    "availability": {
                                        "type": "string",
                                        "enum": [
                                            "in stock",
                                            "out of stock",
                                            "preorder",
                                            "available for order",
                                            "discontinued"
                                        ],
                                        "description": "Left out, it is derived from `inventory`: a count of zero means `out of stock` unless the shop allows backorders. Sent explicitly, what you send wins."
                                    },
                                    "condition": {
                                        "type": "string",
                                        "enum": [
                                            "new",
                                            "refurbished",
                                            "used"
                                        ],
                                        "description": "Item condition."
                                    },
                                    "brand": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Brand name. Becomes a brand record on first use."
                                    },
                                    "category": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Category name. Becomes a category record on first use."
                                    },
                                    "product_type": {
                                        "type": "string",
                                        "maxLength": 750,
                                        "description": "Your own taxonomy path."
                                    },
                                    "inventory": {
                                        "type": "integer",
                                        "minimum": 0,
                                        "description": "Units on hand."
                                    },
                                    "visibility": {
                                        "type": "string",
                                        "enum": [
                                            "staging",
                                            "published"
                                        ],
                                        "description": "Whether customers may see it."
                                    },
                                    "custom_labels": {
                                        "type": "array",
                                        "maxItems": 5,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Up to five free labels for your own segmentation."
                                    }
                                }
                            },
                            "example": {
                                "inventory": 0,
                                "price": 4200000
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated product.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9301,
                                        "catalogue_id": 42,
                                        "sku": "MNG-45W",
                                        "retailer_id": "MNG-45W",
                                        "meta_product_id": "7766554433",
                                        "name": "Charger Mango 45W",
                                        "description": "USB-C PD, 1 m cable",
                                        "url": "https://shop.example.com/mng45",
                                        "price": 4500000,
                                        "currency": "TZS",
                                        "sale_price": 3900000,
                                        "image_url": "https://cdn.example.com/mng45.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": "Mango",
                                        "category": "Chargers",
                                        "product_type": "Electronics > Chargers",
                                        "inventory": 12,
                                        "visibility": "published",
                                        "review_status": "approved",
                                        "sync_status": "synced",
                                        "listings": [
                                            {
                                                "platform": "whatsapp",
                                                "state": "synced",
                                                "external_id": "7766554433",
                                                "problem": null,
                                                "review_status": "approved",
                                                "last_synced_at": "2026-09-11T02:00:41+00:00"
                                            }
                                        ],
                                        "last_synced_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-01T08:20:00+00:00",
                                        "updated_at": "2026-09-11T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "201": {
                        "description": "The product did not exist and was created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Product",
                                            "description": "The product record."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9301,
                                        "catalogue_id": 42,
                                        "sku": "MNG-45W",
                                        "retailer_id": "MNG-45W",
                                        "meta_product_id": "7766554433",
                                        "name": "Charger Mango 45W",
                                        "description": "USB-C PD, 1 m cable",
                                        "url": "https://shop.example.com/mng45",
                                        "price": 4500000,
                                        "currency": "TZS",
                                        "sale_price": 3900000,
                                        "image_url": "https://cdn.example.com/mng45.jpg",
                                        "availability": "in stock",
                                        "condition": "new",
                                        "brand": "Mango",
                                        "category": "Chargers",
                                        "product_type": "Electronics > Chargers",
                                        "inventory": 12,
                                        "visibility": "published",
                                        "review_status": "approved",
                                        "sync_status": "synced",
                                        "listings": [
                                            {
                                                "platform": "whatsapp",
                                                "state": "synced",
                                                "external_id": "7766554433",
                                                "problem": null,
                                                "review_status": "approved",
                                                "last_synced_at": "2026-09-11T02:00:41+00:00"
                                            }
                                        ],
                                        "last_synced_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-01T08:20:00+00:00",
                                        "updated_at": "2026-09-11T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3ProductDeleteBySku",
                "summary": "Delete a product by your own code",
                "description": "Takes the product off every platform it is on, then off the shelf.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sku",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 100,
                            "example": "MNG-45W"
                        },
                        "description": "Your own product code \u2014 `sku`, or the older `retailer_id`."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The product was removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true."
                                                },
                                                "id": {
                                                    "type": "integer",
                                                    "description": "The id of the product that was removed."
                                                },
                                                "sku": {
                                                    "type": "string",
                                                    "description": "The code it was known by."
                                                },
                                                "retailer_id": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "The older name for that code."
                                                }
                                            },
                                            "description": "What was removed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "id": 9301,
                                        "sku": "MNG-45W",
                                        "retailer_id": "MNG-45W"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/syncs": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueSyncIndex",
                "summary": "List bulk writes",
                "description": "Every bulk write into this catalogue, newest first \u2014 the API, a scheduled feed pull, or a spreadsheet import.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of syncs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/CatalogueSync"
                                                    },
                                                    "description": "The syncs on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "A page of syncs."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 812,
                                                "catalogue_id": 42,
                                                "source": "api",
                                                "mode": "upsert",
                                                "status": "completed",
                                                "idempotency_key": "nightly-2026-09-11",
                                                "received": 2000,
                                                "created": 12,
                                                "updated": 1982,
                                                "unchanged": 0,
                                                "rejected": 6,
                                                "retired": 0,
                                                "platforms": {
                                                    "whatsapp": {
                                                        "synced": 1960,
                                                        "blocked": 34
                                                    }
                                                },
                                                "problems": [
                                                    {
                                                        "sku": "MNG-CABLE",
                                                        "stage": "ingest",
                                                        "reason": "Price must be a whole number of minor units, 0 or more."
                                                    },
                                                    {
                                                        "sku": "MNG-KNIFE",
                                                        "stage": "whatsapp",
                                                        "reason": "WhatsApp needs a product image it can fetch."
                                                    }
                                                ],
                                                "problems_truncated": false,
                                                "error": null,
                                                "started_at": "2026-09-11T02:00:05+00:00",
                                                "finished_at": "2026-09-11T02:00:41+00:00",
                                                "created_at": "2026-09-11T02:00:04+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/syncs/{sync}": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3CatalogueSyncShow",
                "summary": "Read a sync report",
                "description": "What became of one bulk write. `problems[].stage` is the field to read first: `ingest` means the row was not stored at all, and any other value is the name of a platform that stored it but will not show it \u2014 two very different things that both look like \"my product is not live\".",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sync",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 812
                        },
                        "description": "Sync id, from the batch response."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The sync report.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CatalogueSync",
                                            "description": "The sync report."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 812,
                                        "catalogue_id": 42,
                                        "source": "api",
                                        "mode": "upsert",
                                        "status": "completed",
                                        "idempotency_key": "nightly-2026-09-11",
                                        "received": 2000,
                                        "created": 12,
                                        "updated": 1982,
                                        "unchanged": 0,
                                        "rejected": 6,
                                        "retired": 0,
                                        "platforms": {
                                            "whatsapp": {
                                                "synced": 1960,
                                                "blocked": 34
                                            }
                                        },
                                        "problems": [
                                            {
                                                "sku": "MNG-CABLE",
                                                "stage": "ingest",
                                                "reason": "Price must be a whole number of minor units, 0 or more."
                                            },
                                            {
                                                "sku": "MNG-KNIFE",
                                                "stage": "whatsapp",
                                                "reason": "WhatsApp needs a product image it can fetch."
                                            }
                                        ],
                                        "problems_truncated": false,
                                        "error": null,
                                        "started_at": "2026-09-11T02:00:05+00:00",
                                        "finished_at": "2026-09-11T02:00:41+00:00",
                                        "created_at": "2026-09-11T02:00:04+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/inventory": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3StockUpdate",
                "summary": "Set stock levels in bulk",
                "description": "The endpoint to call the moment something sells on your own site. Levels are **absolute**, never deltas \u2014 your system is stating what it has, and a delta would drift out of step the first time a message was delivered twice.\n\nAvailability follows the count: unless the shop allows backorders, a level of `0` sets the product to `out of stock` and stock coming back lifts it to `in stock` again. `derived` in the response names every product where that happened. A `discontinued` or `preorder` product is never quietly put back on sale by a delivery arriving.\n\nCodes we do not have come back in `unknown_skus` rather than being ignored, and one push is sent to every platform the shop is on rather than one per product.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "levels"
                                ],
                                "properties": {
                                    "levels": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 5000,
                                        "description": "Up to 5,000 levels. A row needs a code and a whole-number count.",
                                        "items": {
                                            "type": "object",
                                            "required": [
                                                "sku",
                                                "inventory"
                                            ],
                                            "properties": {
                                                "sku": {
                                                    "type": "string",
                                                    "maxLength": 100,
                                                    "description": "Your product code (`retailer_id` also accepted)."
                                                },
                                                "inventory": {
                                                    "type": "integer",
                                                    "minimum": 0,
                                                    "description": "Units on hand, absolute."
                                                }
                                            }
                                        }
                                    }
                                }
                            },
                            "example": {
                                "levels": [
                                    {
                                        "sku": "MNG-45W",
                                        "inventory": 0
                                    },
                                    {
                                        "sku": "MNG-20W",
                                        "inventory": 37
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "What the levels changed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "updated": {
                                                    "type": "integer",
                                                    "description": "Products whose count changed."
                                                },
                                                "unchanged": {
                                                    "type": "integer",
                                                    "description": "Products already at that level; nothing was re-published for these."
                                                },
                                                "unknown_skus": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Codes this catalogue does not have."
                                                },
                                                "malformed": {
                                                    "type": "array",
                                                    "items": {
                                                        "type": "string"
                                                    },
                                                    "description": "Rows missing a code or a usable count."
                                                },
                                                "derived": {
                                                    "type": "array",
                                                    "description": "Products whose availability changed as a result.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "sku": {
                                                                "type": "string",
                                                                "description": "The product code."
                                                            },
                                                            "availability": {
                                                                "type": "string",
                                                                "description": "What it became."
                                                            }
                                                        }
                                                    }
                                                },
                                                "platforms": {
                                                    "type": "object",
                                                    "additionalProperties": {
                                                        "type": "object",
                                                        "additionalProperties": {
                                                            "type": "integer"
                                                        }
                                                    },
                                                    "description": "Per platform, how many listings ended in each state after the push."
                                                }
                                            },
                                            "description": "What changed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "updated": 2,
                                        "unchanged": 0,
                                        "unknown_skus": [],
                                        "malformed": [],
                                        "derived": [
                                            {
                                                "sku": "MNG-45W",
                                                "availability": "out of stock"
                                            }
                                        ],
                                        "platforms": {
                                            "whatsapp": {
                                                "pending": 2
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3StockIndex",
                "summary": "Read stock levels",
                "description": "On hand, held by pending orders, and the difference \u2014 which is the number that decides whether a customer may buy. A product with `tracked: false` carries no count and is never held back.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sku",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            },
                            "example": [
                                "MNG-45W"
                            ]
                        },
                        "description": "Only these product codes."
                    },
                    {
                        "name": "tracked_only",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "boolean",
                            "default": false
                        },
                        "description": "Only products that carry a count."
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of stock levels.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/StockLevel"
                                                    },
                                                    "description": "The rows on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "A page of stock levels."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "sku": "MNG-45W",
                                                "inventory": 12,
                                                "reserved": 2,
                                                "available": 10,
                                                "availability": "in stock",
                                                "tracked": true
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 100,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/products/by-sku/{sku}/movements": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3StockMovements",
                "summary": "Read a product\u2019s stock history",
                "description": "Every event that has ever moved this count, newest first \u2014 who moved it, why, and what the figures became. This is the audit trail behind `inventory` and `reserved`.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "sku",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "maxLength": 100,
                            "example": "MNG-45W"
                        },
                        "description": "Your own product code."
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of movements.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/InventoryMovement"
                                                    },
                                                    "description": "The rows on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "A page of movements."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 4411,
                                                "kind": "commit",
                                                "quantity": -2,
                                                "on_hand_after": 10,
                                                "reserved_after": 0,
                                                "order_id": 9182,
                                                "reason": null,
                                                "actor": "whatsapp",
                                                "created_at": "2026-09-11T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 100,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/webhooks/events": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookEvents",
                "summary": "List every event we can send",
                "description": "The whole catalogue, grouped, with a sample payload for each. This is what the dashboard picker shows and what the `event` enum in the delivery schema is generated from, so a name here is by definition one the platform sends.",
                "responses": {
                    "200": {
                        "description": "The event catalogue.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "events": {
                                                    "type": "array",
                                                    "description": "One entry per event.",
                                                    "items": {
                                                        "type": "object",
                                                        "properties": {
                                                            "event": {
                                                                "type": "string",
                                                                "description": "The name to subscribe with."
                                                            },
                                                            "group": {
                                                                "type": "string",
                                                                "description": "Family: Messages, Orders, Catalogue, Campaigns, WhatsApp groups, Webhooks."
                                                            },
                                                            "label": {
                                                                "type": "string",
                                                                "description": "Human name."
                                                            },
                                                            "description": {
                                                                "type": "string",
                                                                "description": "When it fires and what to do with it."
                                                            },
                                                            "sample": {
                                                                "type": "object",
                                                                "description": "A complete example body."
                                                            }
                                                        }
                                                    }
                                                }
                                            },
                                            "description": "The event catalogue."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "events": [
                                            {
                                                "event": "message.received",
                                                "group": "Messages",
                                                "label": "A message arrived",
                                                "description": "An inbound message from a customer on any channel.",
                                                "sample": {
                                                    "event": "message.received",
                                                    "message_id": 101,
                                                    "direction": "inbound",
                                                    "sender": "255712345678",
                                                    "recipient": "MyBrand",
                                                    "status": "received",
                                                    "body": "Habari, mna kanga?",
                                                    "media_url": null,
                                                    "channel_type": "whatsapp",
                                                    "timestamp": "2026-09-11T09:14:02+00:00"
                                                }
                                            },
                                            {
                                                "event": "message.sent",
                                                "group": "Messages",
                                                "label": "A message was sent",
                                                "description": "An outbound message was handed to the carrier.",
                                                "sample": {
                                                    "event": "message.sent",
                                                    "message_id": 102,
                                                    "direction": "outbound",
                                                    "sender": "MyBrand",
                                                    "recipient": "255712345678",
                                                    "status": "sent",
                                                    "body": "Ndiyo, tuna kanga.",
                                                    "media_url": null,
                                                    "channel_type": "whatsapp",
                                                    "timestamp": "2026-09-11T09:14:02+00:00"
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/webhooks": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookIndex",
                "summary": "List your receivers",
                "description": "Every endpoint registered on this account, with its health.",
                "responses": {
                    "200": {
                        "description": "Your receivers.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Webhook"
                                                    },
                                                    "description": "The receivers."
                                                }
                                            },
                                            "description": "Your receivers."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 7,
                                                "url": "https://store.example.com/momo",
                                                "events": [
                                                    "order.received",
                                                    "order.status_changed"
                                                ],
                                                "is_active": true,
                                                "paused_at": null,
                                                "paused_reason": null,
                                                "consecutive_failures": 0,
                                                "last_delivered_at": "2026-09-11T09:14:03+00:00",
                                                "created_at": "2026-09-01T08:15:00+00:00",
                                                "updated_at": "2026-09-11T09:14:03+00:00"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookCreate",
                "summary": "Register a receiver",
                "description": "Subscribe a URL to events. **The response carries `secret` \u2014 the only time it is ever shown.** Store it; your receiver verifies every delivery with it. Needs a key issued by a user with `webhooks.manage`.",
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "A public http(s) address. Private and internal targets are refused."
                                    },
                                    "events": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 60,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Event names from `GET /api/v3/webhooks/events`. An unknown name is refused."
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "description": "Switch the receiver on or off. Turning a paused endpoint back on resumes it."
                                    }
                                },
                                "required": [
                                    "url",
                                    "events"
                                ]
                            },
                            "example": {
                                "url": "https://store.example.com/momo",
                                "events": [
                                    "order.received",
                                    "order.status_changed"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The receiver, with its secret.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "allOf": [
                                                {
                                                    "$ref": "#/components/schemas/Webhook"
                                                },
                                                {
                                                    "type": "object",
                                                    "properties": {
                                                        "secret": {
                                                            "type": "string",
                                                            "description": "The signing secret. Shown here and never again."
                                                        }
                                                    }
                                                }
                                            ],
                                            "description": "The receiver, with its secret."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 7,
                                        "url": "https://store.example.com/momo",
                                        "events": [
                                            "order.received",
                                            "order.status_changed"
                                        ],
                                        "is_active": true,
                                        "paused_at": null,
                                        "paused_reason": null,
                                        "consecutive_failures": 0,
                                        "last_delivered_at": "2026-09-11T09:14:03+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T09:14:03+00:00",
                                        "secret": "cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/webhooks/{webhook}": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookShow",
                "summary": "Read a receiver",
                "description": "One receiver and its health. The secret is not included.",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The receiver.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Webhook",
                                            "description": "The receiver."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 7,
                                        "url": "https://store.example.com/momo",
                                        "events": [
                                            "order.received",
                                            "order.status_changed"
                                        ],
                                        "is_active": true,
                                        "paused_at": null,
                                        "paused_reason": null,
                                        "consecutive_failures": 0,
                                        "last_delivered_at": "2026-09-11T09:14:03+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T09:14:03+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookUpdate",
                "summary": "Change a receiver",
                "description": "Change the URL, the events, or switch it on or off. Setting `is_active: true` on a paused endpoint resumes it.",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "A public http(s) address. Private and internal targets are refused."
                                    },
                                    "events": {
                                        "type": "array",
                                        "minItems": 1,
                                        "maxItems": 60,
                                        "items": {
                                            "type": "string"
                                        },
                                        "description": "Event names from `GET /api/v3/webhooks/events`. An unknown name is refused."
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "description": "Switch the receiver on or off. Turning a paused endpoint back on resumes it."
                                    }
                                }
                            },
                            "example": {
                                "events": [
                                    "order.received",
                                    "order.status_changed",
                                    "stock.low"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated receiver.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Webhook",
                                            "description": "The updated receiver."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 7,
                                        "url": "https://store.example.com/momo",
                                        "events": [
                                            "order.received",
                                            "order.status_changed"
                                        ],
                                        "is_active": true,
                                        "paused_at": null,
                                        "paused_reason": null,
                                        "consecutive_failures": 0,
                                        "last_delivered_at": "2026-09-11T09:14:03+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T09:14:03+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookDelete",
                "summary": "Remove a receiver",
                "description": "Stops every delivery to it. The delivery log goes with it.",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true."
                                                },
                                                "id": {
                                                    "type": "integer",
                                                    "description": "The id that was removed."
                                                }
                                            },
                                            "description": "What was removed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "id": 7
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/webhooks/{webhook}/rotate-secret": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookRotateSecret",
                "summary": "Issue a new signing secret",
                "description": "The old secret stops verifying immediately, so update your receiver first and rotate second. The new one is in the response and is never shown again.",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The receiver, with its new secret.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "allOf": [
                                                {
                                                    "$ref": "#/components/schemas/Webhook"
                                                },
                                                {
                                                    "type": "object",
                                                    "properties": {
                                                        "secret": {
                                                            "type": "string",
                                                            "description": "The new signing secret. Shown here and never again."
                                                        }
                                                    }
                                                }
                                            ],
                                            "description": "The receiver, with its new secret."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 7,
                                        "url": "https://store.example.com/momo",
                                        "events": [
                                            "order.received",
                                            "order.status_changed"
                                        ],
                                        "is_active": true,
                                        "paused_at": null,
                                        "paused_reason": null,
                                        "consecutive_failures": 0,
                                        "last_delivered_at": "2026-09-11T09:14:03+00:00",
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-11T09:14:03+00:00",
                                        "secret": "dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/webhooks/{webhook}/deliveries": {
            "get": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookDeliveries",
                "summary": "Read the delivery log",
                "description": "Every delivery to this receiver, newest first: what was sent, how many times, what came back. This is how you find out an endpoint has been failing without waiting for a customer to complain.",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "delivered",
                                "failed",
                                "skipped"
                            ],
                            "example": "failed"
                        },
                        "description": "Only deliveries in this state."
                    },
                    {
                        "name": "event",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "example": "order.received"
                        },
                        "description": "Only this event."
                    },
                    {
                        "name": "since",
                        "in": "query",
                        "required": false,
                        "schema": {
                            "type": "string",
                            "format": "date-time",
                            "example": "2026-09-11T00:00:00+00:00"
                        },
                        "description": "Only deliveries created at or after this moment."
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of deliveries.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WebhookDelivery"
                                                    },
                                                    "description": "The deliveries on this page."
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "A page of deliveries."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 4410,
                                                "delivery_uid": "dlv_01j9qk3v8x2m7n4p5r6s",
                                                "event": "order.received",
                                                "status": "delivered",
                                                "attempts": 1,
                                                "next_attempt_at": null,
                                                "last_attempt_at": "2026-09-11T09:14:03+00:00",
                                                "delivered_at": "2026-09-11T09:14:03+00:00",
                                                "response_code": 200,
                                                "response_excerpt": "ok",
                                                "error": null,
                                                "replay_of_id": null,
                                                "payload": {
                                                    "event": "order.received",
                                                    "order": {
                                                        "id": 9182,
                                                        "catalogue_id": 42,
                                                        "platform": "whatsapp",
                                                        "status": "pending",
                                                        "needs_attention": false,
                                                        "stock_policy": "external",
                                                        "customer_handle": "255712345678",
                                                        "customer_name": "Asha Mrisho",
                                                        "customer_phone": "255712345678",
                                                        "customer_note": null,
                                                        "lines": [
                                                            {
                                                                "sku": "MNG-45W",
                                                                "name": "Charger Mango 45W",
                                                                "quantity": 1,
                                                                "unit_price_minor": 3900000,
                                                                "line_total_minor": 3900000,
                                                                "currency": "TZS",
                                                                "reserved": 1,
                                                                "stock_short": false,
                                                                "unresolved": false
                                                            }
                                                        ],
                                                        "total_minor": 3900000,
                                                        "currency": "TZS",
                                                        "conversation_id": 771,
                                                        "priced_at": "2026-09-11T09:14:02+00:00",
                                                        "created_at": "2026-09-11T09:14:02+00:00",
                                                        "order_id": 9182,
                                                        "customer_wa_id": "255712345678",
                                                        "total_amount": 3900000,
                                                        "total_currency": "TZS"
                                                    },
                                                    "timestamp": "2026-09-11T09:14:02+00:00"
                                                },
                                                "created_at": "2026-09-11T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 50,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/webhooks/{webhook}/deliveries/{delivery}/replay": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "v3WebhookReplay",
                "summary": "Send a delivery again",
                "description": "Queues a fresh delivery of the same payload with a new delivery id. If the endpoint was paused, this resumes it \u2014 a replay is you saying \"it is fixed, try again\".",
                "parameters": [
                    {
                        "name": "webhook",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 7
                        },
                        "description": "Webhook id."
                    },
                    {
                        "name": "delivery",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 4410
                        },
                        "description": "Delivery id, from the log."
                    }
                ],
                "responses": {
                    "202": {
                        "description": "The new delivery, queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WebhookDelivery",
                                            "description": "The new delivery."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 4411,
                                        "delivery_uid": "dlv_01j9qk4a1b2c3d4e5f6g",
                                        "event": "order.received",
                                        "status": "pending",
                                        "attempts": 0,
                                        "next_attempt_at": null,
                                        "last_attempt_at": "2026-09-11T09:14:03+00:00",
                                        "delivered_at": null,
                                        "response_code": null,
                                        "response_excerpt": null,
                                        "error": null,
                                        "replay_of_id": 4410,
                                        "payload": {
                                            "event": "order.received",
                                            "order": {
                                                "id": 9182,
                                                "catalogue_id": 42,
                                                "platform": "whatsapp",
                                                "status": "pending",
                                                "needs_attention": false,
                                                "stock_policy": "external",
                                                "customer_handle": "255712345678",
                                                "customer_name": "Asha Mrisho",
                                                "customer_phone": "255712345678",
                                                "customer_note": null,
                                                "lines": [
                                                    {
                                                        "sku": "MNG-45W",
                                                        "name": "Charger Mango 45W",
                                                        "quantity": 1,
                                                        "unit_price_minor": 3900000,
                                                        "line_total_minor": 3900000,
                                                        "currency": "TZS",
                                                        "reserved": 1,
                                                        "stock_short": false,
                                                        "unresolved": false
                                                    }
                                                ],
                                                "total_minor": 3900000,
                                                "currency": "TZS",
                                                "conversation_id": 771,
                                                "priced_at": "2026-09-11T09:14:02+00:00",
                                                "created_at": "2026-09-11T09:14:02+00:00",
                                                "order_id": 9182,
                                                "customer_wa_id": "255712345678",
                                                "total_amount": 3900000,
                                                "total_currency": "TZS"
                                            },
                                            "timestamp": "2026-09-11T09:14:02+00:00"
                                        },
                                        "created_at": "2026-09-11T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/feeds": {
            "get": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3FeedIndex",
                "summary": "List a catalogue\u2019s feeds",
                "description": "Every feed URL this shop pulls from, with when each last ran and whether it worked.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The feeds.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/CatalogueFeed"
                                                    },
                                                    "description": "The feeds."
                                                }
                                            },
                                            "description": "The feeds."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 3,
                                                "catalogue_id": 42,
                                                "url": "https://shop.example.com/google-feed.xml",
                                                "schedule": "daily",
                                                "mode": "replace",
                                                "is_active": true,
                                                "mapping": {
                                                    "retailer_id": 0,
                                                    "name": 1,
                                                    "price": 5,
                                                    "availability": 7
                                                },
                                                "last_pulled_at": "2026-09-12T02:00:41+00:00",
                                                "next_pull_at": "2026-09-13T02:00:41+00:00",
                                                "last_sync_id": 812,
                                                "last_error": null,
                                                "consecutive_failures": 0,
                                                "created_at": "2026-09-01T08:15:00+00:00",
                                                "updated_at": "2026-09-12T02:00:41+00:00"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3FeedCreate",
                "summary": "Register a feed",
                "description": "Point the shop at a product feed. It is pulled at once, and the first pull tells you whether the column mapping was guessed right \u2014 read `last_sync_id`. A feed is one-way, so the shop should be under `stock_policy: external`: the store owns the count and the feed states it.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "The feed address. Google Shopping / Meta XML, or CSV, or JSON \u2014 detected from the content."
                                    },
                                    "schedule": {
                                        "type": "string",
                                        "enum": [
                                            "hourly",
                                            "daily",
                                            "manual"
                                        ],
                                        "default": "daily",
                                        "description": "How often to pull."
                                    },
                                    "mode": {
                                        "type": "string",
                                        "enum": [
                                            "upsert",
                                            "replace"
                                        ],
                                        "default": "replace",
                                        "description": "Whether the feed is the whole catalogue."
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "description": "Switch it on or off. Turning it back on clears the failure count."
                                    },
                                    "mapping": {
                                        "type": [
                                            "object",
                                            "null"
                                        ],
                                        "additionalProperties": {
                                            "type": "integer"
                                        },
                                        "description": "Field key \u2192 column position, to override the guess."
                                    }
                                },
                                "required": [
                                    "url"
                                ]
                            },
                            "example": {
                                "url": "https://shop.example.com/google-feed.xml",
                                "schedule": "daily"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The feed, queued for its first pull.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CatalogueFeed",
                                            "description": "The feed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 3,
                                        "catalogue_id": 42,
                                        "url": "https://shop.example.com/google-feed.xml",
                                        "schedule": "daily",
                                        "mode": "replace",
                                        "is_active": true,
                                        "mapping": {
                                            "retailer_id": 0,
                                            "name": 1,
                                            "price": 5,
                                            "availability": 7
                                        },
                                        "last_pulled_at": "2026-09-12T02:00:41+00:00",
                                        "next_pull_at": "2026-09-13T02:00:41+00:00",
                                        "last_sync_id": 812,
                                        "last_error": null,
                                        "consecutive_failures": 0,
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-12T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/feeds/{feed}": {
            "patch": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3FeedUpdate",
                "summary": "Change a feed",
                "description": "Change the URL, schedule, mode or mapping, or switch it on or off. A new URL clears the mapping so it is guessed afresh.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "feed",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 3
                        },
                        "description": "Feed id."
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "format": "uri",
                                        "maxLength": 2048,
                                        "description": "The feed address. Google Shopping / Meta XML, or CSV, or JSON \u2014 detected from the content."
                                    },
                                    "schedule": {
                                        "type": "string",
                                        "enum": [
                                            "hourly",
                                            "daily",
                                            "manual"
                                        ],
                                        "default": "daily",
                                        "description": "How often to pull."
                                    },
                                    "mode": {
                                        "type": "string",
                                        "enum": [
                                            "upsert",
                                            "replace"
                                        ],
                                        "default": "replace",
                                        "description": "Whether the feed is the whole catalogue."
                                    },
                                    "is_active": {
                                        "type": "boolean",
                                        "description": "Switch it on or off. Turning it back on clears the failure count."
                                    },
                                    "mapping": {
                                        "type": [
                                            "object",
                                            "null"
                                        ],
                                        "additionalProperties": {
                                            "type": "integer"
                                        },
                                        "description": "Field key \u2192 column position, to override the guess."
                                    }
                                }
                            },
                            "example": {
                                "schedule": "hourly",
                                "is_active": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated feed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CatalogueFeed",
                                            "description": "The feed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 3,
                                        "catalogue_id": 42,
                                        "url": "https://shop.example.com/google-feed.xml",
                                        "schedule": "daily",
                                        "mode": "replace",
                                        "is_active": true,
                                        "mapping": {
                                            "retailer_id": 0,
                                            "name": 1,
                                            "price": 5,
                                            "availability": 7
                                        },
                                        "last_pulled_at": "2026-09-12T02:00:41+00:00",
                                        "next_pull_at": "2026-09-13T02:00:41+00:00",
                                        "last_sync_id": 812,
                                        "last_error": null,
                                        "consecutive_failures": 0,
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-12T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3FeedDelete",
                "summary": "Remove a feed",
                "description": "Stops pulling. Products already imported stay.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "feed",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 3
                        },
                        "description": "Feed id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Removed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true."
                                                },
                                                "id": {
                                                    "type": "integer",
                                                    "description": "The id that was removed."
                                                }
                                            },
                                            "description": "What was removed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "id": 3
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/catalogues/{catalogue}/feeds/{feed}/run": {
            "post": {
                "tags": [
                    "Catalogue"
                ],
                "operationId": "v3FeedRun",
                "summary": "Pull a feed now",
                "description": "Whatever the schedule says. Answers 202; read the outcome from the sync the feed's `last_sync_id` points at once it has run.",
                "parameters": [
                    {
                        "$ref": "#/components/parameters/CatalogueId"
                    },
                    {
                        "name": "feed",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 3
                        },
                        "description": "Feed id."
                    }
                ],
                "responses": {
                    "202": {
                        "description": "Queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "enum": [
                                                "success"
                                            ],
                                            "description": "Always \"success\"."
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/CatalogueFeed",
                                            "description": "The feed."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 3,
                                        "catalogue_id": 42,
                                        "url": "https://shop.example.com/google-feed.xml",
                                        "schedule": "daily",
                                        "mode": "replace",
                                        "is_active": true,
                                        "mapping": {
                                            "retailer_id": 0,
                                            "name": 1,
                                            "price": 5,
                                            "availability": 7
                                        },
                                        "last_pulled_at": "2026-09-12T02:00:41+00:00",
                                        "next_pull_at": "2026-09-13T02:00:41+00:00",
                                        "last_sync_id": 812,
                                        "last_error": null,
                                        "consecutive_failures": 0,
                                        "created_at": "2026-09-01T08:15:00+00:00",
                                        "updated_at": "2026-09-12T02:00:41+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flows": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowList",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "List message flows",
                "description": "The workspace's message flows as cards, newest change first. Archived flows are left out unless status=archived (or status=all) asks for them. A key issued with scopes needs flows:read.",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "draft, active, paused, archived, or all.",
                        "schema": {
                            "type": "string",
                            "example": "active"
                        }
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Part of the flow's name.",
                        "schema": {
                            "type": "string",
                            "example": "oda"
                        }
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The flows and the page.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data",
                                        "meta"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/Flow"
                                            },
                                            "description": "The flows on this page."
                                        },
                                        "meta": {
                                            "type": "object",
                                            "description": "Page numbers.",
                                            "properties": {
                                                "current_page": {
                                                    "type": "integer",
                                                    "description": "This page."
                                                },
                                                "per_page": {
                                                    "type": "integer",
                                                    "description": "Rows per page."
                                                },
                                                "total": {
                                                    "type": "integer",
                                                    "description": "Flows matching."
                                                },
                                                "last_page": {
                                                    "type": "integer",
                                                    "description": "The last page number."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": [
                                                {
                                                    "id": 17,
                                                    "name": "Oda ya chakula",
                                                    "description": "Takes a food order and collects payment.",
                                                    "status": "active",
                                                    "priority": 10,
                                                    "channels": [
                                                        "whatsapp"
                                                    ],
                                                    "version": 42,
                                                    "has_unpublished_changes": false,
                                                    "published_version": 3,
                                                    "published_at": "2026-09-12T09:14:02+03:00",
                                                    "node_count": 18,
                                                    "triggers": [
                                                        {
                                                            "type": "keyword",
                                                            "value": "oda",
                                                            "values": [
                                                                "oda",
                                                                "order"
                                                            ]
                                                        }
                                                    ],
                                                    "keywords": [
                                                        "oda",
                                                        "order"
                                                    ],
                                                    "created_at": "2026-08-30T10:00:00+03:00",
                                                    "updated_at": "2026-09-12T09:14:02+03:00"
                                                }
                                            ],
                                            "meta": {
                                                "current_page": 1,
                                                "per_page": 25,
                                                "total": 1,
                                                "last_page": 1
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "An unknown status.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Unknown status \"live\". One of: draft, active, paused, archived."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flows/{flow}": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowShow",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "Read one flow",
                "description": "One flow's card; include=definition adds the draft graph with secrets redacted. The `version` on the card is what a publish must send back as expected_version.",
                "parameters": [
                    {
                        "name": "flow",
                        "in": "path",
                        "required": true,
                        "description": "The flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    },
                    {
                        "name": "include",
                        "in": "query",
                        "required": false,
                        "description": "Comma-separated extras: definition.",
                        "schema": {
                            "type": "string",
                            "example": "definition"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The flow.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "allOf": [
                                                {
                                                    "$ref": "#/components/schemas/Flow"
                                                }
                                            ],
                                            "description": "The flow."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "id": 17,
                                                "name": "Oda ya chakula",
                                                "description": "Takes a food order and collects payment.",
                                                "status": "active",
                                                "priority": 10,
                                                "channels": [
                                                    "whatsapp"
                                                ],
                                                "version": 42,
                                                "has_unpublished_changes": false,
                                                "published_version": 3,
                                                "published_at": "2026-09-12T09:14:02+03:00",
                                                "node_count": 18,
                                                "triggers": [
                                                    {
                                                        "type": "keyword",
                                                        "value": "oda",
                                                        "values": [
                                                            "oda",
                                                            "order"
                                                        ]
                                                    }
                                                ],
                                                "keywords": [
                                                    "oda",
                                                    "order"
                                                ],
                                                "created_at": "2026-08-30T10:00:00+03:00",
                                                "updated_at": "2026-09-12T09:14:02+03:00"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flows/{flow}/publish": {
            "post": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowPublish",
                "x-permission": "flows.publish",
                "x-permission-scope": "controller",
                "summary": "Publish the draft",
                "description": "Makes the draft live for real customers, after the same validation, scenario tests and go-live readiness checks the builder runs. A draft that equals what is live answers unchanged:true and mints nothing. Needs the flows:publish scope on a scoped key.",
                "parameters": [
                    {
                        "name": "flow",
                        "in": "path",
                        "required": true,
                        "description": "The flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "expected_version"
                                ],
                                "properties": {
                                    "expected_version": {
                                        "type": "integer",
                                        "description": "The draft version you read on the flow card. A draft somebody changed since answers 409 rather than publishing a graph nobody checked."
                                    }
                                }
                            },
                            "example": {
                                "expected_version": 42
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Published, or nothing to publish.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "description": "What happened.",
                                            "properties": {
                                                "published": {
                                                    "type": "boolean",
                                                    "description": "A new version went live."
                                                },
                                                "unchanged": {
                                                    "type": "boolean",
                                                    "description": "The draft equalled the live version; nothing was minted."
                                                },
                                                "version_number": {
                                                    "type": "integer",
                                                    "nullable": true,
                                                    "description": "The version now live."
                                                },
                                                "status": {
                                                    "type": "string",
                                                    "description": "The flow's status after the publish."
                                                },
                                                "issues": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/FlowIssue"
                                                    },
                                                    "description": "Warnings that did not block."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "published": true,
                                                "unchanged": false,
                                                "version_number": 4,
                                                "status": "active",
                                                "issues": []
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The draft moved: expected_version is not the draft's version.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "The draft is at version 43, not 42. Read the flow again and publish with the version it answers."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Refused: graph errors, failed scenario tests or readiness blockers. `issues` names each.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"error\"."
                                        },
                                        "message": {
                                            "type": "string",
                                            "description": "What to do."
                                        },
                                        "issues": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/FlowIssue"
                                            },
                                            "description": "Every finding, errors and warnings."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Nothing went live. Fix the issues and publish again; a `readiness:*` issue is an account setting fixed at its fix_href.",
                                            "issues": [
                                                {
                                                    "level": "error",
                                                    "node_id": null,
                                                    "field": null,
                                                    "code": "readiness:whatsapp_channel",
                                                    "message": "No WhatsApp number is connected to this workspace, so the flow has nothing to speak from.",
                                                    "fix_href": "/app/accounts"
                                                }
                                            ]
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.publish, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.publish\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flows/{flow}/export": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowExport",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "Export a flow as a bundle",
                "description": "The flow as a marketplace bundle \u2014 the same file the builder's Export menu downloads and its Import reads. Workspace-specific references (tables, profiles, templates) come out as placeholders the importer fills.",
                "parameters": [
                    {
                        "name": "flow",
                        "in": "path",
                        "required": true,
                        "description": "The flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The bundle.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "additionalProperties": true,
                                    "description": "A flow bundle: format, version, exported_at, the artifacts (the flow and what it carries), and the workspace-specific things an import must supply under requires."
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "format": "momo.marketplace.bundle",
                                            "version": 1,
                                            "exported_at": "2026-09-12T09:14:02+03:00",
                                            "artifacts": [
                                                {
                                                    "kind": "flow",
                                                    "name": "Oda ya chakula",
                                                    "definition": {
                                                        "nodes": []
                                                    }
                                                }
                                            ],
                                            "requires": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flows/{flow}/sessions": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionList",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "List a flow's sessions",
                "description": "This flow's sessions, newest first, with the support filters. Cursor-paginated: pass meta.next_cursor as cursor for the next page. No variables ride a list row.",
                "parameters": [
                    {
                        "name": "flow",
                        "in": "path",
                        "required": true,
                        "description": "The flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    },
                    {
                        "name": "phone",
                        "in": "query",
                        "required": false,
                        "description": "The customer's phone in any shape (0712\u2026, 255712\u2026, +255712\u2026); matched exactly against the stored identifier.",
                        "schema": {
                            "type": "string",
                            "example": "255712345678"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One session status.",
                        "schema": {
                            "type": "string",
                            "example": "waiting"
                        }
                    },
                    {
                        "name": "outcome",
                        "in": "query",
                        "required": false,
                        "description": "One outcome word (in_progress, completed, abandoned, handed_over, failed, expired, cancelled, ended_by_operator).",
                        "schema": {
                            "type": "string",
                            "example": "completed"
                        }
                    },
                    {
                        "name": "node",
                        "in": "query",
                        "required": false,
                        "description": "Sessions on this step.",
                        "schema": {
                            "type": "string",
                            "example": "ask_name"
                        }
                    },
                    {
                        "name": "ended_reason",
                        "in": "query",
                        "required": false,
                        "description": "The runtime's ended reason.",
                        "schema": {
                            "type": "string",
                            "example": "timeout"
                        }
                    },
                    {
                        "name": "version",
                        "in": "query",
                        "required": false,
                        "description": "Sessions pinned to this published version id.",
                        "schema": {
                            "type": "integer",
                            "example": 91
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Started on or after this day (YYYY-MM-DD). `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself).",
                        "schema": {
                            "type": "string",
                            "example": "2026-09-01"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Started on or before this day (YYYY-MM-DD).",
                        "schema": {
                            "type": "string",
                            "example": "2026-09-12"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Rows per page, at most 100.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "description": "The next_cursor of the previous page.",
                        "schema": {
                            "type": "string",
                            "example": "eyJtZXNzYWdlX2Zsb3dfc2Vzc2lvbnMuaWQiOjUxMTksIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0"
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The sessions.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data",
                                        "meta"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/FlowSession"
                                            },
                                            "description": "The sessions, newest first."
                                        },
                                        "meta": {
                                            "type": "object",
                                            "description": "Cursor paging.",
                                            "properties": {
                                                "per_page": {
                                                    "type": "integer",
                                                    "description": "Rows per page."
                                                },
                                                "next_cursor": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "Pass as cursor for the next page; null on the last."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": [
                                                {
                                                    "id": 5120,
                                                    "flow_id": 17,
                                                    "flow_name": "Oda ya chakula",
                                                    "flow_version": 3,
                                                    "conversation_id": 771,
                                                    "contact_id": 2201,
                                                    "contact_name": "Asha Mrisho",
                                                    "contact_identifier": "255712345678",
                                                    "trigger": "inbound",
                                                    "status": "completed",
                                                    "outcome": "completed",
                                                    "ended_reason": "completed",
                                                    "node_id": "done",
                                                    "awaiting": null,
                                                    "turns": 6,
                                                    "resume_at": null,
                                                    "expires_at": null,
                                                    "started_at": "2026-09-12T09:01:12+03:00",
                                                    "ended_at": "2026-09-12T09:14:02+03:00"
                                                }
                                            ],
                                            "meta": {
                                                "per_page": 25,
                                                "next_cursor": null
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionStart",
                "x-permission": "flows.edit",
                "x-permission-scope": "controller",
                "summary": "Start a flow for a customer",
                "description": "Queues the live flow on an existing WhatsApp conversation \u2014 by the customer's phone or the conversation id \u2014 with optional starting variables. Answers 202: the session appears once the runner takes its first step, so read the sessions list or subscribe to the flow.session.started webhook. A thread a person has silenced is respected. Needs flows:write on a scoped key.",
                "parameters": [
                    {
                        "name": "flow",
                        "in": "path",
                        "required": true,
                        "description": "The flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "phone": {
                                        "type": "string",
                                        "description": "The customer's WhatsApp number in any shape. Required unless conversation_id is given."
                                    },
                                    "conversation_id": {
                                        "type": "integer",
                                        "description": "The inbox conversation to start on. Required unless phone is given."
                                    },
                                    "variables": {
                                        "type": "object",
                                        "additionalProperties": true,
                                        "description": "Up to 32 starting variables (strings, numbers, booleans), readable in the flow as {{name}}. Names are letters, digits and underscores."
                                    }
                                }
                            },
                            "example": {
                                "phone": "255712345678",
                                "variables": {
                                    "order_ref": "ORD-2026-0091"
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "Queued.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "description": "The start, queued.",
                                            "properties": {
                                                "queued": {
                                                    "type": "boolean",
                                                    "description": "Always true."
                                                },
                                                "flow_id": {
                                                    "type": "integer",
                                                    "description": "The flow."
                                                },
                                                "conversation_id": {
                                                    "type": "integer",
                                                    "description": "The conversation it starts on."
                                                },
                                                "contact_identifier": {
                                                    "type": "string",
                                                    "description": "The customer's stored identifier."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "queued": true,
                                                "flow_id": 17,
                                                "conversation_id": 771,
                                                "contact_identifier": "255712345678"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The flow is not live, no conversation with that customer exists, or a variable is not allowed.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This flow is not live: publish it (and resume it if paused) before starting it for a customer."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.edit, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.edit\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flow-sessions": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionFind",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "Find sessions by customer",
                "description": "Sessions across every flow, found by the customer's phone (or narrowed to one flow with `flow`). The same filters and cursor as a flow's session list.",
                "parameters": [
                    {
                        "name": "phone",
                        "in": "query",
                        "required": false,
                        "description": "The customer's phone in any shape (0712\u2026, 255712\u2026, +255712\u2026); matched exactly against the stored identifier.",
                        "schema": {
                            "type": "string",
                            "example": "255712345678"
                        }
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "One session status.",
                        "schema": {
                            "type": "string",
                            "example": "waiting"
                        }
                    },
                    {
                        "name": "outcome",
                        "in": "query",
                        "required": false,
                        "description": "One outcome word (in_progress, completed, abandoned, handed_over, failed, expired, cancelled, ended_by_operator).",
                        "schema": {
                            "type": "string",
                            "example": "completed"
                        }
                    },
                    {
                        "name": "node",
                        "in": "query",
                        "required": false,
                        "description": "Sessions on this step.",
                        "schema": {
                            "type": "string",
                            "example": "ask_name"
                        }
                    },
                    {
                        "name": "ended_reason",
                        "in": "query",
                        "required": false,
                        "description": "The runtime's ended reason.",
                        "schema": {
                            "type": "string",
                            "example": "timeout"
                        }
                    },
                    {
                        "name": "version",
                        "in": "query",
                        "required": false,
                        "description": "Sessions pinned to this published version id.",
                        "schema": {
                            "type": "integer",
                            "example": 91
                        }
                    },
                    {
                        "name": "from",
                        "in": "query",
                        "required": false,
                        "description": "Started on or after this day (YYYY-MM-DD). `GET /api/v3/whatsapp/accounts` lists the accounts and their numbers (`phone_numbers[].id`, or the number itself).",
                        "schema": {
                            "type": "string",
                            "example": "2026-09-01"
                        }
                    },
                    {
                        "name": "to",
                        "in": "query",
                        "required": false,
                        "description": "Started on or before this day (YYYY-MM-DD).",
                        "schema": {
                            "type": "string",
                            "example": "2026-09-12"
                        }
                    },
                    {
                        "name": "limit",
                        "in": "query",
                        "required": false,
                        "description": "Rows per page, at most 100.",
                        "schema": {
                            "type": "integer",
                            "default": 25
                        }
                    },
                    {
                        "name": "cursor",
                        "in": "query",
                        "required": false,
                        "description": "The next_cursor of the previous page.",
                        "schema": {
                            "type": "string",
                            "example": "eyJtZXNzYWdlX2Zsb3dfc2Vzc2lvbnMuaWQiOjUxMTksIl9wb2ludHNUb05leHRJdGVtcyI6dHJ1ZX0"
                        }
                    },
                    {
                        "name": "flow",
                        "in": "query",
                        "required": false,
                        "description": "Narrow to one flow id.",
                        "schema": {
                            "type": "integer",
                            "example": 17
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The sessions.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data",
                                        "meta"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/FlowSession"
                                            },
                                            "description": "The sessions, newest first."
                                        },
                                        "meta": {
                                            "type": "object",
                                            "description": "Cursor paging.",
                                            "properties": {
                                                "per_page": {
                                                    "type": "integer",
                                                    "description": "Rows per page."
                                                },
                                                "next_cursor": {
                                                    "type": "string",
                                                    "nullable": true,
                                                    "description": "Pass as cursor for the next page; null on the last."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": [
                                                {
                                                    "id": 5120,
                                                    "flow_id": 17,
                                                    "flow_name": "Oda ya chakula",
                                                    "flow_version": 3,
                                                    "conversation_id": 771,
                                                    "contact_id": 2201,
                                                    "contact_name": "Asha Mrisho",
                                                    "contact_identifier": "255712345678",
                                                    "trigger": "inbound",
                                                    "status": "completed",
                                                    "outcome": "completed",
                                                    "ended_reason": "completed",
                                                    "node_id": "done",
                                                    "awaiting": null,
                                                    "turns": 6,
                                                    "resume_at": null,
                                                    "expires_at": null,
                                                    "started_at": "2026-09-12T09:01:12+03:00",
                                                    "ended_at": "2026-09-12T09:14:02+03:00"
                                                }
                                            ],
                                            "meta": {
                                                "per_page": 25,
                                                "next_cursor": null
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "Neither a phone nor a flow was given.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Give a `phone` to find a customer's sessions, or a `flow` id."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flow-sessions/{session}": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionShow",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "Read one session and its trace",
                "description": "The session card and its step-by-step trace, redacted. `variables` is the session's variable bag ONLY for a key whose issuer holds flows.sessions.pii (the same line the app draws), and that read is written to the audit log; otherwise it is null.",
                "parameters": [
                    {
                        "name": "session",
                        "in": "path",
                        "required": true,
                        "description": "The session id.",
                        "schema": {
                            "type": "integer",
                            "example": 5120
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The session, its trace and \u2014 when permitted \u2014 its variables.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "description": "The session in full.",
                                            "properties": {
                                                "session": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/FlowSession"
                                                        }
                                                    ],
                                                    "description": "The session card."
                                                },
                                                "steps": {
                                                    "type": "array",
                                                    "items": {
                                                        "$ref": "#/components/schemas/FlowSessionStep"
                                                    },
                                                    "description": "The trace, oldest first, at most 1000 rows."
                                                },
                                                "variables": {
                                                    "type": "object",
                                                    "additionalProperties": true,
                                                    "nullable": true,
                                                    "description": "The variable bag, redacted, or null when the key may not read it."
                                                },
                                                "exported_at": {
                                                    "type": "string",
                                                    "format": "date-time",
                                                    "description": "When this read happened."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "session": {
                                                    "id": 5120,
                                                    "flow_id": 17,
                                                    "flow_name": "Oda ya chakula",
                                                    "flow_version": 3,
                                                    "conversation_id": 771,
                                                    "contact_id": 2201,
                                                    "contact_name": "Asha Mrisho",
                                                    "contact_identifier": "255712345678",
                                                    "trigger": "inbound",
                                                    "status": "completed",
                                                    "outcome": "completed",
                                                    "ended_reason": "completed",
                                                    "node_id": "done",
                                                    "awaiting": null,
                                                    "turns": 6,
                                                    "resume_at": null,
                                                    "expires_at": null,
                                                    "started_at": "2026-09-12T09:01:12+03:00",
                                                    "ended_at": "2026-09-12T09:14:02+03:00"
                                                },
                                                "steps": [
                                                    {
                                                        "seq": 3,
                                                        "node_id": "ask_name",
                                                        "node_kind": "ask_text",
                                                        "kind": "awaited",
                                                        "payload": {
                                                            "kind": "text"
                                                        },
                                                        "duration_ms": 12,
                                                        "at": "2026-09-12T09:14:02+03:00"
                                                    }
                                                ],
                                                "variables": null,
                                                "exported_at": "2026-09-12T09:14:02+03:00"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flow-sessions/{session}/export": {
            "get": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionExport",
                "x-permission": "flows.view",
                "x-permission-scope": "controller",
                "summary": "Download a session's trace as CSV",
                "description": "One row per step: seq, at, node_id, node_kind, kind, detail (JSON), duration_ms. Never carries variables.",
                "parameters": [
                    {
                        "name": "session",
                        "in": "path",
                        "required": true,
                        "description": "The session id.",
                        "schema": {
                            "type": "integer",
                            "example": 5120
                        }
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The CSV.",
                        "content": {
                            "text/csv": {
                                "schema": {
                                    "type": "string",
                                    "description": "CSV text."
                                },
                                "example": "seq,at,node_id,node_kind,kind,detail,duration_ms\n1,2026-09-12T09:01:12+03:00,hi,send_text,entered,{},3\n"
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.view, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.view\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/flow-sessions/{session}/end": {
            "post": {
                "tags": [
                    "Flows"
                ],
                "operationId": "v3FlowSessionEnd",
                "x-permission": "flows.edit",
                "x-permission-scope": "controller",
                "summary": "End a live session",
                "description": "Ends a running or waiting session as an operator would; the conversation goes back to the inbox. notify_customer sends the customer one line saying a person will continue. A session already over answers 409. Needs flows:write on a scoped key.",
                "parameters": [
                    {
                        "name": "session",
                        "in": "path",
                        "required": true,
                        "description": "The session id.",
                        "schema": {
                            "type": "integer",
                            "example": 5120
                        }
                    }
                ],
                "requestBody": {
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "notify_customer": {
                                        "type": "boolean",
                                        "description": "Tell the customer a person will continue. Default false."
                                    }
                                }
                            },
                            "example": {
                                "notify_customer": true
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Ended.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "data"
                                    ],
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "description": "The result.",
                                            "properties": {
                                                "ended": {
                                                    "type": "boolean",
                                                    "description": "True: it was live and is now cancelled."
                                                },
                                                "message": {
                                                    "type": "string",
                                                    "description": "One sentence."
                                                },
                                                "session": {
                                                    "allOf": [
                                                        {
                                                            "$ref": "#/components/schemas/FlowSession"
                                                        }
                                                    ],
                                                    "description": "The session after the end."
                                                }
                                            }
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "ended": true,
                                                "message": "The session was ended.",
                                                "session": {
                                                    "status": "cancelled",
                                                    "outcome": "ended_by_operator",
                                                    "id": 5120,
                                                    "flow_id": 17,
                                                    "flow_name": "Oda ya chakula",
                                                    "flow_version": 3,
                                                    "conversation_id": 771,
                                                    "contact_id": 2201,
                                                    "contact_name": "Asha Mrisho",
                                                    "contact_identifier": "255712345678",
                                                    "trigger": "inbound",
                                                    "ended_reason": "completed",
                                                    "node_id": "done",
                                                    "awaiting": null,
                                                    "turns": 6,
                                                    "resume_at": null,
                                                    "expires_at": null,
                                                    "started_at": "2026-09-12T09:01:12+03:00",
                                                    "ended_at": "2026-09-12T09:14:02+03:00"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No such flow or session in this workspace. Another workspace's answers 404, never 403.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "Resource not found."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The session had already ended.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "data": {
                                            "type": "object",
                                            "additionalProperties": true,
                                            "description": "The same shape as 200 with ended:false."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "data": {
                                                "ended": false,
                                                "message": "That session had already ended.",
                                                "session": {
                                                    "id": 5120,
                                                    "flow_id": 17,
                                                    "flow_name": "Oda ya chakula",
                                                    "flow_version": 3,
                                                    "conversation_id": 771,
                                                    "contact_id": 2201,
                                                    "contact_name": "Asha Mrisho",
                                                    "contact_identifier": "255712345678",
                                                    "trigger": "inbound",
                                                    "status": "completed",
                                                    "outcome": "completed",
                                                    "ended_reason": "completed",
                                                    "node_id": "done",
                                                    "awaiting": null,
                                                    "turns": 6,
                                                    "resume_at": null,
                                                    "expires_at": null,
                                                    "started_at": "2026-09-12T09:01:12+03:00",
                                                    "ended_at": "2026-09-12T09:14:02+03:00"
                                                }
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "description": "The key's issuer does not hold flows.edit, the key has no issuer on record, or the key was issued without the scope this call needs.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "status": "error",
                                            "message": "This API key was issued by a user without the \"flows.edit\" permission."
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates": {
            "get": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateList",
                "summary": "List templates",
                "description": "WhatsApp templates in this workspace, newest first, with their Meta review status. Archived rows are left out unless `status=archived` or `status=all`. `updated_since` makes an incremental mirror cheap: it returns rows whose local record changed after that time, which includes every status move.",
                "x-permission": "communications.templates.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "waba_id",
                        "in": "query",
                        "required": false,
                        "description": "Only templates on this WhatsApp Business Account. `GET /api/v3/whatsapp/accounts` lists them (`waba_id`).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "102290129340398"
                    },
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Local state. Omit for everything but archived; `all` includes archived.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "active",
                                "archived",
                                "all"
                            ]
                        },
                        "example": "active"
                    },
                    {
                        "name": "whatsapp_status",
                        "in": "query",
                        "required": false,
                        "description": "Meta's review status.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "pending",
                                "in_review",
                                "approved",
                                "rejected",
                                "disabled",
                                "paused"
                            ]
                        },
                        "example": "approved"
                    },
                    {
                        "name": "category",
                        "in": "query",
                        "required": false,
                        "description": "Meta category.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "marketing",
                                "utility",
                                "authentication"
                            ]
                        },
                        "example": "utility"
                    },
                    {
                        "name": "language",
                        "in": "query",
                        "required": false,
                        "description": "Language code, exact.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "sw"
                    },
                    {
                        "name": "name",
                        "in": "query",
                        "required": false,
                        "description": "Template name, exact \u2014 every language of it.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "order_shipped"
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Free text over name, display name and body.",
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "example": "oda"
                    },
                    {
                        "name": "updated_since",
                        "in": "query",
                        "required": false,
                        "description": "Only rows changed at or after this ISO-8601 time.",
                        "schema": {
                            "type": "string",
                            "format": "date-time"
                        },
                        "example": "2026-09-12T00:00:00Z"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of templates.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "The page of templates.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WhatsAppTemplateSummary"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "A page of templates."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 418,
                                                "name": "order_shipped",
                                                "display_name": "Order shipped",
                                                "language": "sw",
                                                "category": "utility",
                                                "status": "active",
                                                "whatsapp_status": "in_review",
                                                "approved": false,
                                                "sendable": false,
                                                "rejection_reason": null,
                                                "whatsapp_business_account_id": "102290129340398",
                                                "whatsapp_template_id": "1189456212345678",
                                                "quality_rating": null,
                                                "parameter_format": "POSITIONAL",
                                                "variables": [
                                                    "1",
                                                    "2"
                                                ],
                                                "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "last_synced_at": "2026-09-13T09:14:02+00:00",
                                                "created_at": "2026-09-13T09:14:02+00:00",
                                                "updated_at": "2026-09-13T09:14:02+00:00"
                                            },
                                            {
                                                "id": 417,
                                                "name": "karibu",
                                                "display_name": "Order shipped",
                                                "language": "en",
                                                "category": "marketing",
                                                "status": "active",
                                                "whatsapp_status": "approved",
                                                "approved": true,
                                                "sendable": true,
                                                "rejection_reason": null,
                                                "whatsapp_business_account_id": "102290129340398",
                                                "whatsapp_template_id": "1189456200000417",
                                                "quality_rating": "GREEN",
                                                "parameter_format": "POSITIONAL",
                                                "variables": [
                                                    "1"
                                                ],
                                                "body": "Welcome to Amina, {{1}}!",
                                                "last_synced_at": "2026-09-13T09:14:02+00:00",
                                                "created_at": "2026-09-13T09:14:02+00:00",
                                                "updated_at": "2026-09-13T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 2,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateCreate",
                "summary": "Create a template and submit it for review",
                "description": "Creates the template on the chosen WhatsApp Business Account and \u2014 unless `submit` is false \u2014 submits it to Meta for review inside this request. The answer is always 201 with the template; read `whatsapp_status` for Meta's verdict: `in_review` (or `approved` outright) with a `whatsapp_template_id`, or `rejected` with Meta's own words in `rejection_reason` (a bad body, a name it will not take, a token without the permission). Only when Meta cannot be reached is the submission queued to retry; `submission.queued` says so and the row stays `pending`.\n\nDescribe the content either way: `components` in WhatsApp's own shape (everything Meta supports \u2014 media headers, carousels, limited-time offers, copy-code and flow buttons, named parameters), or the flat fields `body`, `header_text`, `footer`, `buttons`, `variable_samples` for the common case. Meta needs a sample value for every placeholder; with the flat fields, supply them in `variable_samples`.\n\nA name is one template per language: `order_shipped` in `sw` and in `en` are two rows, each reviewed on its own. The same name and language again answers 409.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "requestBody": {
                    "description": "The template.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WhatsAppTemplateWriteRequest"
                            },
                            "examples": {
                                "flat": {
                                    "summary": "Flat fields \u2014 the common case",
                                    "value": {
                                        "name": "order_shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "display_name": "Order shipped",
                                        "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "variable_samples": {
                                            "1": "Asha",
                                            "2": "ORD-1042"
                                        }
                                    }
                                },
                                "components": {
                                    "summary": "WhatsApp's own components \u2014 every feature",
                                    "value": {
                                        "name": "ofa_ijumaa",
                                        "language": "sw",
                                        "category": "marketing",
                                        "waba_id": "102290129340398",
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "IMAGE",
                                                "example": {
                                                    "header_handle": [
                                                        "4::aW1hZ2UvcG5n:ARZ\u2026"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Ofa ya {{1}}: punguzo la {{2}} hadi {{3}}.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Ijumaa",
                                                            "20%",
                                                            "30 Sept"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Jibu STOP kuacha"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "QUICK_REPLY",
                                                        "text": "Nataka"
                                                    },
                                                    {
                                                        "type": "COPY_CODE",
                                                        "example": "OFA20"
                                                    }
                                                ]
                                            }
                                        ]
                                    }
                                },
                                "draft": {
                                    "summary": "Save without submitting",
                                    "value": {
                                        "name": "karibu",
                                        "language": "en",
                                        "category": "marketing",
                                        "body": "Welcome to Amina, {{1}}!",
                                        "variable_samples": {
                                            "1": "Asha"
                                        },
                                        "submit": false
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The template as saved, with Meta's answer in `whatsapp_status` and `submission`.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppTemplate",
                                            "description": "The template as saved, with Meta's answer in `whatsapp_status` and `submission`."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "name": "order_shipped",
                                        "display_name": "Order shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "status": "active",
                                        "whatsapp_status": "in_review",
                                        "approved": false,
                                        "sendable": false,
                                        "rejection_reason": null,
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "quality_rating": null,
                                        "parameter_format": "POSITIONAL",
                                        "variables": [
                                            "1",
                                            "2"
                                        ],
                                        "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                        "last_synced_at": "2026-09-13T09:14:02+00:00",
                                        "created_at": "2026-09-13T09:14:02+00:00",
                                        "updated_at": "2026-09-13T09:14:02+00:00",
                                        "header_type": "text",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "TEXT",
                                                "text": "Oda {{1}}",
                                                "example": {
                                                    "header_text": [
                                                        "ORD-1042"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Asha",
                                                            "ORD-1042"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Duka la Amina"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "URL",
                                                        "text": "Fuatilia",
                                                        "url": "https://amina.co.tz/track/{{1}}",
                                                        "example": [
                                                            "ORD-1042"
                                                        ]
                                                    }
                                                ]
                                            }
                                        ],
                                        "deployments": [],
                                        "submission": {
                                            "submitted": true,
                                            "queued": false,
                                            "message": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Refused because of the workspace's current state; the message says what to do.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "No WhatsApp business account is connected to this workspace, so there is nothing to submit a template to. Connect one under Settings \u2192 WhatsApp first."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates/sync": {
            "post": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateSync",
                "summary": "Pull templates from WhatsApp",
                "description": "Makes this workspace a mirror of what Meta has: every APPROVED template on the account(s) that is not here yet is imported as a local row (name, language, category and full components), ones already here are refreshed from Meta's copy, and the review status of every template already submitted is re-read. Templates still in review on Meta's side that were not submitted through this platform appear once approved. Runs inside the request against Meta's paginated list, so on an account with hundreds of templates allow a few seconds. Omit `waba_id` to do every account.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "requestBody": {
                    "description": "Which account to pull from; omit for all.",
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "properties": {
                                    "waba_id": {
                                        "type": [
                                            "string",
                                            "null"
                                        ],
                                        "description": "One WhatsApp Business Account, or omit for every connected account. `GET /api/v3/whatsapp/accounts` lists them (`waba_id`)."
                                    }
                                }
                            },
                            "example": {
                                "waba_id": "102290129340398"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "What the pull did.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "imported": {
                                                    "type": "integer",
                                                    "description": "Approved templates that were new here and are now rows."
                                                },
                                                "updated": {
                                                    "type": "integer",
                                                    "description": "Approved templates already here whose content was refreshed from Meta."
                                                },
                                                "statuses_updated": {
                                                    "type": "integer",
                                                    "description": "Rows whose review status changed as a result."
                                                },
                                                "errors": {
                                                    "type": "array",
                                                    "description": "Per-template problems, when any \u2014 the rest of the pull still happened.",
                                                    "items": {
                                                        "type": "string",
                                                        "description": "One problem."
                                                    }
                                                }
                                            },
                                            "description": "What the pull did."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "imported": 3,
                                        "updated": 9,
                                        "statuses_updated": 1,
                                        "errors": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates/{template}": {
            "get": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateShow",
                "summary": "Read a template",
                "description": "One template in full: the summary fields, its content in both the flat fields and Meta's `components` shape, and its review status on every account it has been deployed to. `components` is exactly what was (or would be) submitted to Meta \u2014 post it back to create a twin, or edit and PATCH it.",
                "x-permission": "communications.templates.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The template.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppTemplate",
                                            "description": "The template."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "name": "order_shipped",
                                        "display_name": "Order shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "status": "active",
                                        "whatsapp_status": "in_review",
                                        "approved": false,
                                        "sendable": false,
                                        "rejection_reason": null,
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "quality_rating": null,
                                        "parameter_format": "POSITIONAL",
                                        "variables": [
                                            "1",
                                            "2"
                                        ],
                                        "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                        "last_synced_at": "2026-09-13T09:14:02+00:00",
                                        "created_at": "2026-09-13T09:14:02+00:00",
                                        "updated_at": "2026-09-13T09:14:02+00:00",
                                        "header_type": "text",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "TEXT",
                                                "text": "Oda {{1}}",
                                                "example": {
                                                    "header_text": [
                                                        "ORD-1042"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Asha",
                                                            "ORD-1042"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Duka la Amina"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "URL",
                                                        "text": "Fuatilia",
                                                        "url": "https://amina.co.tz/track/{{1}}",
                                                        "example": [
                                                            "ORD-1042"
                                                        ]
                                                    }
                                                ]
                                            }
                                        ],
                                        "deployments": []
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateUpdate",
                "summary": "Change a template",
                "description": "Any subset of the create fields. Changing content \u2014 `body`, `header_text`, `footer`, `buttons`, `components` or `category` \u2014 re-submits to Meta as an EDIT of the template it already holds (Meta then puts it back in review); changing only `display_name` or `status` does not touch Meta. `submit: false` saves a content change without re-submitting. A template in review cannot be edited on Meta's side, so the change is saved here and submitted the next time you call `\u2026/submit` once the review is over.\n\n`name`, `language` and `waba_id` cannot change: Meta knows the template by those. A template described by `components` (or imported from WhatsApp) may hold parts the flat fields cannot express, so to change part of it send the edited `components`; a flat `body` re-describes the whole content.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    }
                ],
                "requestBody": {
                    "description": "The fields to change.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WhatsAppTemplateWriteRequest"
                            },
                            "examples": {
                                "copy": {
                                    "summary": "New body copy \u2014 re-submits",
                                    "value": {
                                        "body": "Habari {{1}}, oda yako {{2}} iko njiani.",
                                        "variable_samples": {
                                            "1": "Asha",
                                            "2": "ORD-1042"
                                        }
                                    }
                                },
                                "archive": {
                                    "summary": "Hide it \u2014 no submission",
                                    "value": {
                                        "status": "archived"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The template as saved, with `submission` when a content change was submitted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppTemplate",
                                            "description": "The template as saved, with `submission` when a content change was submitted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "name": "order_shipped",
                                        "display_name": "Order shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "status": "active",
                                        "whatsapp_status": "in_review",
                                        "approved": false,
                                        "sendable": false,
                                        "rejection_reason": null,
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "quality_rating": null,
                                        "parameter_format": "POSITIONAL",
                                        "variables": [
                                            "1",
                                            "2"
                                        ],
                                        "body": "Habari {{1}}, oda yako {{2}} iko njiani.",
                                        "last_synced_at": "2026-09-13T09:14:02+00:00",
                                        "created_at": "2026-09-13T09:14:02+00:00",
                                        "updated_at": "2026-09-13T09:14:02+00:00",
                                        "header_type": "text",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "TEXT",
                                                "text": "Oda {{1}}",
                                                "example": {
                                                    "header_text": [
                                                        "ORD-1042"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Asha",
                                                            "ORD-1042"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Duka la Amina"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "URL",
                                                        "text": "Fuatilia",
                                                        "url": "https://amina.co.tz/track/{{1}}",
                                                        "example": [
                                                            "ORD-1042"
                                                        ]
                                                    }
                                                ]
                                            }
                                        ],
                                        "deployments": [],
                                        "submission": {
                                            "submitted": true,
                                            "queued": false,
                                            "message": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateDelete",
                "summary": "Delete a template",
                "description": "Removes THIS language of the template from the WhatsApp Business Account (Meta keeps other languages of the same name) and archives the row here, so campaign history that pointed at it still reads. `permanent=true` deletes the row as well. A template never submitted has nothing to remove from Meta, and `removed_from_whatsapp` is false.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    },
                    {
                        "name": "permanent",
                        "in": "query",
                        "required": false,
                        "description": "Delete the local row too, not just archive it.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        },
                        "example": false
                    }
                ],
                "responses": {
                    "200": {
                        "description": "What was done.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "description": "The template id."
                                                },
                                                "archived": {
                                                    "type": "boolean",
                                                    "description": "True when the row was archived (the default)."
                                                },
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "True when the row was deleted (`permanent=true`)."
                                                },
                                                "removed_from_whatsapp": {
                                                    "type": "boolean",
                                                    "description": "True when Meta confirmed the removal of this language from the account."
                                                }
                                            },
                                            "description": "What was done."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "archived": true,
                                        "deleted": false,
                                        "removed_from_whatsapp": true
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates/{template}/submit": {
            "post": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateSubmit",
                "summary": "Submit to Meta for review",
                "description": "Submits (or re-submits) the template to Meta now, inside the request, and answers with the template as Meta left it. Use it after fixing a `rejected` template, or for one created with `submit: false`. A template Meta already holds is edited rather than created again; one Meta is still reviewing is left alone and its current status recorded. Meta allows an approved template about ten edits a month.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The template, with `submission` saying what happened.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppTemplate",
                                            "description": "The template, with `submission` saying what happened."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "name": "order_shipped",
                                        "display_name": "Order shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "status": "active",
                                        "whatsapp_status": "in_review",
                                        "approved": false,
                                        "sendable": false,
                                        "rejection_reason": null,
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "quality_rating": null,
                                        "parameter_format": "POSITIONAL",
                                        "variables": [
                                            "1",
                                            "2"
                                        ],
                                        "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                        "last_synced_at": "2026-09-13T09:14:02+00:00",
                                        "created_at": "2026-09-13T09:14:02+00:00",
                                        "updated_at": "2026-09-13T09:14:02+00:00",
                                        "header_type": "text",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "TEXT",
                                                "text": "Oda {{1}}",
                                                "example": {
                                                    "header_text": [
                                                        "ORD-1042"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Asha",
                                                            "ORD-1042"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Duka la Amina"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "URL",
                                                        "text": "Fuatilia",
                                                        "url": "https://amina.co.tz/track/{{1}}",
                                                        "example": [
                                                            "ORD-1042"
                                                        ]
                                                    }
                                                ]
                                            }
                                        ],
                                        "deployments": [],
                                        "submission": {
                                            "submitted": true,
                                            "queued": false,
                                            "message": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates/{template}/refresh": {
            "post": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateRefresh",
                "summary": "Ask Meta for the current status",
                "description": "Reads the template from Meta right now \u2014 review status, rejection reason, quality score \u2014 and writes it on the row. The background poll and Meta's status webhook keep rows current on their own; this is for the moment you need the answer, such as right after `\u2026/submit`. By Meta id when the row has one, by name and language otherwise. `refresh.found_on_whatsapp` is false when Meta has no such template on the account, and the row is left as it was.",
                "x-permission": "communications.templates.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The template as Meta reports it.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/WhatsAppTemplate",
                                            "description": "The template as Meta reports it."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 418,
                                        "name": "order_shipped",
                                        "display_name": "Order shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "status": "active",
                                        "whatsapp_status": "approved",
                                        "approved": true,
                                        "sendable": true,
                                        "rejection_reason": null,
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "quality_rating": "GREEN",
                                        "parameter_format": "POSITIONAL",
                                        "variables": [
                                            "1",
                                            "2"
                                        ],
                                        "body": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                        "last_synced_at": "2026-09-13T09:14:02+00:00",
                                        "created_at": "2026-09-13T09:14:02+00:00",
                                        "updated_at": "2026-09-13T09:14:02+00:00",
                                        "header_type": "text",
                                        "header_text": "Oda {{1}}",
                                        "footer": "Duka la Amina",
                                        "buttons": [
                                            {
                                                "type": "url",
                                                "text": "Fuatilia",
                                                "url": "https://amina.co.tz/track/{{1}}",
                                                "example": "ORD-1042"
                                            }
                                        ],
                                        "components": [
                                            {
                                                "type": "HEADER",
                                                "format": "TEXT",
                                                "text": "Oda {{1}}",
                                                "example": {
                                                    "header_text": [
                                                        "ORD-1042"
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "BODY",
                                                "text": "Habari {{1}}, oda yako {{2}} imetumwa leo.",
                                                "example": {
                                                    "body_text": [
                                                        [
                                                            "Asha",
                                                            "ORD-1042"
                                                        ]
                                                    ]
                                                }
                                            },
                                            {
                                                "type": "FOOTER",
                                                "text": "Duka la Amina"
                                            },
                                            {
                                                "type": "BUTTONS",
                                                "buttons": [
                                                    {
                                                        "type": "URL",
                                                        "text": "Fuatilia",
                                                        "url": "https://amina.co.tz/track/{{1}}",
                                                        "example": [
                                                            "ORD-1042"
                                                        ]
                                                    }
                                                ]
                                            }
                                        ],
                                        "deployments": [],
                                        "refresh": {
                                            "found_on_whatsapp": true,
                                            "message": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Refused because of the workspace's current state; the message says what to do.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "No WhatsApp business account is connected for this template."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    },
                    "502": {
                        "$ref": "#/components/responses/UpstreamFailure"
                    }
                }
            }
        },
        "/api/v3/whatsapp/templates/{template}/deployments": {
            "post": {
                "tags": [
                    "WhatsApp templates"
                ],
                "operationId": "v3WhatsAppTemplateDeploy",
                "summary": "Deploy to more business accounts",
                "description": "Puts an authored template on other WhatsApp Business Accounts of this workspace. Each account reviews it independently, so each gets its own deployment with its own Meta id and status \u2014 reported on the template's `deployments` and announced by `template.status_changed` with that account's id. Submission to each account is queued (202); read the template, or subscribe to the webhook, for the outcome. Deploying to an account it is already on re-submits it there.",
                "x-permission": "communications.templates.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "template",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "integer",
                            "example": 418
                        },
                        "description": "Local template id, from the list or the create response."
                    }
                ],
                "requestBody": {
                    "description": "The accounts to deploy to.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "waba_ids"
                                ],
                                "properties": {
                                    "waba_ids": {
                                        "type": "array",
                                        "description": "WhatsApp Business Account ids from `GET /api/v3/whatsapp/accounts`. One to twenty. `GET /api/v3/whatsapp/accounts` lists them (`waba_id`).",
                                        "items": {
                                            "type": "string",
                                            "description": "A WABA id."
                                        },
                                        "minItems": 1,
                                        "maxItems": 20
                                    }
                                }
                            },
                            "example": {
                                "waba_ids": [
                                    "102290129340777"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "202": {
                        "description": "The deployments, queued for submission.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "template_id": {
                                                    "type": "integer",
                                                    "description": "The template."
                                                },
                                                "deployments": {
                                                    "type": "array",
                                                    "description": "One per account, each now `pending` until its submission lands.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WhatsAppTemplateDeployment"
                                                    }
                                                }
                                            },
                                            "description": "The deployments, queued for submission."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "template_id": 418,
                                        "deployments": [
                                            {
                                                "id": 91,
                                                "whatsapp_business_account_id": "102290129340777",
                                                "whatsapp_template_id": null,
                                                "whatsapp_status": "pending",
                                                "rejection_reason": null,
                                                "quality_rating": null,
                                                "category": null,
                                                "last_synced_at": null
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/whatsapp/accounts": {
            "get": {
                "tags": [
                    "WhatsApp"
                ],
                "operationId": "v3WhatsAppAccounts",
                "summary": "List the WhatsApp business accounts and their numbers",
                "description": "Where the identifiers come from. Every WhatsApp Business Account connected to this workspace with its phone numbers: `phone_numbers[].id` is the value `sender_id` takes on `/whatsapp/send` and the group endpoints and `from` takes on the catalogue sends and flow sessions (the number itself is accepted there too); `waba_id` is what the templates endpoints take. `default_phone_number_id` \u2014 and the `is_default` flags \u2014 say what a send without `sender_id` goes out from; null means there is no usable default and every send must name one. Readable by a key whose issuer may read the workspace's accounts or holds any permission that uses these ids. Credentials are never included.",
                "x-permission": "communications.accounts.view (or any permission that uses these ids)",
                "x-permission-scope": "controller",
                "responses": {
                    "200": {
                        "description": "The connected accounts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "default_phone_number_id": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "The phone_number_id a send without `sender_id` goes out from; null when no default is configured."
                                                },
                                                "items": {
                                                    "type": "array",
                                                    "description": "The accounts, active first.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/WhatsAppAccount"
                                                    }
                                                }
                                            },
                                            "description": "The connected accounts."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "default_phone_number_id": "104512345678901",
                                        "items": [
                                            {
                                                "waba_id": "102290129340398",
                                                "name": "Duka la Amina",
                                                "is_active": true,
                                                "is_default": true,
                                                "phone_numbers": [
                                                    {
                                                        "id": "104512345678901",
                                                        "phone_number": "+255700000001",
                                                        "display": "+255 700 000 001",
                                                        "is_default": true
                                                    }
                                                ],
                                                "quality_rating": "GREEN",
                                                "messaging_tier": "TIER_1K",
                                                "templates_count": 12,
                                                "catalogues_count": 1,
                                                "last_synced_at": "2026-09-13T09:14:02+00:00"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/sms/senders": {
            "get": {
                "tags": [
                    "SMS"
                ],
                "operationId": "v3SmsSenders",
                "summary": "List the identities an SMS can be sent as",
                "description": "Where `sender_id` comes from. Every identity this workspace may send SMS as \u2014 approved alphanumeric sender IDs, its own SMS-capable phone numbers, and its active short codes \u2014 with `value` being exactly what `sender_id` takes on `/sms/send` and `/sms/campaign`. Only usable identities are listed (a sender ID still under review is not). Readable by a key whose issuer may read the workspace's accounts or holds any permission that uses these ids.",
                "x-permission": "communications.accounts.view (or any permission that uses these ids)",
                "x-permission-scope": "controller",
                "responses": {
                    "200": {
                        "description": "The sending identities.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "The identities, sender IDs first, then numbers, then short codes.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/SmsSender"
                                                    }
                                                }
                                            },
                                            "description": "The sending identities."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "type": "sender_id",
                                                "value": "AMINA",
                                                "label": "AMINA",
                                                "status": "approved"
                                            },
                                            {
                                                "type": "phone_number",
                                                "value": "+255700000001",
                                                "label": "Main line",
                                                "status": "active"
                                            },
                                            {
                                                "type": "short_code",
                                                "value": "15551",
                                                "label": "Promotions",
                                                "status": "active"
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contact-groups": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupList",
                "summary": "List contact groups",
                "description": "Where `{group_id}` comes from. Every contact path takes a group, and until now an integrator had to read its id off the dashboard \u2014 this is the list, with how many people each group holds, how many still accept messages, and the extra fields its contacts may carry. Either the numeric `id` or the `uid` works anywhere a group is named.",
                "x-permission": "contacts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Narrow to groups in this state; `all` includes retired ones (the default returns every group).",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "active",
                                "inactive",
                                "all"
                            ]
                        },
                        "example": "active"
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Free text over the group name.",
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "example": "Dar"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The groups, most recently changed first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "The groups, most recently changed first.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ContactGroup"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "The groups, most recently changed first."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 42,
                                                "uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                                "name": "Wateja wa Dar",
                                                "status": "active",
                                                "contacts_count": 1180,
                                                "subscribed_count": 1094,
                                                "custom_fields": [
                                                    {
                                                        "key": "order_ref",
                                                        "label": "Order reference",
                                                        "type": "text"
                                                    },
                                                    {
                                                        "key": "branch",
                                                        "label": "Branch",
                                                        "type": "select"
                                                    }
                                                ],
                                                "created_at": "2026-09-14T09:14:02+00:00",
                                                "updated_at": "2026-09-14T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupCreate",
                "summary": "Create a contact group",
                "description": "Creates a group to put contacts in. `custom_fields` declares the extra fields its contacts may carry \u2014 a contact can still be given an undeclared key, but a declared one is what the dashboard shows a column for and what a campaign addresses as `{{cf:key}}`. Duplicate keys are refused.",
                "x-permission": "contacts.create",
                "x-permission-scope": "controller",
                "requestBody": {
                    "description": "The group.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactGroupWriteRequest"
                            },
                            "example": {
                                "name": "Wateja wa Dar",
                                "custom_fields": [
                                    {
                                        "key": "order_ref",
                                        "label": "Order reference",
                                        "type": "text"
                                    }
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The group as created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/ContactGroup",
                                            "description": "The group as created."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Wateja wa Dar",
                                        "status": "active",
                                        "contacts_count": 1180,
                                        "subscribed_count": 1094,
                                        "custom_fields": [
                                            {
                                                "key": "order_ref",
                                                "label": "Order reference",
                                                "type": "text"
                                            },
                                            {
                                                "key": "branch",
                                                "label": "Branch",
                                                "type": "select"
                                            }
                                        ],
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contact-groups/{group}": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupShow",
                "summary": "Read a contact group",
                "description": "One group with its counts and the extra fields it declares \u2014 what a caller needs before writing a contact into it.",
                "x-permission": "contacts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The group.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/ContactGroup",
                                            "description": "The group."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Wateja wa Dar",
                                        "status": "active",
                                        "contacts_count": 1180,
                                        "subscribed_count": 1094,
                                        "custom_fields": [
                                            {
                                                "key": "order_ref",
                                                "label": "Order reference",
                                                "type": "text"
                                            },
                                            {
                                                "key": "branch",
                                                "label": "Branch",
                                                "type": "select"
                                            }
                                        ],
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupUpdate",
                "summary": "Change a contact group",
                "description": "Rename a group, retire it with `status: inactive`, or change the fields it declares. `custom_fields` replaces the declaration rather than merging into it; the values already stored on contacts are untouched either way.",
                "x-permission": "contacts.edit",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    }
                ],
                "requestBody": {
                    "description": "The fields to change.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactGroupWriteRequest"
                            },
                            "example": {
                                "name": "Wateja wa Mwanza"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The group as saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/ContactGroup",
                                            "description": "The group as saved."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Wateja wa Dar",
                                        "status": "active",
                                        "contacts_count": 1180,
                                        "subscribed_count": 1094,
                                        "custom_fields": [
                                            {
                                                "key": "order_ref",
                                                "label": "Order reference",
                                                "type": "text"
                                            },
                                            {
                                                "key": "branch",
                                                "label": "Branch",
                                                "type": "select"
                                            }
                                        ],
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupDelete",
                "summary": "Delete a contact group",
                "description": "Deleting a group deletes every contact in it. A group that still holds people is refused with 409 and the count, unless you repeat the call with `force=true` \u2014 there is no undo, and the contacts do not move anywhere.",
                "x-permission": "contacts.delete",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    },
                    {
                        "name": "force",
                        "in": "query",
                        "required": false,
                        "description": "Delete the group even though it still holds contacts, taking them with it.",
                        "schema": {
                            "type": "boolean",
                            "default": false
                        },
                        "example": true
                    }
                ],
                "responses": {
                    "200": {
                        "description": "What was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "id": {
                                                    "type": "integer",
                                                    "description": "The group that was deleted."
                                                },
                                                "uid": {
                                                    "type": "string",
                                                    "description": "Its UUID."
                                                },
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true on a 200 here."
                                                },
                                                "contacts_deleted": {
                                                    "type": "integer",
                                                    "description": "How many contacts went with it."
                                                }
                                            },
                                            "description": "What was deleted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 42,
                                        "uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "deleted": true,
                                        "contacts_deleted": 1180
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Refused because of the state the data is in; the message says what to do.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope"
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This group still holds 1180 contact(s), and deleting it deletes them too. Move them first, or repeat with ?force=true."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contact-groups/{group}/contacts": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactList",
                "summary": "List the contacts in a group",
                "description": "The people in one group, most recently changed first. `search` matches the name, the national number, and the full number with punctuation stripped, so a number pasted as `+255 712 345 678` finds them.",
                "x-permission": "contacts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    },
                    {
                        "name": "search",
                        "in": "query",
                        "required": false,
                        "description": "Free text over name and number.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "Asha"
                    },
                    {
                        "name": "subscribed",
                        "in": "query",
                        "required": false,
                        "description": "Only those who do (or do not) still accept messages.",
                        "schema": {
                            "type": "boolean"
                        },
                        "example": true
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The contacts in this group.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "The contacts in this group.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Contact"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "The contacts in this group."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 9201,
                                                "uid": "ctc_7f2ab1c93de04a6b8f10",
                                                "group_id": 42,
                                                "group_uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                                "name": "Asha Mwinyi",
                                                "country_code": "255",
                                                "phone_number": "712345678",
                                                "full_phone_number": "255712345678",
                                                "is_subscribed": true,
                                                "custom_field_values": {
                                                    "order_ref": "ORD-1042",
                                                    "branch": "Mlimani"
                                                },
                                                "created_at": "2026-09-14T09:14:02+00:00",
                                                "updated_at": "2026-09-14T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactCreate",
                "summary": "Add a contact to a group",
                "description": "Creates one contact. The REST twin of `POST /api/v3/contacts/{group_id}/store`, which still works and does the same thing.",
                "x-permission": "contacts.create",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    }
                ],
                "requestBody": {
                    "description": "The contact.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactWriteRequest"
                            },
                            "example": {
                                "PHONE": "0712345678",
                                "country_code": "255",
                                "name": "Asha Mwinyi",
                                "order_ref": "ORD-1042"
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The contact as created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact as created."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9201,
                                        "uid": "ctc_7f2ab1c93de04a6b8f10",
                                        "group_id": 42,
                                        "group_uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Asha Mwinyi",
                                        "country_code": "255",
                                        "phone_number": "712345678",
                                        "full_phone_number": "255712345678",
                                        "is_subscribed": true,
                                        "custom_field_values": {
                                            "order_ref": "ORD-1042",
                                            "branch": "Mlimani"
                                        },
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contact-groups/{group}/contacts/batch": {
            "post": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactBatch",
                "summary": "Import many contacts at once",
                "description": "Up to 500 contacts in one call \u2014 the import an integration actually has, instead of one POST per person. A number already in the group is UPDATED (its custom fields merge, exactly as PATCH does, and a row with no `name` does not rename anybody); a new one is created. `skip_existing` leaves the ones already there completely untouched.\n\nEvery row is judged on its own: a row that fails validation is reported in `problems` with its index and the rest still apply, and the answer is 207 when any row was rejected, 200 when none was. `results` names the outcome of every row that landed, so a caller knows what it changed without diffing anything.",
                "x-permission": "contacts.import",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    }
                ],
                "requestBody": {
                    "description": "The contacts to import.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "contacts"
                                ],
                                "properties": {
                                    "contacts": {
                                        "type": "array",
                                        "description": "The rows, 1 to 500 of them, each shaped like a single create.",
                                        "items": {
                                            "$ref": "#/components/schemas/ContactWriteRequest"
                                        },
                                        "minItems": 1,
                                        "maxItems": 500
                                    },
                                    "skip_existing": {
                                        "type": "boolean",
                                        "description": "Leave a number that is already in the group exactly as it is, rather than updating it. Defaults false."
                                    }
                                }
                            },
                            "example": {
                                "contacts": [
                                    {
                                        "PHONE": "0712345678",
                                        "country_code": "255",
                                        "name": "Asha Mwinyi",
                                        "order_ref": "ORD-1042"
                                    },
                                    {
                                        "PHONE": "0754000111",
                                        "country_code": "255",
                                        "name": "Juma Ally"
                                    }
                                ],
                                "skip_existing": false
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Every row applied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "group_id": {
                                                    "type": "integer",
                                                    "description": "The group they went into."
                                                },
                                                "received": {
                                                    "type": "integer",
                                                    "description": "How many rows you sent."
                                                },
                                                "created": {
                                                    "type": "integer",
                                                    "description": "How many were new."
                                                },
                                                "updated": {
                                                    "type": "integer",
                                                    "description": "How many matched a number already in the group."
                                                },
                                                "skipped": {
                                                    "type": "integer",
                                                    "description": "How many were left alone because of `skip_existing`."
                                                },
                                                "rejected": {
                                                    "type": "integer",
                                                    "description": "How many failed validation and did nothing."
                                                },
                                                "results": {
                                                    "type": "array",
                                                    "description": "One entry per row that landed.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ContactBatchResult"
                                                    }
                                                },
                                                "problems": {
                                                    "type": "array",
                                                    "description": "One entry per rejected row.",
                                                    "items": {
                                                        "type": "object",
                                                        "description": "A rejected row.",
                                                        "properties": {
                                                            "index": {
                                                                "type": "integer",
                                                                "description": "Its position in the array you sent."
                                                            },
                                                            "errors": {
                                                                "type": "object",
                                                                "description": "Field-by-field validation messages.",
                                                                "additionalProperties": {
                                                                    "type": "array",
                                                                    "description": "The messages for that field.",
                                                                    "items": {
                                                                        "type": "string",
                                                                        "description": "One message."
                                                                    }
                                                                }
                                                            }
                                                        }
                                                    }
                                                }
                                            },
                                            "description": "Every row applied."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "group_id": 42,
                                        "received": 2,
                                        "created": 1,
                                        "updated": 1,
                                        "skipped": 0,
                                        "rejected": 0,
                                        "results": [
                                            {
                                                "index": 0,
                                                "uid": "ctc_7f2ab1c93de04a6b8f10",
                                                "outcome": "updated"
                                            },
                                            {
                                                "index": 1,
                                                "uid": "ctc_88c1de40ab7392f5c001",
                                                "outcome": "created"
                                            }
                                        ],
                                        "problems": []
                                    }
                                }
                            }
                        }
                    },
                    "207": {
                        "description": "Some rows were rejected; the rest applied.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "received": {
                                                    "type": "integer",
                                                    "description": "How many rows you sent."
                                                },
                                                "created": {
                                                    "type": "integer",
                                                    "description": "How many were new."
                                                },
                                                "updated": {
                                                    "type": "integer",
                                                    "description": "How many matched an existing number."
                                                },
                                                "skipped": {
                                                    "type": "integer",
                                                    "description": "How many `skip_existing` left alone."
                                                },
                                                "rejected": {
                                                    "type": "integer",
                                                    "description": "How many failed validation."
                                                },
                                                "results": {
                                                    "type": "array",
                                                    "description": "The rows that landed.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/ContactBatchResult"
                                                    }
                                                },
                                                "problems": {
                                                    "type": "array",
                                                    "description": "The rows that did not, with why.",
                                                    "items": {
                                                        "type": "object",
                                                        "description": "A rejected row.",
                                                        "additionalProperties": true,
                                                        "properties": {
                                                            "index": {
                                                                "type": "integer",
                                                                "description": "Its position in the array you sent."
                                                            },
                                                            "errors": {
                                                                "type": "object",
                                                                "description": "Field-by-field validation messages.",
                                                                "additionalProperties": true
                                                            }
                                                        }
                                                    }
                                                }
                                            },
                                            "description": "Some rows were rejected; the rest applied."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "received": 3,
                                        "created": 1,
                                        "updated": 1,
                                        "skipped": 0,
                                        "rejected": 1,
                                        "results": [
                                            {
                                                "index": 0,
                                                "uid": "ctc_7f2ab1c93de04a6b8f10",
                                                "outcome": "updated"
                                            }
                                        ],
                                        "problems": [
                                            {
                                                "index": 2,
                                                "errors": {
                                                    "PHONE": [
                                                        "The PHONE field is required."
                                                    ]
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contact-groups/{group}/contacts/{contact}": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactShow",
                "summary": "Read a contact",
                "description": "One contact. The REST twin of `POST /api/v3/contacts/{group_id}/search/{uid}`.",
                "x-permission": "contacts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    },
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "ctc_7f2ab1c93de04a6b8f10"
                        },
                        "description": "The contact, by its UID or numeric id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The contact.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9201,
                                        "uid": "ctc_7f2ab1c93de04a6b8f10",
                                        "group_id": 42,
                                        "group_uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Asha Mwinyi",
                                        "country_code": "255",
                                        "phone_number": "712345678",
                                        "full_phone_number": "255712345678",
                                        "is_subscribed": true,
                                        "custom_field_values": {
                                            "order_ref": "ORD-1042",
                                            "branch": "Mlimani"
                                        },
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactUpdate",
                "summary": "Change a contact",
                "description": "Changes exactly what you send and nothing else. Custom fields MERGE into what is stored \u2014 send a key as `null` to remove it \u2014 and the name, the number and the subscription each keep their current value when the payload is silent about them. `PHONE` is not required unless the number itself is changing.\n\nThis is a change of behaviour: until 2026-09-14 this endpoint replaced the whole custom-field map and renamed the contact after their phone number whenever `name` was absent, so a call meant to flip `is_subscribed` quietly destroyed data. A caller that followed the old advice \u2014 read, merge, send everything \u2014 gets the same result as before.",
                "x-permission": "contacts.edit",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    },
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "ctc_7f2ab1c93de04a6b8f10"
                        },
                        "description": "The contact, by its UID or numeric id."
                    }
                ],
                "requestBody": {
                    "description": "The fields to change.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/ContactWriteRequest"
                            },
                            "example": {
                                "name": "Asha Juma",
                                "order_ref": "ORD-2099"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The contact as saved.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Contact",
                                            "description": "The contact as saved."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "id": 9201,
                                        "uid": "ctc_7f2ab1c93de04a6b8f10",
                                        "group_id": 42,
                                        "group_uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                        "name": "Asha Mwinyi",
                                        "country_code": "255",
                                        "phone_number": "712345678",
                                        "full_phone_number": "255712345678",
                                        "is_subscribed": true,
                                        "custom_field_values": {
                                            "order_ref": "ORD-1042",
                                            "branch": "Mlimani"
                                        },
                                        "created_at": "2026-09-14T09:14:02+00:00",
                                        "updated_at": "2026-09-14T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactGroupContactDelete",
                "summary": "Delete a contact",
                "description": "Removes the contact from the group permanently. The REST twin of `DELETE /api/v3/contacts/{group_id}/delete/{uid}`.",
                "x-permission": "contacts.delete",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "group",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": 42
                        },
                        "description": "The group, by numeric id or UUID."
                    },
                    {
                        "name": "contact",
                        "in": "path",
                        "required": true,
                        "schema": {
                            "type": "string",
                            "example": "ctc_7f2ab1c93de04a6b8f10"
                        },
                        "description": "The contact, by its UID or numeric id."
                    }
                ],
                "responses": {
                    "200": {
                        "description": "What was deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "Always true on a 200 here."
                                                },
                                                "uid": {
                                                    "type": "string",
                                                    "description": "The contact that was deleted."
                                                }
                                            },
                                            "description": "What was deleted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "uid": "ctc_7f2ab1c93de04a6b8f10"
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/contacts": {
            "get": {
                "tags": [
                    "Contacts"
                ],
                "operationId": "v3ContactSearch",
                "summary": "Find a contact across every group",
                "description": "Every contact in the workspace, whichever group holds them \u2014 the answer to \"who is this number?\" when the caller does not know. `q` matches the name, the national number and the full number with punctuation stripped. `group_id` narrows it back to one group.",
                "x-permission": "contacts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Free text over name and number. `search` is an alias.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "712345678"
                    },
                    {
                        "name": "group_id",
                        "in": "query",
                        "required": false,
                        "description": "Only this group, by numeric id or UUID.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "42"
                    },
                    {
                        "name": "subscribed",
                        "in": "query",
                        "required": false,
                        "description": "Only those who do (or do not) still accept messages.",
                        "schema": {
                            "type": "boolean"
                        },
                        "example": true
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The matching contacts, most recently changed first.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "The matching contacts, most recently changed first.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/Contact"
                                                    }
                                                },
                                                "pagination": {
                                                    "$ref": "#/components/schemas/Pagination",
                                                    "description": "Page state."
                                                }
                                            },
                                            "description": "The matching contacts, most recently changed first."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 9201,
                                                "uid": "ctc_7f2ab1c93de04a6b8f10",
                                                "group_id": 42,
                                                "group_uid": "9f3a1c20-5d6e-4a71-9c3b-2f1a0e7b8c44",
                                                "name": "Asha Mwinyi",
                                                "country_code": "255",
                                                "phone_number": "712345678",
                                                "full_phone_number": "255712345678",
                                                "is_subscribed": true,
                                                "custom_field_values": {
                                                    "order_ref": "ORD-1042",
                                                    "branch": "Mlimani"
                                                },
                                                "created_at": "2026-09-14T09:14:02+00:00",
                                                "updated_at": "2026-09-14T09:14:02+00:00"
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 25,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts": {
            "get": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostList",
                "summary": "List posts",
                "description": "Posts in this workspace: scheduled ones first (soonest first), then newest. `status=sent` is published or partially published; `failed` includes posts with a target waiting on a reconnect.",
                "x-permission": "posts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "status",
                        "in": "query",
                        "required": false,
                        "description": "Only posts in this state.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "draft",
                                "scheduled",
                                "publishing",
                                "published",
                                "partially_published",
                                "failed",
                                "cancelled",
                                "sent"
                            ]
                        },
                        "example": "scheduled"
                    },
                    {
                        "name": "platform",
                        "in": "query",
                        "required": false,
                        "description": "Only posts with a target on this platform.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "facebook",
                                "instagram",
                                "tiktok",
                                "youtube",
                                "linkedin"
                            ]
                        },
                        "example": "facebook"
                    },
                    {
                        "name": "q",
                        "in": "query",
                        "required": false,
                        "description": "Free text over the post body.",
                        "schema": {
                            "type": "string",
                            "maxLength": 120
                        },
                        "example": "chapati"
                    },
                    {
                        "$ref": "#/components/parameters/Limit"
                    },
                    {
                        "$ref": "#/components/parameters/Page"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "A page of posts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/PostPage",
                                            "description": "A page of posts."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "uid": "pub_9k2f3m1x",
                                                "status": "scheduled",
                                                "schedule_status": "pending",
                                                "scheduled_at": "2026-09-20T09:00:00+03:00",
                                                "scheduled_tz": "Africa/Dar_es_Salaam",
                                                "published_at": null,
                                                "created_at": "2026-09-18T10:12:00+03:00",
                                                "body_excerpt": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "thumbnail": {
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "kind": "image"
                                                },
                                                "media_count": 1,
                                                "media_kind": "image",
                                                "platforms": [
                                                    "facebook"
                                                ],
                                                "targets_summary": {
                                                    "pending": 1
                                                },
                                                "targets": [
                                                    {
                                                        "id": 31,
                                                        "platform": "facebook",
                                                        "status": "pending"
                                                    }
                                                ],
                                                "comments_href": null,
                                                "metrics": null,
                                                "comment_count": 0,
                                                "unanswered_count": 0,
                                                "created_by": {
                                                    "id": 12,
                                                    "name": "Amina Juma"
                                                }
                                            }
                                        ],
                                        "pagination": {
                                            "current_page": 1,
                                            "per_page": 20,
                                            "last_page": 1,
                                            "total": 1,
                                            "has_more_pages": false
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "post": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostCreate",
                "summary": "Create a post",
                "description": "Creates a post through the same rules as the composer. `schedule.mode` decides what happens next: `draft` (default) saves it; `now` publishes at once; `later` schedules it at `at`. Every target must be a connected account (`GET /api/v3/posts/accounts`) and, for now/later, able to publish. Per-platform `options` are validated against that platform (YouTube needs `title` and `made_for_kids`, TikTok `privacy_level`); pre-flight warnings block now/later until listed in `accept_warnings`. The same `idempotency_key` again returns the existing post with 200.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "requestBody": {
                    "description": "The post.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PostWriteRequest",
                                "description": "The post to write."
                            },
                            "examples": {
                                "default": {
                                    "summary": "Example",
                                    "value": {
                                        "targets": [
                                            4,
                                            7
                                        ],
                                        "content": {
                                            "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                            "media": [
                                                {
                                                    "asset": "ast_7h3k2p",
                                                    "alt_text": "Chapati on a plate"
                                                }
                                            ],
                                            "first_comment": "#chapati #dar"
                                        },
                                        "options": {
                                            "tiktok": {
                                                "privacy_level": "PUBLIC_TO_EVERYONE"
                                            }
                                        },
                                        "schedule": {
                                            "mode": "later",
                                            "at": "2026-09-20T09:00:00",
                                            "tz": "Africa/Dar_es_Salaam"
                                        },
                                        "idempotency_key": "order-42"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The post was created.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                },
                                                "notice": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Anything the scheduler wants you to know."
                                                },
                                                "existing": {
                                                    "type": "boolean",
                                                    "description": "False on a fresh create."
                                                }
                                            },
                                            "description": "The post was created."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "scheduled",
                                            "schedule_status": "pending",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        },
                                        "notice": null,
                                        "existing": false
                                    }
                                }
                            }
                        }
                    },
                    "200": {
                        "description": "The idempotency key matched an existing post; it is returned unchanged.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                },
                                                "notice": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Always null here."
                                                },
                                                "existing": {
                                                    "type": "boolean",
                                                    "description": "True."
                                                }
                                            },
                                            "description": "The idempotency key matched an existing post; it is returned unchanged."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "scheduled",
                                            "schedule_status": "pending",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        },
                                        "notice": null,
                                        "existing": true
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The pre-flight found errors, or a warning was not accepted. `verification` lists them by target.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post has warnings to accept before it can be scheduled.",
                                    "verification": {
                                        "warnings": [
                                            {
                                                "code": "caption_truncated",
                                                "target": 4
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/accounts": {
            "get": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostAccountList",
                "summary": "List publish targets",
                "description": "The connected accounts a post can go to, with each one's publishing state and why it cannot publish when it cannot. Bounded by what the key's owner is assigned to.",
                "x-permission": "posts.view",
                "x-permission-scope": "controller",
                "responses": {
                    "200": {
                        "description": "The accounts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "items"
                                            ],
                                            "properties": {
                                                "items": {
                                                    "type": "array",
                                                    "description": "Every account this key may post to.",
                                                    "items": {
                                                        "$ref": "#/components/schemas/PostAccount",
                                                        "description": "A publish target."
                                                    }
                                                }
                                            },
                                            "description": "The accounts."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "items": [
                                            {
                                                "id": 4,
                                                "platform": "facebook",
                                                "name": "Duka la Amina",
                                                "handle": null,
                                                "avatar": null,
                                                "publish_enabled": true,
                                                "needs_reconnect": false,
                                                "needs_reconnect_reason": null,
                                                "reason_text": null,
                                                "publish_tier": "ready",
                                                "publish_state": "on",
                                                "publish_gate": null,
                                                "publish_defaults": [],
                                                "insights_status": "ok",
                                                "author_kind": null,
                                                "token_expires_at": null,
                                                "health": {
                                                    "checked_at": "2026-09-18T04:05:00+03:00",
                                                    "quota": null
                                                }
                                            }
                                        ]
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/media": {
            "post": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostMediaCreate",
                "summary": "Upload media for a post",
                "description": "Send a multipart `file` (JPEG, PNG, WebP, HEIC, GIF, MP4, MOV, WebM) or an https `url` to fetch. The asset comes back `processing`; poll `GET /api/v3/posts/media/{uid}` until it is `ready`, then put its uid in `content.media`. Pictures over 1920px on the long side are resized; videos are probed for duration, aspect and audio.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "requestBody": {
                    "description": "A file or a URL.",
                    "required": true,
                    "content": {
                        "multipart/form-data": {
                            "schema": {
                                "type": "object",
                                "description": "The file.",
                                "properties": {
                                    "file": {
                                        "type": "string",
                                        "format": "binary",
                                        "description": "The picture or video."
                                    }
                                }
                            },
                            "examples": {
                                "file": {
                                    "summary": "A file",
                                    "value": {
                                        "file": "(binary)"
                                    }
                                }
                            }
                        },
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "description": "A URL to fetch.",
                                "required": [
                                    "url"
                                ],
                                "properties": {
                                    "url": {
                                        "type": "string",
                                        "description": "An https URL of a picture or video to fetch."
                                    }
                                }
                            },
                            "examples": {
                                "url": {
                                    "summary": "From a URL",
                                    "value": {
                                        "url": "https://cdn.example.co.tz/chapati.jpg"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "201": {
                        "description": "The asset, processing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "media"
                                            ],
                                            "properties": {
                                                "media": {
                                                    "$ref": "#/components/schemas/PostMediaAsset",
                                                    "description": "An uploaded media asset."
                                                }
                                            },
                                            "description": "The asset, processing."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "media": {
                                            "uid": "ast_7h3k2p",
                                            "kind": "image",
                                            "mime_type": "image/jpeg",
                                            "original_name": "chapati.jpg",
                                            "size": 412000,
                                            "status": "processing",
                                            "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                            "thumbnail_url": null,
                                            "probe": null,
                                            "warnings": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/media/{uid}": {
            "get": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostMediaShow",
                "summary": "Read a media asset",
                "description": "One uploaded asset and its state; `ready` means it can go on a post.",
                "x-permission": "posts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The asset uid (ast_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "ast_7h3k2p"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The asset.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "media"
                                            ],
                                            "properties": {
                                                "media": {
                                                    "$ref": "#/components/schemas/PostMediaAsset",
                                                    "description": "An uploaded media asset."
                                                }
                                            },
                                            "description": "The asset."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "media": {
                                            "uid": "ast_7h3k2p",
                                            "kind": "image",
                                            "mime_type": "image/jpeg",
                                            "original_name": "chapati.jpg",
                                            "size": 412000,
                                            "status": "ready",
                                            "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                            "thumbnail_url": null,
                                            "probe": {
                                                "width": 1080,
                                                "height": 1350,
                                                "duration_ms": null,
                                                "aspect": 0.8,
                                                "has_audio": null
                                            },
                                            "warnings": []
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/{uid}": {
            "get": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostShow",
                "summary": "Read a post",
                "description": "One post in full: content, per-platform options, every target's state and public link, the pre-flight report, and any pending approval.",
                "x-permission": "posts.view",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The post.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "$ref": "#/components/schemas/Post",
                                            "description": "The post."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "uid": "pub_9k2f3m1x",
                                        "status": "scheduled",
                                        "schedule_status": "pending",
                                        "scheduled_at": "2026-09-20T09:00:00+03:00",
                                        "scheduled_tz": "Africa/Dar_es_Salaam",
                                        "published_at": null,
                                        "completed_at": null,
                                        "created_at": "2026-09-18T10:12:00+03:00",
                                        "updated_at": "2026-09-18T10:15:00+03:00",
                                        "created_by": {
                                            "id": 12,
                                            "name": "Amina Juma"
                                        },
                                        "approved_by": {
                                            "id": 12,
                                            "name": "Amina Juma"
                                        },
                                        "approved_at": "2026-09-18T10:15:00+03:00",
                                        "content": {
                                            "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                            "media": [
                                                {
                                                    "asset": "ast_7h3k2p",
                                                    "alt_text": "Chapati on a plate"
                                                }
                                            ],
                                            "first_comment": "#chapati #dar"
                                        },
                                        "overrides": [],
                                        "options": {
                                            "tiktok": {
                                                "privacy_level": "PUBLIC_TO_EVERYONE"
                                            }
                                        },
                                        "options_overrides": [],
                                        "targets": [
                                            {
                                                "id": 31,
                                                "social_account_id": 4,
                                                "platform": "facebook",
                                                "status": "pending",
                                                "provider_post_id": null,
                                                "permalink": null,
                                                "error_message": null,
                                                "published_at": null
                                            }
                                        ],
                                        "media": [
                                            {
                                                "uid": "ast_7h3k2p",
                                                "kind": "image",
                                                "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                "status": "ready"
                                            }
                                        ],
                                        "verification": {
                                            "errors": [],
                                            "warnings": []
                                        },
                                        "notes": null,
                                        "idempotency_key": "order-42",
                                        "approval": null
                                    }
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "patch": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostUpdate",
                "summary": "Replace a post's content",
                "description": "Replaces the content, targets and options of a draft or a pending scheduled post \u2014 the same body as create. A post already publishing answers 409. Editing an approved post withdraws the approval; `schedule.mode` re-records it.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "requestBody": {
                    "description": "The post.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/PostWriteRequest",
                                "description": "The post to write."
                            },
                            "examples": {
                                "default": {
                                    "summary": "Example",
                                    "value": {
                                        "targets": [
                                            4,
                                            7
                                        ],
                                        "content": {
                                            "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                            "media": [
                                                {
                                                    "asset": "ast_7h3k2p",
                                                    "alt_text": "Chapati on a plate"
                                                }
                                            ],
                                            "first_comment": "#chapati #dar"
                                        },
                                        "options": {
                                            "tiktok": {
                                                "privacy_level": "PUBLIC_TO_EVERYONE"
                                            }
                                        },
                                        "schedule": {
                                            "mode": "later",
                                            "at": "2026-09-20T09:00:00",
                                            "tz": "Africa/Dar_es_Salaam"
                                        },
                                        "idempotency_key": "order-42"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The updated post.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                },
                                                "notice": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Anything the scheduler wants you to know."
                                                }
                                            },
                                            "description": "The updated post."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "scheduled",
                                            "schedule_status": "pending",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        },
                                        "notice": null
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The post is already publishing, or the pre-flight blocked the requested schedule.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post is already publishing and can no longer be edited."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            },
            "delete": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostDelete",
                "summary": "Delete a post",
                "description": "Removes the post here. Anything already published on a platform stays there; a post that is publishing right now answers 409.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Deleted.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "deleted",
                                                "uid"
                                            ],
                                            "properties": {
                                                "deleted": {
                                                    "type": "boolean",
                                                    "description": "True."
                                                },
                                                "uid": {
                                                    "type": "string",
                                                    "description": "The uid that was deleted."
                                                }
                                            },
                                            "description": "Deleted."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "deleted": true,
                                        "uid": "pub_9k2f3m1x"
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The post is publishing right now.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post is already publishing."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/{uid}/schedule": {
            "post": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostSchedule",
                "summary": "Schedule a post",
                "description": "Schedules a draft (or moves a pending scheduled post) to `at`. Pre-flight warnings must be accepted by code; errors answer 409 with the report.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "requestBody": {
                    "description": "The time.",
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "description": "When.",
                                "required": [
                                    "at"
                                ],
                                "properties": {
                                    "at": {
                                        "type": "string",
                                        "description": "When to publish, ISO-8601."
                                    },
                                    "tz": {
                                        "type": "string",
                                        "description": "IANA timezone for `at`."
                                    },
                                    "accept_warnings": {
                                        "type": "array",
                                        "description": "Warning codes accepted.",
                                        "items": {
                                            "type": "string",
                                            "description": "A warning code."
                                        }
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "summary": "Example",
                                    "value": {
                                        "at": "2026-09-20T09:00:00",
                                        "tz": "Africa/Dar_es_Salaam",
                                        "accept_warnings": []
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Scheduled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                },
                                                "notice": {
                                                    "type": [
                                                        "string",
                                                        "null"
                                                    ],
                                                    "description": "Anything the scheduler wants you to know."
                                                }
                                            },
                                            "description": "Scheduled."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "scheduled",
                                            "schedule_status": "pending",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        },
                                        "notice": null
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The pre-flight blocked it, or the post is already publishing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post has warnings to accept before it can be scheduled."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/{uid}/publish-now": {
            "post": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostPublishNow",
                "summary": "Publish a post now",
                "description": "Queues the post to go out immediately on every target. Same pre-flight rule as scheduling.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "requestBody": {
                    "description": "Accepted warnings, if any.",
                    "required": false,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "description": "Accepted warnings.",
                                "properties": {
                                    "accept_warnings": {
                                        "type": "array",
                                        "description": "Warning codes accepted.",
                                        "items": {
                                            "type": "string",
                                            "description": "A warning code."
                                        }
                                    }
                                }
                            },
                            "examples": {
                                "default": {
                                    "summary": "Accepting one warning",
                                    "value": {
                                        "accept_warnings": [
                                            "caption_truncated"
                                        ]
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Publishing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                }
                                            },
                                            "description": "Publishing."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "scheduled",
                                            "schedule_status": "pending",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "The pre-flight blocked it, or the post is already publishing.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post is already publishing."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "422": {
                        "$ref": "#/components/responses/ValidationFailed"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/api/v3/posts/{uid}/cancel": {
            "post": {
                "tags": [
                    "Posts"
                ],
                "operationId": "v3PostCancel",
                "summary": "Cancel a scheduled post",
                "description": "Stops a scheduled post before its time: it is marked cancelled and will not go out. A post already publishing stops only the targets that have not started.",
                "x-permission": "posts.manage",
                "x-permission-scope": "controller",
                "parameters": [
                    {
                        "name": "uid",
                        "in": "path",
                        "required": true,
                        "description": "The post id (pub_\u2026).",
                        "schema": {
                            "type": "string"
                        },
                        "example": "pub_9k2f3m1x"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "Cancelled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "required": [
                                        "status",
                                        "data"
                                    ],
                                    "properties": {
                                        "status": {
                                            "type": "string",
                                            "description": "Always \"success\".",
                                            "enum": [
                                                "success"
                                            ]
                                        },
                                        "data": {
                                            "type": "object",
                                            "required": [
                                                "post"
                                            ],
                                            "properties": {
                                                "post": {
                                                    "$ref": "#/components/schemas/Post",
                                                    "description": "The post in full."
                                                }
                                            },
                                            "description": "Cancelled."
                                        }
                                    }
                                },
                                "example": {
                                    "status": "success",
                                    "data": {
                                        "post": {
                                            "uid": "pub_9k2f3m1x",
                                            "status": "cancelled",
                                            "schedule_status": "processed",
                                            "scheduled_at": "2026-09-20T09:00:00+03:00",
                                            "scheduled_tz": "Africa/Dar_es_Salaam",
                                            "published_at": null,
                                            "completed_at": null,
                                            "created_at": "2026-09-18T10:12:00+03:00",
                                            "updated_at": "2026-09-18T10:15:00+03:00",
                                            "created_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_by": {
                                                "id": 12,
                                                "name": "Amina Juma"
                                            },
                                            "approved_at": "2026-09-18T10:15:00+03:00",
                                            "content": {
                                                "body": "Chapati za asubuhi zimeanza! Karibu Duka la Amina.",
                                                "media": [
                                                    {
                                                        "asset": "ast_7h3k2p",
                                                        "alt_text": "Chapati on a plate"
                                                    }
                                                ],
                                                "first_comment": "#chapati #dar"
                                            },
                                            "overrides": [],
                                            "options": {
                                                "tiktok": {
                                                    "privacy_level": "PUBLIC_TO_EVERYONE"
                                                }
                                            },
                                            "options_overrides": [],
                                            "targets": [
                                                {
                                                    "id": 31,
                                                    "social_account_id": 4,
                                                    "platform": "facebook",
                                                    "status": "pending",
                                                    "provider_post_id": null,
                                                    "permalink": null,
                                                    "error_message": null,
                                                    "published_at": null
                                                }
                                            ],
                                            "media": [
                                                {
                                                    "uid": "ast_7h3k2p",
                                                    "kind": "image",
                                                    "url": "https://business.momo.tz/storage/posts/ast_7h3k2p.jpg",
                                                    "status": "ready"
                                                }
                                            ],
                                            "verification": {
                                                "errors": [],
                                                "warnings": []
                                            },
                                            "notes": null,
                                            "idempotency_key": "order-42",
                                            "approval": null
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "409": {
                        "description": "Nothing to cancel: the post is not scheduled.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/LegacyErrorEnvelope",
                                    "description": "See the referenced schema."
                                },
                                "example": {
                                    "status": "error",
                                    "message": "This post is not scheduled."
                                }
                            }
                        }
                    },
                    "401": {
                        "$ref": "#/components/responses/Unauthorized"
                    },
                    "403": {
                        "$ref": "#/components/responses/Forbidden"
                    },
                    "404": {
                        "$ref": "#/components/responses/NotFound"
                    },
                    "429": {
                        "$ref": "#/components/responses/RateLimited"
                    }
                }
            }
        },
        "/mcp": {
            "post": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpAccountEndpoint",
                "summary": "Call the account MCP server",
                "description": "The bare `/mcp` root, serving the **account** server \u2014 the cross-domain starting point, and what a person types when a client asks for a URL.\n\nIt exists because without it the whole OAuth handshake succeeds \u2014 discovery, consent, a real access token \u2014 and then the first `tools/call` 404s, which is the least debuggable failure there is.\n\nEverything below applies equally to `POST /mcp/v1/{server}`; connect a specific server there when you know which part of the business you want, because most clients fold the entire tool list into their context and connecting everything makes an assistant worse at choosing.",
                "x-generated-by": "php artisan mcp:manifest",
                "security": [
                    {
                        "McpBearerToken": []
                    },
                    {
                        "McpOAuth": [
                            "mcp:use"
                        ]
                    }
                ],
                "requestBody": {
                    "required": true,
                    "description": "A JSON-RPC 2.0 request. `Accept` must allow both `application/json` and `text/event-stream`.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonRpcRequest"
                            },
                            "examples": {
                                "initialize": {
                                    "summary": "1. initialize \u2014 open the session",
                                    "description": "Sent once, first. Negotiates a protocol version and returns the server's instructions.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 1,
                                        "method": "initialize",
                                        "params": {
                                            "protocolVersion": "2025-06-18",
                                            "capabilities": {
                                                "roots": {
                                                    "listChanged": true
                                                }
                                            },
                                            "clientInfo": {
                                                "name": "my-agent",
                                                "version": "1.0.0"
                                            }
                                        }
                                    }
                                },
                                "toolsList": {
                                    "summary": "2. tools/list \u2014 discover what is here",
                                    "description": "The only way to learn the tool names. They are deliberately not in this OpenAPI document: what a credential can reach depends on the account, its modules and the granted scopes.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 2,
                                        "method": "tools/list"
                                    }
                                },
                                "toolsCall": {
                                    "summary": "3. tools/call \u2014 run one",
                                    "description": "`params.arguments` must satisfy that tool's `inputSchema` from `tools/list`.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 3,
                                        "method": "tools/call",
                                        "params": {
                                            "name": "list_ivr_flows",
                                            "arguments": {
                                                "search": "main"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The JSON-RPC result. A notification \u2014 a request with no `id` \u2014 is answered `202` with an empty body instead.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "examples": {
                                    "initialize": {
                                        "summary": "initialize",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 1,
                                            "result": {
                                                "protocolVersion": "2025-06-18",
                                                "capabilities": {
                                                    "tools": {
                                                        "listChanged": false
                                                    },
                                                    "resources": {
                                                        "listChanged": false
                                                    },
                                                    "prompts": {
                                                        "listChanged": false
                                                    }
                                                },
                                                "serverInfo": {
                                                    "name": "Momo IVR",
                                                    "version": "1.0.0"
                                                },
                                                "instructions": "Build and edit the call flows (IVRs) that answer this business's phone lines. \u2026"
                                            }
                                        }
                                    },
                                    "toolsList": {
                                        "summary": "tools/list",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 2,
                                            "result": {
                                                "tools": [
                                                    {
                                                        "name": "list_ivr_flows",
                                                        "title": "List Ivr Flows",
                                                        "description": "The call flows on this account, newest first.",
                                                        "inputSchema": {
                                                            "type": "object",
                                                            "properties": {
                                                                "search": {
                                                                    "type": "string",
                                                                    "description": "Filter by name."
                                                                }
                                                            }
                                                        },
                                                        "annotations": {
                                                            "readOnlyHint": true
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    "toolsCall": {
                                        "summary": "tools/call",
                                        "description": "A tool that fails cleanly still answers 200 \u2014 with `isError` true and a message the model is meant to act on.",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 3,
                                            "result": {
                                                "content": [
                                                    {
                                                        "type": "text",
                                                        "text": "{\"flows\":[{\"id\":41,\"name\":\"Main line\",\"status\":\"published\"}]}"
                                                    }
                                                ],
                                                "isError": false
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "A notification was accepted. No body."
                    },
                    "401": {
                        "description": "No credential, or one that is expired or revoked. The `WWW-Authenticate` header points at the protected-resource document, which is what bootstraps the OAuth handshake.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32001,
                                        "message": "Authentication required.",
                                        "data": {
                                            "reason": "missing_token"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The credential is valid but this server is out of reach \u2014 a capability that was not granted, a module switched off for the account, a suspended account, or a v3 API key used in place of an MCP credential. `data.reason` says which.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "This connection was not given access to Numbers. The account owner can add it by reconnecting.",
                                        "data": {
                                            "reason": "server_not_granted"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "More than 120 requests in a minute from this connection.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32003,
                                        "message": "Too many MCP requests from this connection. Wait a minute and retry \u2014 do not loop."
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "The MCP surface is switched off platform-wide. Never cached \u2014 shutting it down is a database write that takes effect on the next request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "The MCP surface is not enabled on this platform right now.",
                                        "data": {
                                            "reason": "surface_disabled"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    }
                }
            }
        },
        "/mcp/v1": {
            "get": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpListServers",
                "summary": "List the servers this credential can reach",
                "description": "What **this** credential can reach, which is not the same question as what exists: scopes differ per credential, and a capability the account holder did not grant leaves its server absent rather than merely unauthorized.\n\nThe public catalogue, for someone evaluating the platform before they have a token, is `GET /api-docs/mcp.json`.",
                "x-generated-by": "php artisan mcp:manifest",
                "security": [
                    {
                        "McpBearerToken": []
                    },
                    {
                        "McpOAuth": [
                            "mcp:use"
                        ]
                    }
                ],
                "responses": {
                    "200": {
                        "description": "The servers, each marked reachable or not for this credential.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "account": {
                                            "type": [
                                                "string",
                                                "null"
                                            ],
                                            "description": "The account this credential belongs to."
                                        },
                                        "protocol": {
                                            "type": "string",
                                            "const": "mcp",
                                            "description": "Always \"mcp\"."
                                        },
                                        "transport": {
                                            "type": "string",
                                            "const": "streamable-http",
                                            "description": "The MCP transport these endpoints speak."
                                        },
                                        "servers": {
                                            "type": "array",
                                            "items": {
                                                "$ref": "#/components/schemas/ServerInfo"
                                            },
                                            "description": "Every mounted server, marked reachable or not for this credential."
                                        },
                                        "docs": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "Where a person can read about all of this."
                                        }
                                    }
                                },
                                "example": {
                                    "account": "Workspace Alpha",
                                    "protocol": "mcp",
                                    "transport": "streamable-http",
                                    "servers": [
                                        {
                                            "key": "ivr",
                                            "name": "IVR",
                                            "description": "Build and edit call flows: read the graph, apply node operations, validate, simulate, version and assign to numbers.",
                                            "url": "https://business.momo.tz/mcp/v1/ivr",
                                            "available": true,
                                            "reason": null
                                        },
                                        {
                                            "key": "numbers",
                                            "name": "Numbers",
                                            "description": "Phone numbers: what you own, what is available, what one costs, and how to pay for it.",
                                            "url": "https://business.momo.tz/mcp/v1/numbers",
                                            "available": false,
                                            "reason": "This connection was not granted access to Numbers."
                                        }
                                    ],
                                    "docs": "https://business.momo.tz/api-docs#mcp"
                                }
                            }
                        }
                    },
                    "401": {
                        "description": "No credential, or one that is expired or revoked.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32001,
                                        "message": "Authentication required.",
                                        "data": {
                                            "reason": "missing_token"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "The MCP surface is switched off platform-wide.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "The MCP surface is not enabled on this platform right now.",
                                        "data": {
                                            "reason": "surface_disabled"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    }
                }
            }
        },
        "/mcp/v1/{server}": {
            "post": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpServerEndpoint",
                "summary": "Call one MCP server",
                "description": "One server, one URL, one JSON-RPC endpoint. The tools it offers are discovered at runtime with `tools/list`; their arguments are a JSON Schema each, published for every server at `GET /api-docs/mcp.json`.\n\n| `server` | Name | What it covers |\n|---|---|---|\n| `ivr` | IVR | Build and edit call flows: read the graph, apply node operations, validate, simulate, version and assign to numbers. |\n| `flows` | Message flows | Build and edit WhatsApp conversation flows: nodes, edges, triggers, validation, simulation and analytics. |\n| `data` | Data tables | The tables this business defined for itself and their records: read with filters, create/update/upsert rows, shape fields, run and save reports, and group related tables into folders with reports that read across them. Flows and IVRs read the same tables. |\n| `approvals` | Approvals | Decisions a person has been asked for before something happens: read the queue, read one in full with every comment on it, answer one. |\n| `payments` | Payments | Money this business collects from its customers: what has been asked for and where each one got to, one payment's whole timeline, asking a customer to pay, and refunds. Not the business's own Momo bill. |\n| `automations` | Automations | What happens without anybody there: the log of what has actually happened in the business, the subscriptions that react to it, and the schedules that run on a rhythm. |\n| `alerts` | Alerts & service levels | The business watching itself: the alert rules it wrote, the service-level promises and the clocks running against them, the risk rules that hold or refuse an action, and one log of everything that fired \u2014 including what reached nobody. |\n| `operations` | Operations | The named things this business can do \u2014 create a booking, register a customer, process a refund \u2014 each written down once, and the log of every time one ran. |\n| `studio` | Studio | Voice and audio: browse the voice library, generate speech, convert audio and publish it for use in an IVR. |\n| `numbers` | Numbers | Phone numbers: what you own, what is available, what one costs, and how to pay for it. |\n| `groups` | WhatsApp groups | Groups the business runs from its WhatsApp number: create, invite, post, approve joins, remove members. |\n| `agents` | Agents | Your own AI specialists: see the roster and ask one a question. |\n| `orders` | Orders | Customer orders across every platform: find, read, move status, request payment. |\n| `shop` | Shop | Products, brands and categories, plus the order tools. |\n| `tickets` | Tickets | Support tickets: create, update, assign, reply, labels and notifications. |\n| `kb` | Knowledge base | Your knowledge base: categories, search and full article text. |\n| `content` | Platform content | Public help articles, changelog, roadmap and system status. |\n| `calls` | Calls | Call history, recordings, transcripts, events and Call Studio scripts. |\n| `routing` | Call routing | Routing rules, ring groups, working hours and forwarding targets. |\n| `meetings` | Meetings | See and schedule meetings, and invite people to them. |\n| `messaging` | Messaging | Templates, sender IDs, campaigns, message history \u2014 and sending SMS and WhatsApp. |\n| `inbox` | Inbox | Customer conversations across WhatsApp, SMS, social and email \u2014 read, assign, reply, and send new mail. |\n| `comments` | Comments | Comments on your Facebook, Instagram and TikTok posts. |\n| `posts` | Posts | Social posts to Facebook, Instagram, TikTok, YouTube and LinkedIn: what is drafted, scheduled and sent; drafting a new one; scheduling or publishing it. |\n| `contacts` | Contacts | The contact book and groups. |\n| `overview` | Overview | The dashboard, business analytics, call stats and spend \u2014 how the business is doing. |\n| `accounts` | Connected accounts | The WhatsApp numbers, social profiles, mailboxes and SMS routes this business has connected, and what each can actually do. |\n| `navigate` | Finding things | Where pages and settings live in the app, and what each form asks for. |\n| `account` | Account | A cross-domain starting point: overview, search, fetch, and the most-used read tools. |",
                "x-generated-by": "php artisan mcp:manifest",
                "security": [
                    {
                        "McpBearerToken": []
                    },
                    {
                        "McpOAuth": [
                            "mcp:use"
                        ]
                    }
                ],
                "parameters": [
                    {
                        "name": "server",
                        "in": "path",
                        "required": true,
                        "description": "Which server to talk to.",
                        "schema": {
                            "type": "string",
                            "enum": [
                                "ivr",
                                "flows",
                                "data",
                                "approvals",
                                "payments",
                                "automations",
                                "alerts",
                                "operations",
                                "studio",
                                "numbers",
                                "groups",
                                "agents",
                                "orders",
                                "shop",
                                "tickets",
                                "kb",
                                "content",
                                "calls",
                                "routing",
                                "meetings",
                                "messaging",
                                "inbox",
                                "comments",
                                "posts",
                                "contacts",
                                "overview",
                                "accounts",
                                "navigate",
                                "account"
                            ]
                        },
                        "example": "ivr"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "description": "A JSON-RPC 2.0 request. `Accept` must allow both `application/json` and `text/event-stream`.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/JsonRpcRequest"
                            },
                            "examples": {
                                "initialize": {
                                    "summary": "1. initialize \u2014 open the session",
                                    "description": "Sent once, first. Negotiates a protocol version and returns the server's instructions.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 1,
                                        "method": "initialize",
                                        "params": {
                                            "protocolVersion": "2025-06-18",
                                            "capabilities": {
                                                "roots": {
                                                    "listChanged": true
                                                }
                                            },
                                            "clientInfo": {
                                                "name": "my-agent",
                                                "version": "1.0.0"
                                            }
                                        }
                                    }
                                },
                                "toolsList": {
                                    "summary": "2. tools/list \u2014 discover what is here",
                                    "description": "The only way to learn the tool names. They are deliberately not in this OpenAPI document: what a credential can reach depends on the account, its modules and the granted scopes.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 2,
                                        "method": "tools/list"
                                    }
                                },
                                "toolsCall": {
                                    "summary": "3. tools/call \u2014 run one",
                                    "description": "`params.arguments` must satisfy that tool's `inputSchema` from `tools/list`.",
                                    "value": {
                                        "jsonrpc": "2.0",
                                        "id": 3,
                                        "method": "tools/call",
                                        "params": {
                                            "name": "list_ivr_flows",
                                            "arguments": {
                                                "search": "main"
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The JSON-RPC result. A notification \u2014 a request with no `id` \u2014 is answered `202` with an empty body instead.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "examples": {
                                    "initialize": {
                                        "summary": "initialize",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 1,
                                            "result": {
                                                "protocolVersion": "2025-06-18",
                                                "capabilities": {
                                                    "tools": {
                                                        "listChanged": false
                                                    },
                                                    "resources": {
                                                        "listChanged": false
                                                    },
                                                    "prompts": {
                                                        "listChanged": false
                                                    }
                                                },
                                                "serverInfo": {
                                                    "name": "Momo IVR",
                                                    "version": "1.0.0"
                                                },
                                                "instructions": "Build and edit the call flows (IVRs) that answer this business's phone lines. \u2026"
                                            }
                                        }
                                    },
                                    "toolsList": {
                                        "summary": "tools/list",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 2,
                                            "result": {
                                                "tools": [
                                                    {
                                                        "name": "list_ivr_flows",
                                                        "title": "List Ivr Flows",
                                                        "description": "The call flows on this account, newest first.",
                                                        "inputSchema": {
                                                            "type": "object",
                                                            "properties": {
                                                                "search": {
                                                                    "type": "string",
                                                                    "description": "Filter by name."
                                                                }
                                                            }
                                                        },
                                                        "annotations": {
                                                            "readOnlyHint": true
                                                        }
                                                    }
                                                ]
                                            }
                                        }
                                    },
                                    "toolsCall": {
                                        "summary": "tools/call",
                                        "description": "A tool that fails cleanly still answers 200 \u2014 with `isError` true and a message the model is meant to act on.",
                                        "value": {
                                            "jsonrpc": "2.0",
                                            "id": 3,
                                            "result": {
                                                "content": [
                                                    {
                                                        "type": "text",
                                                        "text": "{\"flows\":[{\"id\":41,\"name\":\"Main line\",\"status\":\"published\"}]}"
                                                    }
                                                ],
                                                "isError": false
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    },
                    "202": {
                        "description": "A notification was accepted. No body."
                    },
                    "401": {
                        "description": "No credential, or one that is expired or revoked. The `WWW-Authenticate` header points at the protected-resource document, which is what bootstraps the OAuth handshake.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32001,
                                        "message": "Authentication required.",
                                        "data": {
                                            "reason": "missing_token"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "403": {
                        "description": "The credential is valid but this server is out of reach \u2014 a capability that was not granted, a module switched off for the account, a suspended account, or a v3 API key used in place of an MCP credential. `data.reason` says which.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "This connection was not given access to Numbers. The account owner can add it by reconnecting.",
                                        "data": {
                                            "reason": "server_not_granted"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "404": {
                        "description": "No server by that key.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "No such MCP server.",
                                        "data": {
                                            "reason": "unknown_server"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "More than 120 requests in a minute from this connection.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32003,
                                        "message": "Too many MCP requests from this connection. Wait a minute and retry \u2014 do not loop."
                                    },
                                    "id": null
                                }
                            }
                        }
                    },
                    "503": {
                        "description": "The MCP surface is switched off platform-wide. Never cached \u2014 shutting it down is a database write that takes effect on the next request.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/JsonRpcResponse"
                                },
                                "example": {
                                    "jsonrpc": "2.0",
                                    "error": {
                                        "code": -32002,
                                        "message": "The MCP surface is not enabled on this platform right now.",
                                        "data": {
                                            "reason": "surface_disabled"
                                        }
                                    },
                                    "id": null
                                }
                            }
                        }
                    }
                }
            }
        },
        "/.well-known/oauth-authorization-server": {
            "get": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpOAuthAuthorizationServerMetadata",
                "summary": "OAuth 2.1 authorization server metadata",
                "description": "RFC 8414 discovery, and the **first** call a hosted client makes. Claude will not finish a connector setup without a `registration_endpoint` here, and ChatGPT's OAuth mode needs the same handshake.\n\n`scopes_supported` is the full granular set rather than a single blanket scope, because a client can only ask for what is advertised.",
                "x-generated-by": "php artisan mcp:manifest",
                "x-no-client-error": "A public discovery document with no request to get wrong: it is served unauthenticated, on any path suffix, and always answers 200.",
                "security": [],
                "responses": {
                    "200": {
                        "description": "The discovery document.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "issuer": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "The authorization server's identifier."
                                        },
                                        "authorization_endpoint": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "Where the person is sent to approve the connection."
                                        },
                                        "token_endpoint": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "Where the authorization code is exchanged for a token."
                                        },
                                        "registration_endpoint": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "RFC 7591 dynamic client registration. Claude will not finish a connector setup without this field."
                                        },
                                        "response_types_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "Only `code`."
                                        },
                                        "code_challenge_methods_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "Only `S256`. PKCE is required, not optional."
                                        },
                                        "scopes_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string",
                                                "enum": [
                                                    "mcp:use",
                                                    "mcp:overview",
                                                    "mcp:calls",
                                                    "mcp:routing",
                                                    "mcp:numbers",
                                                    "mcp:meetings",
                                                    "mcp:builders",
                                                    "mcp:data",
                                                    "mcp:studio",
                                                    "mcp:contacts",
                                                    "mcp:agents",
                                                    "mcp:commerce",
                                                    "mcp:support",
                                                    "mcp:accounts",
                                                    "mcp:approvals",
                                                    "mcp:payments",
                                                    "mcp:automations",
                                                    "mcp:alerts",
                                                    "mcp:operations",
                                                    "mcp:navigate",
                                                    "mcp:messaging",
                                                    "mcp:inbox",
                                                    "mcp:comments",
                                                    "mcp:posts",
                                                    "mcp:groups",
                                                    "mcp:publish",
                                                    "mcp:send",
                                                    "mcp:spend",
                                                    "mcp:delete",
                                                    "mcp:write",
                                                    "mcp:shape",
                                                    "mcp:automate",
                                                    "mcp:approve"
                                                ]
                                            },
                                            "description": "Every scope a client may ask for. A client can only request what is advertised here."
                                        },
                                        "grant_types_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "`authorization_code` and `refresh_token`."
                                        },
                                        "token_endpoint_auth_methods_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "`none`: clients are public and authenticate with PKCE."
                                        }
                                    }
                                },
                                "example": {
                                    "issuer": "https://business.momo.tz",
                                    "authorization_endpoint": "https://business.momo.tz/oauth/authorize",
                                    "token_endpoint": "https://business.momo.tz/oauth/token",
                                    "registration_endpoint": "https://business.momo.tz/oauth/register",
                                    "response_types_supported": [
                                        "code"
                                    ],
                                    "code_challenge_methods_supported": [
                                        "S256"
                                    ],
                                    "scopes_supported": [
                                        "mcp:use",
                                        "mcp:overview",
                                        "mcp:calls",
                                        "mcp:routing",
                                        "mcp:numbers",
                                        "mcp:meetings",
                                        "mcp:builders",
                                        "mcp:data",
                                        "mcp:studio",
                                        "mcp:contacts",
                                        "mcp:agents",
                                        "mcp:commerce",
                                        "mcp:support",
                                        "mcp:accounts",
                                        "mcp:approvals",
                                        "mcp:payments",
                                        "mcp:automations",
                                        "mcp:alerts",
                                        "mcp:operations",
                                        "mcp:navigate",
                                        "mcp:messaging",
                                        "mcp:inbox",
                                        "mcp:comments",
                                        "mcp:posts",
                                        "mcp:groups",
                                        "mcp:publish",
                                        "mcp:send",
                                        "mcp:spend",
                                        "mcp:delete",
                                        "mcp:write",
                                        "mcp:shape",
                                        "mcp:automate",
                                        "mcp:approve"
                                    ],
                                    "grant_types_supported": [
                                        "authorization_code",
                                        "refresh_token"
                                    ],
                                    "token_endpoint_auth_methods_supported": [
                                        "none"
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/.well-known/oauth-protected-resource": {
            "get": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpOAuthProtectedResourceMetadata",
                "summary": "OAuth 2.1 protected resource metadata",
                "description": "RFC 9728. A client that gets a `401` from an MCP endpoint reads the `WWW-Authenticate` header, lands here, and learns which authorization server guards the resource. That chain is what turns an unauthenticated first request into a completed connector setup without anybody typing a URL.",
                "x-generated-by": "php artisan mcp:manifest",
                "x-no-client-error": "A public discovery document with no request to get wrong: it is served unauthenticated, on any path suffix, and always answers 200.",
                "security": [],
                "responses": {
                    "200": {
                        "description": "The resource metadata.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "resource": {
                                            "type": "string",
                                            "format": "uri",
                                            "description": "The protected resource this document describes."
                                        },
                                        "authorization_servers": {
                                            "type": "array",
                                            "items": {
                                                "type": "string",
                                                "format": "uri"
                                            },
                                            "description": "Where to go to get a token for it."
                                        },
                                        "scopes_supported": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "The base scope every MCP token carries."
                                        }
                                    }
                                },
                                "example": {
                                    "resource": "https://business.momo.tz",
                                    "authorization_servers": [
                                        "https://business.momo.tz"
                                    ],
                                    "scopes_supported": [
                                        "mcp:use"
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        },
        "/oauth/register": {
            "post": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpOAuthRegisterClient",
                "summary": "Register an OAuth client",
                "description": "RFC 7591 dynamic client registration. Open by design \u2014 a hosted client registers itself, unattended, the first time somebody adds the connector \u2014 which is why `redirect_uris` is checked against an allow-list of published callback hosts. Register a redirect you control and the authorization code for somebody's account would be delivered to you, so a redirect outside the list is rejected rather than trusted.\n\nThe issued client is public: no secret, PKCE required.",
                "x-generated-by": "php artisan mcp:manifest",
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "redirect_uris"
                                ],
                                "properties": {
                                    "client_name": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "A name for the client. `name` is accepted as an alias; one of the two is required."
                                    },
                                    "name": {
                                        "type": "string",
                                        "maxLength": 255,
                                        "description": "Alias for `client_name`."
                                    },
                                    "redirect_uris": {
                                        "type": "array",
                                        "minItems": 1,
                                        "items": {
                                            "type": "string",
                                            "format": "uri"
                                        },
                                        "description": "Absolute callback URLs. Each must sit under a permitted host, or under loopback for a desktop client that finishes the flow locally."
                                    }
                                }
                            },
                            "example": {
                                "client_name": "My agent",
                                "redirect_uris": [
                                    "https://claude.ai/api/mcp/auth_callback"
                                ]
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The registered client.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "client_id": {
                                            "type": "string",
                                            "description": "Send this on the authorize and token calls."
                                        },
                                        "grant_types": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "The grants this client may use."
                                        },
                                        "response_types": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "Only `code`."
                                        },
                                        "redirect_uris": {
                                            "type": "array",
                                            "items": {
                                                "type": "string",
                                                "format": "uri"
                                            },
                                            "description": "The callbacks that were accepted."
                                        },
                                        "scope": {
                                            "type": "string",
                                            "description": "The default scope. Ask for more on the authorize call."
                                        },
                                        "token_endpoint_auth_method": {
                                            "type": "string",
                                            "const": "none",
                                            "description": "No client secret is issued: this is a public client and PKCE is the proof."
                                        }
                                    }
                                },
                                "example": {
                                    "client_id": "9d1f6c2a-4e1b-4a77-9a3a-0f2f1b0d5c11",
                                    "grant_types": [
                                        "authorization_code",
                                        "refresh_token"
                                    ],
                                    "response_types": [
                                        "code"
                                    ],
                                    "redirect_uris": [
                                        "https://claude.ai/api/mcp/auth_callback"
                                    ],
                                    "scope": "mcp:use",
                                    "token_endpoint_auth_method": "none"
                                }
                            }
                        }
                    },
                    "422": {
                        "description": "The registration was rejected \u2014 most often a redirect URI outside the permitted hosts.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "A sentence naming the first problem."
                                        },
                                        "errors": {
                                            "type": "object",
                                            "additionalProperties": {
                                                "type": "array",
                                                "items": {
                                                    "type": "string"
                                                }
                                            },
                                            "description": "Each rejected field mapped to its messages."
                                        }
                                    }
                                },
                                "example": {
                                    "message": "The redirect uris.0 field is not a permitted redirect domain.",
                                    "errors": {
                                        "redirect_uris.0": [
                                            "redirect_uris.0 is not a permitted redirect domain."
                                        ]
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "/oauth/token": {
            "post": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpOAuthIssueToken",
                "summary": "Exchange an authorization code for an access token",
                "description": "The standard OAuth 2.1 token endpoint, form-encoded. Public clients only: send `code_verifier`, not a client secret. `refresh_token` is supported with the same call and `grant_type=refresh_token`.\n\nThe returned token carries the scopes the account holder actually ticked, which may be fewer than the ones requested.",
                "x-generated-by": "php artisan mcp:manifest",
                "security": [],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/x-www-form-urlencoded": {
                            "schema": {
                                "type": "object",
                                "required": [
                                    "grant_type",
                                    "client_id"
                                ],
                                "properties": {
                                    "grant_type": {
                                        "type": "string",
                                        "enum": [
                                            "authorization_code",
                                            "refresh_token"
                                        ],
                                        "description": "Which exchange this is."
                                    },
                                    "client_id": {
                                        "type": "string",
                                        "description": "The client id from dynamic client registration."
                                    },
                                    "code": {
                                        "type": "string",
                                        "description": "The authorization code, for `grant_type=authorization_code`."
                                    },
                                    "redirect_uri": {
                                        "type": "string",
                                        "format": "uri",
                                        "description": "The same redirect used to obtain the code."
                                    },
                                    "code_verifier": {
                                        "type": "string",
                                        "description": "The PKCE verifier whose S256 challenge was sent to the authorize endpoint."
                                    },
                                    "refresh_token": {
                                        "type": "string",
                                        "description": "For `grant_type=refresh_token`."
                                    }
                                }
                            },
                            "example": {
                                "grant_type": "authorization_code",
                                "client_id": "9d1f6c2a-4e1b-4a77-9a3a-0f2f1b0d5c11",
                                "code": "def502009a\u2026",
                                "redirect_uri": "https://claude.ai/api/mcp/auth_callback",
                                "code_verifier": "dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk"
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "The access token.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "token_type": {
                                            "type": "string",
                                            "const": "Bearer",
                                            "description": "Always \"Bearer\"."
                                        },
                                        "expires_in": {
                                            "type": "integer",
                                            "description": "Seconds until the access token expires."
                                        },
                                        "access_token": {
                                            "type": "string",
                                            "description": "Send as `Authorization: Bearer \u2026` on the MCP endpoints."
                                        },
                                        "refresh_token": {
                                            "type": "string",
                                            "description": "Exchange this for a new access token with `grant_type=refresh_token`."
                                        },
                                        "scope": {
                                            "type": "string",
                                            "description": "Space-separated scopes actually granted, which may be fewer than were asked for."
                                        }
                                    }
                                },
                                "example": {
                                    "token_type": "Bearer",
                                    "expires_in": 31536000,
                                    "access_token": "eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiJ9\u2026",
                                    "refresh_token": "def50200f0a1\u2026",
                                    "scope": "mcp:use mcp:overview mcp:calls"
                                }
                            }
                        }
                    },
                    "400": {
                        "description": "The grant was refused \u2014 a spent or mismatched code, a bad `code_verifier`, or an unknown client.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "error": {
                                            "type": "string",
                                            "description": "The OAuth error code, such as `invalid_grant` or `invalid_client`."
                                        },
                                        "error_description": {
                                            "type": "string",
                                            "description": "What went wrong, in a sentence."
                                        },
                                        "hint": {
                                            "type": "string",
                                            "description": "Which part of the request was at fault, when the server can tell."
                                        },
                                        "message": {
                                            "type": "string",
                                            "description": "The same text as `error_description`."
                                        }
                                    }
                                },
                                "example": {
                                    "error": "invalid_grant",
                                    "error_description": "The provided authorization grant is invalid, expired, revoked, or was issued to another client.",
                                    "message": "The provided authorization grant is invalid, expired, revoked, or was issued to another client."
                                }
                            }
                        }
                    },
                    "429": {
                        "description": "Too many token requests. Back off and retry.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "message": {
                                            "type": "string",
                                            "description": "The refusal, in a sentence."
                                        }
                                    }
                                },
                                "example": {
                                    "message": "Too Many Attempts."
                                }
                            }
                        }
                    }
                }
            }
        },
        "/api-docs/mcp.json": {
            "get": {
                "tags": [
                    "MCP"
                ],
                "operationId": "mcpToolManifest",
                "summary": "Get the MCP tool manifest",
                "description": "The machine-readable tool contract: every server, every tool, and a **complete JSON Schema** for each tool's arguments \u2014 generate typed bindings from it rather than hand-writing them.\n\nPublic and unauthenticated on purpose, so a developer can point a client at us before they have signed up. It is the same document this OpenAPI file is for REST: this one describes the transport, that one describes the operations.",
                "x-generated-by": "php artisan mcp:manifest",
                "x-no-client-error": "A public document, served to anyone with no parameters to get wrong.",
                "security": [],
                "responses": {
                    "200": {
                        "description": "The manifest.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "generated_by": {
                                            "type": "string",
                                            "const": "php artisan mcp:manifest",
                                            "description": "The command that wrote this document. It is generated, never hand-edited."
                                        },
                                        "transport": {
                                            "type": "string",
                                            "const": "streamable-http",
                                            "description": "The MCP transport every server speaks."
                                        },
                                        "protocol_versions": {
                                            "type": "array",
                                            "items": {
                                                "type": "string"
                                            },
                                            "description": "Protocol versions accepted at `initialize`, newest first."
                                        },
                                        "auth": {
                                            "type": "object",
                                            "description": "The OAuth handshake and the bearer alternative, plus the scopes a consent screen offers.",
                                            "additionalProperties": true
                                        },
                                        "presets": {
                                            "type": "array",
                                            "items": {
                                                "type": "object",
                                                "additionalProperties": true
                                            },
                                            "description": "Ready-made server selections offered when somebody creates a connection."
                                        },
                                        "server_count": {
                                            "type": "integer",
                                            "description": "How many servers are mounted."
                                        },
                                        "tool_count": {
                                            "type": "integer",
                                            "description": "How many tools they carry between them."
                                        },
                                        "root": {
                                            "type": "object",
                                            "description": "The aggregate root at `/mcp` \u2014 every area a connection was granted, behind one URL.",
                                            "properties": {
                                                "path": {
                                                    "type": "string",
                                                    "description": "The endpoint, relative to the API host."
                                                },
                                                "tool_count": {
                                                    "type": "integer",
                                                    "description": "How many distinct tools the whole surface carries."
                                                },
                                                "tools_hash": {
                                                    "type": "string",
                                                    "description": "One hash over every tool's version. Store it, and a single comparison tells you whether the surface you generated against is the one being served.",
                                                    "examples": [
                                                        "a1b2c3d4"
                                                    ]
                                                }
                                            },
                                            "additionalProperties": true
                                        },
                                        "servers": {
                                            "type": "array",
                                            "description": "Every server and the tools it carries.",
                                            "items": {
                                                "type": "object",
                                                "properties": {
                                                    "key": {
                                                        "type": "string",
                                                        "description": "The `{server}` path segment."
                                                    },
                                                    "name": {
                                                        "type": "string",
                                                        "description": "Display name."
                                                    },
                                                    "summary": {
                                                        "type": "string",
                                                        "description": "What the server is for."
                                                    },
                                                    "path": {
                                                        "type": "string",
                                                        "description": "The endpoint, relative to the API host."
                                                    },
                                                    "module": {
                                                        "type": [
                                                            "string",
                                                            "null"
                                                        ],
                                                        "description": "The sidebar module this server follows; null when it is always available."
                                                    },
                                                    "instructions": {
                                                        "type": "string",
                                                        "description": "What the server tells a model about itself at `initialize`."
                                                    },
                                                    "tools": {
                                                        "type": "array",
                                                        "items": {
                                                            "$ref": "#/components/schemas/ToolDefinition"
                                                        },
                                                        "description": "Its tools, each with a full JSON Schema for its arguments."
                                                    }
                                                }
                                            }
                                        }
                                    }
                                },
                                "example": {
                                    "generated_by": "php artisan mcp:manifest",
                                    "transport": "streamable-http",
                                    "protocol_versions": [
                                        "2025-11-25",
                                        "2025-06-18",
                                        "2025-03-26"
                                    ],
                                    "server_count": 21,
                                    "tool_count": 104,
                                    "servers": [
                                        {
                                            "key": "ivr",
                                            "name": "IVR",
                                            "path": "/mcp/v1/ivr",
                                            "tools": [
                                                {
                                                    "name": "list_ivr_flows",
                                                    "version": "3f9c1a04",
                                                    "description": "The call flows on this account, newest first.",
                                                    "writes": false,
                                                    "permissions": [
                                                        "ivr.view"
                                                    ],
                                                    "input_schema": {
                                                        "$schema": "https://json-schema.org/draft/2020-12/schema",
                                                        "title": "list_ivr_flows arguments",
                                                        "type": "object",
                                                        "properties": {
                                                            "search": {
                                                                "type": "string",
                                                                "description": "Filter by name."
                                                            }
                                                        }
                                                    }
                                                }
                                            ]
                                        }
                                    ]
                                }
                            }
                        }
                    }
                }
            }
        }
    },
    "webhooks": {
        "messageEvent": {
            "post": {
                "tags": [
                    "Webhooks"
                ],
                "operationId": "webhookMessageEvent",
                "summary": "Every event we POST to your server",
                "description": "A signed JSON POST to each receiver you registered for the event. Every delivery is a record you can read back at `GET /api/v3/webhooks/{webhook}/deliveries` and replay. **Retries:** a 5xx, a timeout or a connection failure is retried five times over about six hours (1 m, 5 m, 30 m, 2 h, 6 h). A 4xx other than 408/425/429 is treated as \"understood and refused\" and is not retried. After fifty consecutive failures the endpoint is paused and you are told; replaying any failed delivery resumes it. **Answer 2xx quickly** \u2014 persist or enqueue, then acknowledge \u2014 and verify the signature over the raw bytes before parsing.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-Signature",
                        "in": "header",
                        "required": true,
                        "description": "Plain hex HMAC-SHA256 of the raw body under the endpoint secret; no prefix. Unchanged from the first version, so existing receivers keep verifying.",
                        "schema": {
                            "type": "string",
                            "pattern": "^[a-f0-9]{64}$"
                        },
                        "example": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                    },
                    {
                        "name": "X-Signature-V2",
                        "in": "header",
                        "required": true,
                        "description": "Prefer this. `sha256=` + hex HMAC-SHA256 of `\"{X-Timestamp}.{X-Delivery-Id}.{raw body}\"` under the endpoint secret. Checking it gives you replay protection for free: refuse a timestamp older than five minutes, and remember delivery ids you have seen.",
                        "schema": {
                            "type": "string",
                            "pattern": "^sha256=[a-f0-9]{64}$"
                        },
                        "example": "sha256=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
                    },
                    {
                        "name": "X-Timestamp",
                        "in": "header",
                        "required": true,
                        "description": "Unix seconds when this attempt was sent. Part of the V2 signature.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "1757581442"
                    },
                    {
                        "name": "X-Delivery-Id",
                        "in": "header",
                        "required": true,
                        "description": "Unique per delivery, the same across retries of it. Dedupe on this.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "dlv_01j9qk3v8x2m7n4p5r6s"
                    },
                    {
                        "name": "X-Event",
                        "in": "header",
                        "required": true,
                        "description": "The event name, so a receiver can route before parsing.",
                        "schema": {
                            "type": "string"
                        },
                        "example": "order.received"
                    }
                ],
                "requestBody": {
                    "required": true,
                    "description": "The event payload.",
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/WebhookEvent"
                            },
                            "examples": {
                                "message_received": {
                                    "summary": "A message arrived",
                                    "value": {
                                        "event": "message.received",
                                        "message_id": 101,
                                        "direction": "inbound",
                                        "sender": "255712345678",
                                        "recipient": "MyBrand",
                                        "status": "received",
                                        "body": "Habari, mna kanga?",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_sent": {
                                    "summary": "A message was sent",
                                    "value": {
                                        "event": "message.sent",
                                        "message_id": 102,
                                        "direction": "outbound",
                                        "sender": "MyBrand",
                                        "recipient": "255712345678",
                                        "status": "sent",
                                        "body": "Ndiyo, tuna kanga.",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_delivered": {
                                    "summary": "A message was delivered",
                                    "value": {
                                        "event": "message.delivered",
                                        "message_id": 102,
                                        "direction": "outbound",
                                        "sender": "MyBrand",
                                        "recipient": "255712345678",
                                        "status": "delivered",
                                        "body": "Ndiyo, tuna kanga.",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_read": {
                                    "summary": "A message was read",
                                    "value": {
                                        "event": "message.read",
                                        "message_id": 102,
                                        "direction": "outbound",
                                        "sender": "MyBrand",
                                        "recipient": "255712345678",
                                        "status": "read",
                                        "body": "Ndiyo, tuna kanga.",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_failed": {
                                    "summary": "A message failed",
                                    "value": {
                                        "event": "message.failed",
                                        "message_id": 103,
                                        "direction": "outbound",
                                        "sender": "MyBrand",
                                        "recipient": "255712345678",
                                        "status": "failed",
                                        "body": "Ofa ya leo!",
                                        "media_url": null,
                                        "channel_type": "sms",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_echoed": {
                                    "summary": "A message was sent from the phone itself",
                                    "value": {
                                        "event": "message.echoed",
                                        "message_id": 104,
                                        "direction": "outbound",
                                        "sender": "MyBrand",
                                        "recipient": "255712345678",
                                        "status": "sent",
                                        "body": "Karibu!",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "message_updated": {
                                    "summary": "A message was edited",
                                    "value": {
                                        "event": "message.updated",
                                        "message_id": 101,
                                        "direction": "inbound",
                                        "sender": "255712345678",
                                        "recipient": "MyBrand",
                                        "status": "received",
                                        "body": "Habari, mna kanga za bluu?",
                                        "media_url": null,
                                        "channel_type": "whatsapp",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "order_received": {
                                    "summary": "An order arrived",
                                    "value": {
                                        "event": "order.received",
                                        "order": {
                                            "id": 9182,
                                            "catalogue_id": 42,
                                            "platform": "whatsapp",
                                            "status": "pending",
                                            "needs_attention": false,
                                            "stock_policy": "external",
                                            "customer_handle": "255712345678",
                                            "customer_name": "Asha Mrisho",
                                            "customer_phone": "255712345678",
                                            "customer_note": null,
                                            "lines": [
                                                {
                                                    "sku": "MNG-45W",
                                                    "name": "Charger Mango 45W",
                                                    "quantity": 1,
                                                    "unit_price_minor": 3900000,
                                                    "line_total_minor": 3900000,
                                                    "currency": "TZS",
                                                    "reserved": 1,
                                                    "stock_short": false,
                                                    "unresolved": false
                                                }
                                            ],
                                            "total_minor": 3900000,
                                            "currency": "TZS",
                                            "conversation_id": 771,
                                            "priced_at": "2026-09-11T09:14:02+00:00",
                                            "created_at": "2026-09-11T09:14:02+00:00",
                                            "order_id": 9182,
                                            "customer_wa_id": "255712345678",
                                            "total_amount": 3900000,
                                            "total_currency": "TZS"
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "order_status_changed": {
                                    "summary": "An order changed status",
                                    "value": {
                                        "event": "order.status_changed",
                                        "order": {
                                            "id": 9182,
                                            "catalogue_id": 42,
                                            "platform": "whatsapp",
                                            "status": "confirmed",
                                            "needs_attention": false,
                                            "stock_policy": "external",
                                            "customer_handle": "255712345678",
                                            "customer_name": "Asha Mrisho",
                                            "customer_phone": "255712345678",
                                            "customer_note": null,
                                            "lines": [
                                                {
                                                    "sku": "MNG-45W",
                                                    "name": "Charger Mango 45W",
                                                    "quantity": 1,
                                                    "unit_price_minor": 3900000,
                                                    "line_total_minor": 3900000,
                                                    "currency": "TZS",
                                                    "reserved": 1,
                                                    "stock_short": false,
                                                    "unresolved": false
                                                }
                                            ],
                                            "total_minor": 3900000,
                                            "currency": "TZS",
                                            "conversation_id": 771,
                                            "priced_at": "2026-09-11T09:14:02+00:00",
                                            "created_at": "2026-09-11T09:14:02+00:00",
                                            "order_id": 9182,
                                            "customer_wa_id": "255712345678",
                                            "total_amount": 3900000,
                                            "total_currency": "TZS"
                                        },
                                        "previous_status": "pending",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "order_cancelled": {
                                    "summary": "An order was cancelled",
                                    "value": {
                                        "event": "order.cancelled",
                                        "order": {
                                            "id": 9182,
                                            "catalogue_id": 42,
                                            "platform": "whatsapp",
                                            "status": "cancelled",
                                            "needs_attention": false,
                                            "stock_policy": "external",
                                            "customer_handle": "255712345678",
                                            "customer_name": "Asha Mrisho",
                                            "customer_phone": "255712345678",
                                            "customer_note": null,
                                            "lines": [
                                                {
                                                    "sku": "MNG-45W",
                                                    "name": "Charger Mango 45W",
                                                    "quantity": 1,
                                                    "unit_price_minor": 3900000,
                                                    "line_total_minor": 3900000,
                                                    "currency": "TZS",
                                                    "reserved": 1,
                                                    "stock_short": false,
                                                    "unresolved": false
                                                }
                                            ],
                                            "total_minor": 3900000,
                                            "currency": "TZS",
                                            "conversation_id": 771,
                                            "priced_at": "2026-09-11T09:14:02+00:00",
                                            "created_at": "2026-09-11T09:14:02+00:00",
                                            "order_id": 9182,
                                            "customer_wa_id": "255712345678",
                                            "total_amount": 3900000,
                                            "total_currency": "TZS"
                                        },
                                        "previous_status": "pending",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "order_paid": {
                                    "summary": "An order was paid",
                                    "value": {
                                        "event": "order.paid",
                                        "order_id": 9182,
                                        "payment_id": 4410,
                                        "method": "ussd_push",
                                        "amount_minor": 3900000,
                                        "currency": "TZS",
                                        "payer_msisdn": "255712345678",
                                        "paid_at": "2026-09-11T09:14:02+00:00",
                                        "conversation_id": 771,
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "sync_completed": {
                                    "summary": "A bulk sync finished",
                                    "value": {
                                        "event": "sync.completed",
                                        "sync": {
                                            "id": 812,
                                            "catalogue_id": 42,
                                            "source": "api",
                                            "mode": "upsert",
                                            "status": "completed",
                                            "received": 2000,
                                            "created": 12,
                                            "updated": 1982,
                                            "unchanged": 0,
                                            "rejected": 6,
                                            "retired": 0,
                                            "platforms": {
                                                "whatsapp": {
                                                    "synced": 1960,
                                                    "blocked": 34
                                                }
                                            },
                                            "problems_truncated": false
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "stock_low": {
                                    "summary": "A product is running low",
                                    "value": {
                                        "event": "stock.low",
                                        "catalogue_id": 42,
                                        "sku": "MNG-45W",
                                        "name": "Charger Mango 45W",
                                        "available": 2,
                                        "threshold": 3,
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "product_blocked": {
                                    "summary": "A platform will not show a product",
                                    "value": {
                                        "event": "product.blocked",
                                        "catalogue_id": 42,
                                        "sku": "MNG-KNIFE",
                                        "platform": "whatsapp",
                                        "problem": "WhatsApp needs a product image it can fetch.",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "product_drifted": {
                                    "summary": "A platform's copy of a product differs from ours",
                                    "value": {
                                        "event": "product.drifted",
                                        "catalogue_id": 42,
                                        "sku": "MNG-45W",
                                        "platform": "whatsapp",
                                        "source_of_truth": "api",
                                        "diff": {
                                            "price": {
                                                "ours": 4500000,
                                                "theirs": 4200000
                                            }
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "campaign_completed": {
                                    "summary": "A campaign finished",
                                    "value": {
                                        "event": "campaign.completed",
                                        "campaign_uid": "cmp_8f2c",
                                        "sent": 1180,
                                        "failed": 20,
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "campaign_failed": {
                                    "summary": "A campaign failed",
                                    "value": {
                                        "event": "campaign.failed",
                                        "campaign_uid": "cmp_8f2c",
                                        "reason": "Insufficient balance.",
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_created": {
                                    "summary": "A group was created",
                                    "value": {
                                        "event": "group.created",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_create_failed": {
                                    "summary": "A group could not be created",
                                    "value": {
                                        "event": "group.create_failed",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_updated": {
                                    "summary": "A group was updated",
                                    "value": {
                                        "event": "group.updated",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_deleted": {
                                    "summary": "A group was deleted",
                                    "value": {
                                        "event": "group.deleted",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_suspended": {
                                    "summary": "A group was suspended by WhatsApp",
                                    "value": {
                                        "event": "group.suspended",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_suspension_cleared": {
                                    "summary": "A group suspension was lifted",
                                    "value": {
                                        "event": "group.suspension_cleared",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_participant_joined": {
                                    "summary": "Someone joined a group",
                                    "value": {
                                        "event": "group.participant_joined",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_participant_left": {
                                    "summary": "Someone left a group",
                                    "value": {
                                        "event": "group.participant_left",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_participant_removed": {
                                    "summary": "Someone was removed from a group",
                                    "value": {
                                        "event": "group.participant_removed",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_join_requested": {
                                    "summary": "Someone asked to join a group",
                                    "value": {
                                        "event": "group.join_requested",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_join_request_revoked": {
                                    "summary": "A join request was withdrawn",
                                    "value": {
                                        "event": "group.join_request_revoked",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "group_invite_sent": {
                                    "summary": "A group invite was sent",
                                    "value": {
                                        "event": "group.invite_sent",
                                        "group": {
                                            "id": 31,
                                            "subject": "Wateja wa Dar",
                                            "participants_count": 48
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "webhook_paused": {
                                    "summary": "An endpoint was paused",
                                    "value": {
                                        "event": "webhook.paused",
                                        "webhook_id": 7,
                                        "url": "https://store.example.com/momo",
                                        "consecutive_failures": 50,
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "flow_session_started": {
                                    "summary": "A flow session started",
                                    "value": {
                                        "event": "flow.session.started",
                                        "session_id": 5120,
                                        "flow_id": 17,
                                        "flow_name": "Oda ya chakula",
                                        "flow_version": 3,
                                        "conversation_id": 771,
                                        "contact_id": 2201,
                                        "contact_name": "Asha Mrisho",
                                        "contact_identifier": "255712345678",
                                        "trigger": "inbound",
                                        "status": "running",
                                        "outcome": "in_progress",
                                        "ended_reason": null,
                                        "node_id": "ask_name",
                                        "turns": 0,
                                        "started_at": "2026-09-11T09:14:02+00:00",
                                        "ended_at": null,
                                        "variables": [],
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                },
                                "flow_session_ended": {
                                    "summary": "A flow session ended",
                                    "value": {
                                        "event": "flow.session.ended",
                                        "session_id": 5120,
                                        "flow_id": 17,
                                        "flow_name": "Oda ya chakula",
                                        "flow_version": 3,
                                        "conversation_id": 771,
                                        "contact_id": 2201,
                                        "contact_name": "Asha Mrisho",
                                        "contact_identifier": "255712345678",
                                        "trigger": "inbound",
                                        "status": "completed",
                                        "outcome": "completed",
                                        "ended_reason": "completed",
                                        "node_id": "done",
                                        "turns": 6,
                                        "started_at": "2026-09-11T09:14:02+00:00",
                                        "ended_at": "2026-09-11T09:14:02+00:00",
                                        "variables": {
                                            "order_ref": "ORD-2026-0091",
                                            "total": 24000
                                        },
                                        "timestamp": "2026-09-11T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Your receiver acknowledged the event. The current dispatcher does not retry based on receiver status or parse its response body.",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "type": "object",
                                    "properties": {
                                        "received": {
                                            "type": "boolean",
                                            "description": "Illustrative acknowledgement chosen by your receiver."
                                        }
                                    }
                                },
                                "examples": {
                                    "default": {
                                        "value": {
                                            "received": true
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }
        },
        "businessEvent": {
            "post": {
                "operationId": "receiveBusinessEvent",
                "tags": [
                    "Webhooks"
                ],
                "summary": "Receive a signed automation business event",
                "description": "Sent to the URL of a webhook event subscription. This is a different protocol from messageEvent communication callbacks. Verify X-Momo-Signature over timestamp + dot + raw body; the helper default timestamp tolerance is 300 seconds. The payload is serialized with unescaped Unicode and slashes. Respond with 2xx after durable acceptance. Up to six attempts use a 15-second HTTP timeout. Transport failures, 408, 429 and 5xx are retryable; other HTTP refusals are terminal. Default delays between attempts are 10,20,40,80,160 seconds. Positive numeric Retry-After overrides the delay, capped at 300 seconds; HTTP-date values are not parsed. Ten consecutive terminal delivery failures disable the subscription. The timestamp/signature is regenerated each attempt; deduplicate using event ID and subscription ID. Fan-out counts a webhook as delivered when it is queued and can reset subscription failure counters before the HTTP attempt; the receiver audit is the authoritative record of receipt.",
                "security": [],
                "parameters": [
                    {
                        "name": "X-Momo-Signature",
                        "in": "header",
                        "required": false,
                        "description": "t=<unix seconds>,v1=<hex HMAC-SHA256 of timestamp + dot + raw body>. Use the subscription secret, constant-time comparison and a timestamp tolerance.",
                        "schema": {
                            "type": "string",
                            "example": "t=1918015200,v1=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
                        }
                    },
                    {
                        "name": "X-Momo-Event",
                        "in": "header",
                        "required": true,
                        "description": "Business event key.",
                        "schema": {
                            "type": "string",
                            "example": "record.created"
                        }
                    },
                    {
                        "name": "X-Momo-Event-Id",
                        "in": "header",
                        "required": true,
                        "description": "Stable event ID across retry attempts.",
                        "schema": {
                            "type": "string",
                            "example": "01953b60-4ce0-7000-8000-000000000001"
                        }
                    },
                    {
                        "name": "X-Momo-Subscription",
                        "in": "header",
                        "required": true,
                        "description": "Subscription receiving this event.",
                        "schema": {
                            "type": "string",
                            "example": "12"
                        }
                    },
                    {
                        "name": "X-Momo-Attempt",
                        "in": "header",
                        "required": true,
                        "description": "One-based queue attempt number.",
                        "schema": {
                            "type": "string",
                            "example": "1"
                        }
                    }
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/BusinessWebhookEvent"
                            },
                            "examples": {
                                "recordCreated": {
                                    "summary": "Business event envelope; publisher data varies",
                                    "value": {
                                        "id": "01953b60-4ce0-7000-8000-000000000001",
                                        "event": "record.created",
                                        "occurred_at": "2030-10-12T06:00:00+00:00",
                                        "tenant_id": 42,
                                        "subject": {
                                            "type": "data_record",
                                            "id": "01953b60-4ce0-7000-8000-000000000002"
                                        },
                                        "actor": {
                                            "kind": "api",
                                            "label": "ERP integration",
                                            "id": 7
                                        },
                                        "data": {
                                            "table": {
                                                "id": "01953b60-4ce0-7000-8000-000000000003",
                                                "name": "Customers",
                                                "slug": "customers"
                                            },
                                            "record_id": "01953b60-4ce0-7000-8000-000000000002",
                                            "record": {
                                                "name": "Example"
                                            },
                                            "source": "api"
                                        },
                                        "subscription": {
                                            "id": 12,
                                            "label": "Forward record changes"
                                        }
                                    }
                                },
                                "templateStatusChanged": {
                                    "summary": "template.status_changed \u2014 Meta approved a template",
                                    "value": {
                                        "event": "template.status_changed",
                                        "template_id": 418,
                                        "name": "order_shipped",
                                        "language": "sw",
                                        "category": "utility",
                                        "whatsapp_business_account_id": "102290129340398",
                                        "whatsapp_template_id": "1189456212345678",
                                        "previous_status": "in_review",
                                        "whatsapp_status": "approved",
                                        "rejection_reason": null,
                                        "timestamp": "2026-09-13T09:14:02+00:00"
                                    }
                                }
                            }
                        }
                    }
                },
                "responses": {
                    "200": {
                        "description": "Receiver has durably accepted the event. Any 2xx response is acknowledged as successful."
                    }
                }
            }
        }
    }
}