{
  "openapi": "3.0.0",
  "info": {
    "title": "Blueticks API",
    "version": "2.0.0",
    "description": "Public API for Blueticks WhatsApp automation."
  },
  "servers": [
    {
      "url": "https://api.blueticks.co"
    }
  ],
  "tags": [
    {
      "name": "Account",
      "description": "Account metadata for the authenticated API key."
    },
    {
      "name": "Audiences",
      "description": "Reusable contact lists used as targets for messages and campaigns."
    },
    {
      "name": "Campaigns",
      "description": "Schedule audiences for paced bulk delivery with pause/resume/cancel controls."
    },
    {
      "name": "Chats",
      "description": "Read and manage WhatsApp chats on the connected engine."
    },
    {
      "name": "Contacts",
      "description": "Read WhatsApp contacts known to the connected engine."
    },
    {
      "name": "Engines",
      "description": "Inspect or control the WhatsApp engine(s) connected to the workspace."
    },
    {
      "name": "Groups",
      "description": "Create and manage WhatsApp groups via the connected engine."
    },
    {
      "name": "Messages",
      "description": "Send, list, search, react to, and fetch media for individual WhatsApp messages on the connected engine."
    },
    {
      "name": "Newsletters",
      "description": "Create and inspect WhatsApp newsletters (channels) via the connected engine."
    },
    {
      "name": "Ping",
      "description": "Connectivity probe for the Blueticks API and the account's WhatsApp engine(s)."
    },
    {
      "name": "Scheduled Messages",
      "description": "Send or schedule WhatsApp messages via the user-messages queue. Each request creates a queued send — set `sendAt` (RFC 3339) to defer delivery, omit it to send immediately. List, retrieve, edit, and cancel queued sends."
    },
    {
      "name": "Webhooks",
      "description": "Register URLs to receive signed HTTPS POSTs on Blueticks events."
    }
  ],
  "paths": {
    "/v1/ping": {
      "get": {
        "tags": [
          "Ping"
        ],
        "summary": "Ping",
        "description": "Health and connectivity probe. Confirms the Blueticks API server is live (`api: \"ok\"`) and lists the WhatsApp engines currently connected to this account in `whatsapp_connections`. Each connection is labelled `gateway` (a remote, server-side engine — the Blueticks 24/7 gateway / baileys pod) or `regular` (the user's own WhatsApp Web browser extension). An empty `whatsapp_connections` array means no WhatsApp is connected — this is not an error, and `message` explains it. Requires a valid API key; no scope required.",
        "security": [
          {
            "BearerAuth": []
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "api": {
                          "type": "string",
                          "enum": [
                            "ok"
                          ],
                          "description": "Blueticks API server liveness. \"ok\" means the API server is up and served this request."
                        },
                        "account_id": {
                          "type": "string",
                          "description": "The account (workspace) the API key belongs to."
                        },
                        "whatsapp_connections": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "id": {
                                "type": "string",
                                "description": "Stable id of the live engine session (its MQTT presence client id)."
                              },
                              "type": {
                                "type": "string",
                                "enum": [
                                  "gateway",
                                  "regular"
                                ],
                                "description": "Engine kind. \"gateway\" = a remote, server-side engine (Blueticks 24/7 gateway / baileys pod). \"regular\" = the user's own WhatsApp Web browser extension."
                              },
                              "connected": {
                                "type": "boolean",
                                "enum": [
                                  true
                                ],
                                "description": "Always true — an entry appears only while its presence heartbeat is live."
                              }
                            },
                            "required": [
                              "id",
                              "type",
                              "connected"
                            ],
                            "additionalProperties": false
                          },
                          "description": "WhatsApp engines currently connected for this account. Empty means no WhatsApp is connected."
                        },
                        "message": {
                          "type": "string",
                          "description": "Present only when whatsapp_connections is empty; explains the empty state."
                        }
                      },
                      "required": [
                        "api",
                        "account_id",
                        "whatsapp_connections"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "ping.list"
      }
    },
    "/v1/account": {
      "get": {
        "tags": [
          "Account"
        ],
        "summary": "Get account",
        "description": "Retrieve the account the API key belongs to.",
        "security": [
          {
            "BearerAuth": [
              "account:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Stable identifier for the account."
                        },
                        "name": {
                          "type": "string",
                          "description": "Account display name."
                        },
                        "user_email": {
                          "type": "string",
                          "nullable": true,
                          "description": "Email address of the user the API key belongs to, or null if unavailable."
                        },
                        "timezone": {
                          "type": "string",
                          "nullable": true,
                          "description": "IANA timezone (e.g. \"America/New_York\"), or null if unset."
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "description": "RFC 3339 timestamp of account creation."
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "user_email",
                        "timezone",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "account.list"
      }
    },
    "/v1/scheduled-messages": {
      "get": {
        "tags": [
          "Scheduled Messages"
        ],
        "summary": "List scheduled messages",
        "description": "List messages in the user-messages queue (all sources: API, dashboard, extension), newest first (offset-paginated). Optionally filter by `chatId` and/or lifecycle `status`.",
        "security": [
          {
            "BearerAuth": [
              "messages:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^[0-9]+(?:-[0-9]+)?@(?:c\\.us|g\\.us|newsletter)$"
            },
            "description": "Filter to messages addressed to this WhatsApp JID. Matches the recipient stored on the queued/scheduled doc — for sends to a phone number, the JID is `<phone>@c.us`."
          },
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200
            },
            "description": "Search token; when set, only items whose name matches are returned."
          },
          {
            "name": "status",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "pending",
                "confirmed",
                "received",
                "read",
                "played",
                "failed"
              ]
            },
            "description": "Filter by lifecycle status: `pending` (accepted, waiting), `confirmed` (WhatsApp accepted — has waMessageKey), `received` (double grey tick), `read` (double blue tick), `played` (voice played), `failed`."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (1-200, default 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "nullable": true
                          },
                          "key": {
                            "type": "string",
                            "nullable": true
                          },
                          "to": {
                            "type": "string"
                          },
                          "type": {
                            "type": "string",
                            "enum": [
                              "text",
                              "media",
                              "poll"
                            ],
                            "description": "Message kind that was sent."
                          },
                          "text": {
                            "type": "string",
                            "nullable": true
                          },
                          "mediaUrl": {
                            "type": "string",
                            "nullable": true
                          },
                          "mediaKind": {
                            "type": "string",
                            "enum": [
                              "image",
                              "video",
                              "audio",
                              "document",
                              "sticker",
                              "voice",
                              "gif"
                            ],
                            "nullable": true
                          },
                          "pollQuestion": {
                            "type": "string",
                            "nullable": true
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "confirmed",
                              "received",
                              "read",
                              "played",
                              "failed"
                            ]
                          },
                          "sendAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "createdAt": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "confirmedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "receivedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "readAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "playedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "failedAt": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "failureReason": {
                            "type": "string",
                            "nullable": true
                          },
                          "linkPreview": {
                            "type": "object",
                            "properties": {
                              "title": {
                                "type": "string",
                                "nullable": true
                              },
                              "description": {
                                "type": "string",
                                "nullable": true
                              },
                              "canonicalUrl": {
                                "type": "string",
                                "nullable": true
                              },
                              "thumbnail": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "title",
                              "description",
                              "canonicalUrl",
                              "thumbnail"
                            ],
                            "additionalProperties": false,
                            "nullable": true
                          }
                        },
                        "required": [
                          "id",
                          "key",
                          "to",
                          "type",
                          "text",
                          "mediaUrl",
                          "mediaKind",
                          "pollQuestion",
                          "status",
                          "sendAt",
                          "createdAt",
                          "confirmedAt",
                          "receivedAt",
                          "readAt",
                          "playedAt",
                          "failedAt",
                          "failureReason"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "scheduled-messages.list"
      },
      "post": {
        "tags": [
          "Scheduled Messages"
        ],
        "summary": "Schedule message",
        "description": "Send a message via WhatsApp. The body is a FLAT object — set the `type` field to one of `text`, `media`, or `poll`; `type` selects which top-level fields are relevant.\n\n**Variants:**\n\n- `type: \"text\"` — required `text` (1–4096 chars). A rich link-preview card is attached automatically when the text contains a URL. Example body:\n  ```json\n  {\"type\":\"text\",\"to\":\"+15551234567\",\"text\":\"hello\"}\n  ```\n- `type: \"media\"` — provide the media as `mediaUrl` (HTTPS) **or** `mediaBase64` (base64 / data: URL); `mediaUrl` wins if both are sent. The bytes are uploaded server-side and only a URL is sent on to the engine. Optional `mediaKind` (`image` · `video` · `audio` · `document` · `sticker` · `voice` · `gif`; auto-detected when omitted), `text` (caption), `mediaFilename`. Example:\n  ```json\n  {\"type\":\"media\",\"to\":\"+15551234567\",\"mediaUrl\":\"https://cdn.example.com/x.pdf\",\"mediaKind\":\"document\",\"mediaFilename\":\"receipt.pdf\"}\n  ```\n- `type: \"poll\"` — required `pollQuestion` and `pollOptions` (2–12 items). Optional `pollAllowMultiple` (default false). Example:\n  ```json\n  {\"type\":\"poll\",\"to\":\"+15551234567\",\"pollQuestion\":\"Pizza?\",\"pollOptions\":[\"Yes\",\"No\"]}\n  ```\n\nAll variants accept optional `sendAt` (ISO 8601 ≥10s future, ≤365d) and `replyTo` (wire `key` of a prior message to quote).\n\nSee [Sending messages](/docs/messages) for runnable Python / Node / PHP / cURL examples per variant.",
        "security": [
          {
            "BearerAuth": [
              "messages:write"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendMessageRequest"
              },
              "examples": {
                "text": {
                  "summary": "Plain text",
                  "value": {
                    "to": "+15555550100",
                    "type": "text",
                    "text": "Hello from Blueticks!"
                  }
                },
                "text_with_link": {
                  "summary": "Text with a URL (link preview auto-attached)",
                  "value": {
                    "to": "+15555550100",
                    "type": "text",
                    "text": "Check this out: https://blueticks.co"
                  }
                },
                "media_url": {
                  "summary": "Image from URL",
                  "value": {
                    "to": "+15555550100",
                    "type": "media",
                    "mediaKind": "image",
                    "mediaUrl": "https://blueticks.co/favicon.ico",
                    "text": "Our logo"
                  }
                },
                "media_document": {
                  "summary": "Document attachment",
                  "value": {
                    "to": "+15555550100",
                    "type": "media",
                    "mediaKind": "document",
                    "mediaUrl": "https://example.com/invoice.pdf",
                    "mediaFilename": "invoice.pdf"
                  }
                },
                "poll": {
                  "summary": "Poll",
                  "value": {
                    "to": "+15555550100",
                    "type": "poll",
                    "pollQuestion": "Pizza tonight?",
                    "pollOptions": [
                      "Yes",
                      "No",
                      "Maybe"
                    ]
                  }
                },
                "scheduled_text": {
                  "summary": "Scheduled text (3 hours out)",
                  "value": {
                    "to": "+15555550100",
                    "type": "text",
                    "text": "Reminder: meeting in 3 hours",
                    "sendAt": "2026-12-31T12:00:00Z"
                  }
                },
                "replyTo": {
                  "summary": "Reply quoting a prior message",
                  "value": {
                    "to": "+15555550100",
                    "type": "text",
                    "text": "Sounds good!",
                    "replyTo": "true_15555550100@c.us_3EB0ABCDEF1234567890"
                  }
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 64
            },
            "description": "Optional key for safe retries. Identical bodies with the same key return the original response; differing bodies return 409."
          }
        ],
        "responses": {
          "200": {
            "description": "Idempotency replay",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "nullable": true
                        },
                        "key": {
                          "type": "string",
                          "nullable": true
                        },
                        "to": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "media",
                            "poll"
                          ],
                          "description": "Message kind that was sent."
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaKind": {
                          "type": "string",
                          "enum": [
                            "image",
                            "video",
                            "audio",
                            "document",
                            "sticker",
                            "voice",
                            "gif"
                          ],
                          "nullable": true
                        },
                        "pollQuestion": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "confirmed",
                            "received",
                            "read",
                            "played",
                            "failed"
                          ]
                        },
                        "sendAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "confirmedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "readAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "playedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failureReason": {
                          "type": "string",
                          "nullable": true
                        },
                        "linkPreview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonicalUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonicalUrl",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "to",
                        "type",
                        "text",
                        "mediaUrl",
                        "mediaKind",
                        "pollQuestion",
                        "status",
                        "sendAt",
                        "createdAt",
                        "confirmedAt",
                        "receivedAt",
                        "readAt",
                        "playedAt",
                        "failedAt",
                        "failureReason"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "nullable": true
                        },
                        "key": {
                          "type": "string",
                          "nullable": true
                        },
                        "to": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "media",
                            "poll"
                          ],
                          "description": "Message kind that was sent."
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaKind": {
                          "type": "string",
                          "enum": [
                            "image",
                            "video",
                            "audio",
                            "document",
                            "sticker",
                            "voice",
                            "gif"
                          ],
                          "nullable": true
                        },
                        "pollQuestion": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "confirmed",
                            "received",
                            "read",
                            "played",
                            "failed"
                          ]
                        },
                        "sendAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "confirmedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "readAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "playedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failureReason": {
                          "type": "string",
                          "nullable": true
                        },
                        "linkPreview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonicalUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonicalUrl",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "to",
                        "type",
                        "text",
                        "mediaUrl",
                        "mediaKind",
                        "pollQuestion",
                        "status",
                        "sendAt",
                        "createdAt",
                        "confirmedAt",
                        "receivedAt",
                        "readAt",
                        "playedAt",
                        "failedAt",
                        "failureReason"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "scheduled-messages.create"
      }
    },
    "/v1/scheduled-messages/{id}": {
      "get": {
        "tags": [
          "Scheduled Messages"
        ],
        "summary": "Get scheduled message",
        "description": "Get the current status of a message by ID.",
        "security": [
          {
            "BearerAuth": [
              "messages:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "nullable": true
                        },
                        "key": {
                          "type": "string",
                          "nullable": true
                        },
                        "to": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "media",
                            "poll"
                          ],
                          "description": "Message kind that was sent."
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaKind": {
                          "type": "string",
                          "enum": [
                            "image",
                            "video",
                            "audio",
                            "document",
                            "sticker",
                            "voice",
                            "gif"
                          ],
                          "nullable": true
                        },
                        "pollQuestion": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "confirmed",
                            "received",
                            "read",
                            "played",
                            "failed"
                          ]
                        },
                        "sendAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "confirmedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "readAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "playedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failureReason": {
                          "type": "string",
                          "nullable": true
                        },
                        "linkPreview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonicalUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonicalUrl",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "to",
                        "type",
                        "text",
                        "mediaUrl",
                        "mediaKind",
                        "pollQuestion",
                        "status",
                        "sendAt",
                        "createdAt",
                        "confirmedAt",
                        "receivedAt",
                        "readAt",
                        "playedAt",
                        "failedAt",
                        "failureReason"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "scheduled-messages.get"
      },
      "patch": {
        "tags": [
          "Scheduled Messages"
        ],
        "summary": "Update scheduled message",
        "description": "Edit a previously-queued message that has not dispatched yet. Accepts a subset of `text`, `mediaUrl`, `mediaCaption`, `sendAt` — at least one is required. Returns 400 once the message has advanced past the editable window (status not in `pending`/`sending`).",
        "security": [
          {
            "BearerAuth": [
              "messages:write"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096,
                    "description": "New text body. Replaces the previous text/caption."
                  },
                  "mediaUrl": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "Replace the attached media URL (https only)."
                  },
                  "mediaCaption": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1024,
                    "description": "Replace the media's caption. When set alongside `text`, `text` wins."
                  },
                  "sendAt": {
                    "type": "string",
                    "format": "date-time",
                    "description": "Reschedule. ISO 8601 datetime (UTC) in the future."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "nullable": true
                        },
                        "key": {
                          "type": "string",
                          "nullable": true
                        },
                        "to": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "media",
                            "poll"
                          ],
                          "description": "Message kind that was sent."
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaKind": {
                          "type": "string",
                          "enum": [
                            "image",
                            "video",
                            "audio",
                            "document",
                            "sticker",
                            "voice",
                            "gif"
                          ],
                          "nullable": true
                        },
                        "pollQuestion": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "confirmed",
                            "received",
                            "read",
                            "played",
                            "failed"
                          ]
                        },
                        "sendAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "confirmedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "readAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "playedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failureReason": {
                          "type": "string",
                          "nullable": true
                        },
                        "linkPreview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonicalUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonicalUrl",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "to",
                        "type",
                        "text",
                        "mediaUrl",
                        "mediaKind",
                        "pollQuestion",
                        "status",
                        "sendAt",
                        "createdAt",
                        "confirmedAt",
                        "receivedAt",
                        "readAt",
                        "playedAt",
                        "failedAt",
                        "failureReason"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "scheduled-messages.update"
      }
    },
    "/v1/webhooks": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "List webhooks",
        "description": "List webhooks in the workspace.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (default 50, max 200)."
          }
        ],
        "responses": {
          "200": {
            "description": "list",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "url": {
                            "type": "string"
                          },
                          "events": {
                            "type": "array",
                            "items": {
                              "type": "string"
                            }
                          },
                          "description": {
                            "type": "string",
                            "nullable": true
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "enabled",
                              "disabled"
                            ]
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "url",
                          "events",
                          "description",
                          "status",
                          "created_at"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "webhooks.list"
      },
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Create webhook",
        "description": "Register a new webhook. Returns the signing secret exactly once.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:write"
            ]
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "message.queued",
                        "message.sending",
                        "message.delivered",
                        "message.failed",
                        "message.read",
                        "session.connected",
                        "session.disconnected",
                        "campaign.started",
                        "campaign.paused",
                        "campaign.resumed",
                        "campaign.completed",
                        "campaign.aborted",
                        "new_message_received_webhook",
                        "message_reaction_webhook",
                        "ack_changed_webhook",
                        "participant_joined_via_link_webhook",
                        "participant_added_by_admin_webhook",
                        "participant_left_group_webhook",
                        "participant_kicked_from_group_webhook",
                        "group_admin_changed_webhook",
                        "group_name_changed_webhook",
                        "group_description_changed_webhook",
                        "group_message_pinned_webhook",
                        "poll_vote_webhook",
                        "reply_to_my_message_webhook",
                        "message_deleted_revoked_webhook",
                        "message_edited_webhook"
                      ]
                    },
                    "minItems": 1
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 120
                  }
                },
                "required": [
                  "url",
                  "events"
                ],
                "additionalProperties": false
              },
              "examples": {
                "delivery_status": {
                  "summary": "Subscribe to delivery lifecycle events",
                  "value": {
                    "url": "https://example.com/webhooks/blueticks",
                    "events": [
                      "message.queued",
                      "message.sending",
                      "message.delivered",
                      "message.read",
                      "message.failed"
                    ],
                    "description": "Delivery lifecycle stream"
                  }
                },
                "inbound_messages": {
                  "summary": "Receive inbound messages",
                  "value": {
                    "url": "https://example.com/webhooks/inbound",
                    "events": [
                      "new_message_received_webhook"
                    ],
                    "description": "Inbound message stream"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "enabled",
                            "disabled"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "secret": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "url",
                        "events",
                        "description",
                        "status",
                        "created_at",
                        "secret"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "webhooks.create"
      }
    },
    "/v1/webhooks/{id}": {
      "get": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Get webhook",
        "description": "Get a webhook by id.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "webhook",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "enabled",
                            "disabled"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "url",
                        "events",
                        "description",
                        "status",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "webhooks.get"
      },
      "patch": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Update webhook",
        "description": "Update a webhook.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "message.queued",
                        "message.sending",
                        "message.delivered",
                        "message.failed",
                        "message.read",
                        "session.connected",
                        "session.disconnected",
                        "campaign.started",
                        "campaign.paused",
                        "campaign.resumed",
                        "campaign.completed",
                        "campaign.aborted",
                        "new_message_received_webhook",
                        "message_reaction_webhook",
                        "ack_changed_webhook",
                        "participant_joined_via_link_webhook",
                        "participant_added_by_admin_webhook",
                        "participant_left_group_webhook",
                        "participant_kicked_from_group_webhook",
                        "group_admin_changed_webhook",
                        "group_name_changed_webhook",
                        "group_description_changed_webhook",
                        "group_message_pinned_webhook",
                        "poll_vote_webhook",
                        "reply_to_my_message_webhook",
                        "message_deleted_revoked_webhook",
                        "message_edited_webhook"
                      ]
                    },
                    "minItems": 1
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 120,
                    "nullable": true
                  },
                  "status": {
                    "type": "string",
                    "enum": [
                      "enabled",
                      "disabled"
                    ]
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "enabled",
                            "disabled"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "url",
                        "events",
                        "description",
                        "status",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "webhooks.update"
      },
      "delete": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Delete webhook",
        "description": "Delete a webhook.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "deleted"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "webhooks.delete"
      }
    },
    "/v1/audiences": {
      "get": {
        "tags": [
          "Audiences"
        ],
        "summary": "List audiences",
        "description": "List the audiences in your workspace, newest first. Offset-paginated via `limit` + `skip`. Requires `audiences:read`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (default 50, max 200)."
          }
        ],
        "responses": {
          "200": {
            "description": "audiences",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "contact_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "contact_count",
                          "created_at"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.list"
      },
      "post": {
        "tags": [
          "Audiences"
        ],
        "summary": "Create audience",
        "description": "Create a new audience. Returns the audience with `contact_count: 0`. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  },
                  "contacts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "to": {
                          "type": "string",
                          "description": "Recipient. Either a phone number in international format (e.g. +14155551234) or a WhatsApp JID (e.g. 14155551234@c.us). Stored in international format."
                        },
                        "variables": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string",
                            "maxLength": 1024
                          },
                          "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
                        }
                      },
                      "required": [
                        "to"
                      ],
                      "additionalProperties": false
                    },
                    "maxItems": 1000
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              },
              "examples": {
                "empty": {
                  "summary": "Empty audience (add contacts later)",
                  "value": {
                    "name": "Q4 Newsletter Recipients"
                  }
                },
                "with_contacts": {
                  "summary": "Audience seeded with contacts and variables",
                  "value": {
                    "name": "Q4 Newsletter Recipients",
                    "contacts": [
                      {
                        "to": "+15555550100",
                        "variables": {
                          "firstname": "Alex",
                          "plan": "pro"
                        }
                      },
                      {
                        "to": "+15555550101",
                        "variables": {
                          "firstname": "Sam",
                          "plan": "free"
                        }
                      }
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "contact_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "contact_count",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.create"
      }
    },
    "/v1/audiences/{id}": {
      "get": {
        "tags": [
          "Audiences"
        ],
        "summary": "Get audience",
        "description": "Retrieve a single audience by id, including its `contact_count` and variable schema. Requires `audiences:read`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "audience",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "contact_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "contact_count",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "audiences.get"
      },
      "patch": {
        "tags": [
          "Audiences"
        ],
        "summary": "Update audience",
        "description": "Rename an audience or update its variable schema. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "contact_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "contact_count",
                        "created_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.update"
      },
      "delete": {
        "tags": [
          "Audiences"
        ],
        "summary": "Delete audience",
        "description": "Soft-delete an audience. 409 if it`s referenced by an active campaign. Returns the deleted ref. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "deleted": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "id",
                        "deleted"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.delete"
      }
    },
    "/v1/campaigns": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "summary": "List campaigns",
        "description": "List the campaigns in your workspace, newest first, each with its live counters (`sent_count`, `delivered_count`, `read_count`, `failed_count`). Offset-paginated via `limit` + `skip`. Requires `campaigns:read`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (default 50, max 200)."
          }
        ],
        "responses": {
          "200": {
            "description": "campaigns",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "audience_id": {
                            "type": "string"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "pending",
                              "running",
                              "paused",
                              "complete_sent",
                              "complete_delivered",
                              "aborted"
                            ]
                          },
                          "total_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "sent_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "delivered_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "read_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "failed_count": {
                            "type": "integer",
                            "minimum": 0
                          },
                          "from": {
                            "type": "string",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time"
                          },
                          "started_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "completed_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "aborted_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "audience_id",
                          "status",
                          "total_count",
                          "sent_count",
                          "delivered_count",
                          "read_count",
                          "failed_count",
                          "from",
                          "created_at",
                          "started_at",
                          "completed_at",
                          "aborted_at"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "campaigns.list"
      },
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Create campaign",
        "description": "Schedule a new bulk-message campaign. Returns the campaign in `pending` state. Requires `campaigns:write`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 120,
                    "description": "Display name for the campaign."
                  },
                  "audience_id": {
                    "type": "string",
                    "minLength": 1,
                    "description": "ID of the audience to target. Each audience contact contributes one outgoing message."
                  },
                  "text": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 4096,
                    "description": "Message body. Supports per-contact substitution using single-brace tokens like `{firstName}` or `{product}`.\nResolution rules (case-insensitive, whitespace stripped):\n  - Built-ins always available: `{whatsappname}` (WA profile name), `{displayname}` (firstname+lastname fallback), `{phone}` / `{mobile}`.\n  - Custom variables: every property attached to a contact via audiences.append_contacts becomes a token of the same name.\n  - Unresolved tokens are left as literal `{token}` in the sent message.\nTemplates use SINGLE braces `{var}` — `{{var}}` is treated as literal text."
                  },
                  "media_url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048,
                    "description": "Public https URL of an image/video/document to attach."
                  },
                  "media_caption": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 1024,
                    "description": "Caption for the media attachment. Requires media_url."
                  },
                  "from": {
                    "type": "string",
                    "pattern": "^\\+[1-9]\\d{6,14}$",
                    "description": "Sender phone in international format (e.g. +14155551234). When omitted, the workspace default sender is used."
                  },
                  "on_missing_variable": {
                    "type": "string",
                    "enum": [
                      "fail",
                      "skip"
                    ],
                    "description": "Behavior when a template references a variable that is not present on a contact:\n  - `fail` (default): reject the request at create time; no messages are sent. Returns 400 with `data.examples` listing offending contacts.\n  - `skip`: accept the campaign; contacts missing variables receive the message with literal `{token}` left in place."
                  }
                },
                "required": [
                  "name",
                  "audience_id"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "audience_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "running",
                            "paused",
                            "complete_sent",
                            "complete_delivered",
                            "aborted"
                          ]
                        },
                        "total_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "sent_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "delivered_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "read_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "failed_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "from": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "started_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "completed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "aborted_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "audience_id",
                        "status",
                        "total_count",
                        "sent_count",
                        "delivered_count",
                        "read_count",
                        "failed_count",
                        "from",
                        "created_at",
                        "started_at",
                        "completed_at",
                        "aborted_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "campaigns.create"
      }
    },
    "/v1/campaigns/{id}": {
      "get": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Get campaign",
        "description": "Retrieve a single campaign by id, including its status and live delivery counters. Poll this to track progress. Requires `campaigns:read`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "campaign",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "audience_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "running",
                            "paused",
                            "complete_sent",
                            "complete_delivered",
                            "aborted"
                          ]
                        },
                        "total_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "sent_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "delivered_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "read_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "failed_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "from": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "started_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "completed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "aborted_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "audience_id",
                        "status",
                        "total_count",
                        "sent_count",
                        "delivered_count",
                        "read_count",
                        "failed_count",
                        "from",
                        "created_at",
                        "started_at",
                        "completed_at",
                        "aborted_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "campaigns.get"
      }
    },
    "/v1/chats": {
      "get": {
        "tags": [
          "Chats"
        ],
        "summary": "List chats",
        "description": "List the chats (conversations) the connected WhatsApp engine sees, most-recent first. Offset-paginated via `limit` + `skip`, with an optional case-insensitive substring search on the chat name via `searchToken` and a `filter` to restrict to one chat kind. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search token; when set, only items whose name matches are returned."
          },
          {
            "name": "filter",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "groups",
                "contacts",
                "newsletters"
              ]
            },
            "description": "Restrict to one chat kind."
          },
          {
            "name": "include_last_message",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include the last message snippet on each chat row."
          },
          {
            "name": "include_extended_info",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include extended chat metadata (engine-side opt-in)."
          },
          {
            "name": "include_without_name",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include chats with no resolved name (default: skipped)."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (1-200, default 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "chats",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_group": {
                            "type": "boolean"
                          },
                          "is_newsletter": {
                            "type": "boolean"
                          },
                          "last_message_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "unread_count": {
                            "type": "integer",
                            "minimum": 0,
                            "nullable": true
                          },
                          "marked_unread": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "is_group",
                          "is_newsletter",
                          "last_message_at",
                          "unread_count",
                          "marked_unread"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "chats.list"
      }
    },
    "/v1/chats/{id}": {
      "get": {
        "tags": [
          "Chats"
        ],
        "summary": "Get chat",
        "description": "Retrieve a single chat by its id — a phone number in international format (e.g. +14155551234) or a WhatsApp JID (`@c.us`, `@g.us`, or `@newsletter`). Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "chat",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "is_group": {
                          "type": "boolean"
                        },
                        "is_newsletter": {
                          "type": "boolean"
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "unread_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "marked_unread": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "is_group",
                        "is_newsletter",
                        "last_message_at",
                        "unread_count",
                        "marked_unread"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "chats.get"
      }
    },
    "/v1/groups": {
      "get": {
        "tags": [
          "Groups"
        ],
        "summary": "List groups",
        "description": "List the groups the connected WhatsApp engine sees. Supports offset pagination (`limit`+`skip`) and an optional case-insensitive substring search on the group name via `searchToken`.",
        "security": [
          {
            "BearerAuth": [
              "groups:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 128
            },
            "description": "Search token; when set, only items whose name matches are returned."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (1-200, default 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "groups",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string",
                            "nullable": true
                          },
                          "description": {
                            "type": "string",
                            "nullable": true
                          },
                          "owner": {
                            "type": "string",
                            "nullable": true
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "last_message_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "participant_count": {
                            "type": "integer",
                            "minimum": 0,
                            "nullable": true
                          },
                          "announce": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "restrict": {
                            "type": "boolean",
                            "nullable": true
                          },
                          "participants": {
                            "type": "array",
                            "items": {
                              "type": "object",
                              "properties": {
                                "chat_id": {
                                  "type": "string"
                                },
                                "is_admin": {
                                  "type": "boolean"
                                },
                                "is_super_admin": {
                                  "type": "boolean"
                                },
                                "name": {
                                  "type": "string",
                                  "nullable": true
                                }
                              },
                              "required": [
                                "chat_id",
                                "is_admin",
                                "is_super_admin",
                                "name"
                              ],
                              "additionalProperties": false
                            },
                            "nullable": true
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "owner",
                          "created_at",
                          "last_message_at",
                          "participant_count",
                          "announce",
                          "restrict",
                          "participants"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.list"
      },
      "post": {
        "tags": [
          "Groups"
        ],
        "summary": "Create group",
        "description": "Create a WhatsApp group with the given name and initial participants. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "participants": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 256
                  }
                },
                "required": [
                  "name",
                  "participants"
                ],
                "additionalProperties": false
              },
              "examples": {
                "basic": {
                  "summary": "Two-member group",
                  "value": {
                    "name": "Q4 Planning",
                    "participants": [
                      "+15555550100",
                      "+15555550101"
                    ]
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.create"
      }
    },
    "/v1/groups/{id}": {
      "get": {
        "tags": [
          "Groups"
        ],
        "summary": "Get group",
        "description": "Retrieve a single group by its `@g.us` id, including its subject, description, and participant list. Requires `groups:read`.",
        "security": [
          {
            "BearerAuth": [
              "groups:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "operationId": "groups.get"
      },
      "patch": {
        "tags": [
          "Groups"
        ],
        "summary": "Update group",
        "description": "Update group metadata. Provide at least one of `name` or `settings`. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "settings": {
                    "type": "object",
                    "properties": {
                      "announce": {
                        "type": "boolean"
                      },
                      "restrict": {
                        "type": "boolean"
                      },
                      "edit_info_admins_only": {
                        "type": "boolean"
                      }
                    },
                    "additionalProperties": false
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.update"
      }
    },
    "/v1/newsletters": {
      "get": {
        "tags": [
          "Newsletters"
        ],
        "summary": "List newsletters",
        "description": "List newsletters visible to the connected WhatsApp engine. Offset-paginated via `limit` + `skip`. Requires `newsletters:read` scope.",
        "security": [
          {
            "BearerAuth": [
              "newsletters:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search token; when set, only newsletters whose name matches (case-insensitive substring) are returned, and `total` reflects the matched count."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of items to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Page size (1-200, default 50)."
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string",
                            "description": "Newsletter JID, e.g. 120363201733549020@newsletter."
                          },
                          "name": {
                            "type": "string",
                            "description": "Display name of the newsletter / WhatsApp channel."
                          },
                          "description": {
                            "type": "string",
                            "nullable": true,
                            "description": "Optional description."
                          },
                          "owner": {
                            "type": "string",
                            "nullable": true,
                            "description": "Owner JID, if returned by the engine."
                          },
                          "created_at": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "subscribers": {
                            "type": "integer",
                            "minimum": 0,
                            "nullable": true
                          },
                          "invite": {
                            "type": "string",
                            "nullable": true,
                            "description": "Invite code (suffix of https://whatsapp.com/channel/<invite>)."
                          },
                          "verification": {
                            "type": "string",
                            "enum": [
                              "VERIFIED",
                              "UNVERIFIED"
                            ],
                            "nullable": true
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "description",
                          "owner",
                          "created_at",
                          "subscribers",
                          "invite",
                          "verification"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "newsletters.list"
      },
      "post": {
        "tags": [
          "Newsletters"
        ],
        "summary": "Create newsletter",
        "description": "Create a new WhatsApp newsletter (channel). Requires `messages:write` scope (newsletter creation shares the messages write budget).",
        "security": [
          {
            "BearerAuth": [
              "messages:write"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 100
                  },
                  "description": {
                    "type": "string",
                    "maxLength": 2048
                  }
                },
                "required": [
                  "name"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Newsletter JID, e.g. 120363201733549020@newsletter."
                        },
                        "name": {
                          "type": "string",
                          "description": "Display name of the newsletter / WhatsApp channel."
                        },
                        "description": {
                          "type": "string",
                          "nullable": true,
                          "description": "Optional description."
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true,
                          "description": "Owner JID, if returned by the engine."
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "subscribers": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "invite": {
                          "type": "string",
                          "nullable": true,
                          "description": "Invite code (suffix of https://whatsapp.com/channel/<invite>)."
                        },
                        "verification": {
                          "type": "string",
                          "enum": [
                            "VERIFIED",
                            "UNVERIFIED"
                          ],
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "subscribers",
                        "invite",
                        "verification"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "newsletters.create"
      }
    },
    "/v1/newsletters/{id}": {
      "get": {
        "tags": [
          "Newsletters"
        ],
        "summary": "Get newsletter",
        "description": "Retrieve a newsletter by its JID. Requires `newsletters:read` scope.",
        "security": [
          {
            "BearerAuth": [
              "newsletters:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^\\d+@newsletter$"
            },
            "description": "Newsletter JID, e.g. 12345@newsletter."
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "description": "Newsletter JID, e.g. 120363201733549020@newsletter."
                        },
                        "name": {
                          "type": "string",
                          "description": "Display name of the newsletter / WhatsApp channel."
                        },
                        "description": {
                          "type": "string",
                          "nullable": true,
                          "description": "Optional description."
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true,
                          "description": "Owner JID, if returned by the engine."
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "subscribers": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "invite": {
                          "type": "string",
                          "nullable": true,
                          "description": "Invite code (suffix of https://whatsapp.com/channel/<invite>)."
                        },
                        "verification": {
                          "type": "string",
                          "enum": [
                            "VERIFIED",
                            "UNVERIFIED"
                          ],
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "subscribers",
                        "invite",
                        "verification"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "newsletters.get"
      }
    },
    "/v1/contacts": {
      "get": {
        "tags": [
          "Contacts"
        ],
        "summary": "List contacts",
        "description": "List your workspace contact book — everyone the connected WhatsApp account has messaged. Offset-paginated via `limit` + `skip`. Requires `contacts:read`.",
        "security": [
          {
            "BearerAuth": [
              "contacts:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search token; when set, only items whose name matches are returned."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Number of contacts to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer"
            },
            "description": "Page size (default 10, max 200). Pass `-1` to return every contact in a single page."
          }
        ],
        "responses": {
          "200": {
            "description": "contacts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "chat_id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string",
                            "nullable": true
                          },
                          "is_business": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "chat_id"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "contacts.list"
      }
    },
    "/v1/engines": {
      "get": {
        "tags": [
          "Engines"
        ],
        "summary": "List engines",
        "description": "List engines connected to this workspace. Returns an array (currently up to one entry, but the response shape leaves room for multi-engine workspaces). When no engine is connected, `data` is empty and `message` explains why — this is not an error.",
        "security": [
          {
            "BearerAuth": [
              "engines:read"
            ]
          }
        ],
        "responses": {
          "200": {
            "description": "success",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "data": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "connected": {
                                "type": "boolean",
                                "description": "Whether this engine is currently online and serving requests."
                              },
                              "state": {
                                "type": "string",
                                "nullable": true,
                                "description": "Engine-side connection state (e.g. CONNECTED, OPENING, PAIRING). Null when unknown."
                              },
                              "stream": {
                                "type": "string",
                                "nullable": true,
                                "description": "Underlying WA stream state. Null when unknown."
                              },
                              "has_synced": {
                                "type": "boolean",
                                "nullable": true,
                                "description": "Whether the engine has completed its initial history sync."
                              }
                            },
                            "required": [
                              "connected",
                              "state",
                              "stream",
                              "has_synced"
                            ],
                            "additionalProperties": false
                          },
                          "description": "Engines connected to this workspace. Empty when no engine is paired."
                        },
                        "message": {
                          "type": "string",
                          "description": "Human-readable note (e.g. why the array is empty). Present only when useful."
                        }
                      },
                      "required": [
                        "data"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "engines.list"
      }
    },
    "/v1/webhooks/{id}/rotate-secret": {
      "post": {
        "tags": [
          "Webhooks"
        ],
        "summary": "Rotate webhook secret",
        "description": "Rotate the signing secret. Returns the new secret exactly once. Requires `webhooks:write` scope.",
        "security": [
          {
            "BearerAuth": [
              "webhooks:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "new secret",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "url": {
                          "type": "string"
                        },
                        "events": {
                          "type": "array",
                          "items": {
                            "type": "string"
                          }
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "enabled",
                            "disabled"
                          ]
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "secret": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id",
                        "url",
                        "events",
                        "description",
                        "status",
                        "created_at",
                        "secret"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "webhooks.rotatesecret.create"
      }
    },
    "/v1/audiences/{id}/contacts": {
      "post": {
        "tags": [
          "Audiences"
        ],
        "summary": "Append contacts to audience",
        "description": "Append contacts to an audience. Duplicates (by `to`) are skipped. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "contacts": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "properties": {
                        "to": {
                          "type": "string",
                          "description": "Recipient. Either a phone number in international format (e.g. +14155551234) or a WhatsApp JID (e.g. 14155551234@c.us). Stored in international format."
                        },
                        "variables": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string",
                            "maxLength": 1024
                          },
                          "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
                        }
                      },
                      "required": [
                        "to"
                      ],
                      "additionalProperties": false
                    },
                    "minItems": 1,
                    "maxItems": 1000
                  }
                },
                "required": [
                  "contacts"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "appended",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "added": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "contact_count": {
                          "type": "integer",
                          "minimum": 0
                        }
                      },
                      "required": [
                        "added",
                        "contact_count"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.contacts.create"
      }
    },
    "/v1/audiences/{id}/contacts/{contactId}": {
      "patch": {
        "tags": [
          "Audiences"
        ],
        "summary": "Update audience contact",
        "description": "Edit a contact`s phone or variables. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "to": {
                    "type": "string"
                  },
                  "variables": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "maxLength": 1024
                    },
                    "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "to": {
                          "type": "string"
                        },
                        "variables": {
                          "type": "object",
                          "additionalProperties": {
                            "type": "string"
                          }
                        },
                        "added_at": {
                          "type": "string",
                          "format": "date-time"
                        }
                      },
                      "required": [
                        "id",
                        "to",
                        "variables",
                        "added_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.contacts.update"
      },
      "delete": {
        "tags": [
          "Audiences"
        ],
        "summary": "Remove audience contact",
        "description": "Remove a contact from an audience. Requires `audiences:write`.",
        "security": [
          {
            "BearerAuth": [
              "audiences:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "contactId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "deleted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "id"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "audiences.contacts.delete"
      }
    },
    "/v1/campaigns/{id}/pause": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Pause campaign",
        "description": "Pause a running campaign. 409 if not `running`. Requires `campaigns:write`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "paused",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "audience_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "running",
                            "paused",
                            "complete_sent",
                            "complete_delivered",
                            "aborted"
                          ]
                        },
                        "total_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "sent_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "delivered_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "read_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "failed_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "from": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "started_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "completed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "aborted_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "audience_id",
                        "status",
                        "total_count",
                        "sent_count",
                        "delivered_count",
                        "read_count",
                        "failed_count",
                        "from",
                        "created_at",
                        "started_at",
                        "completed_at",
                        "aborted_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "campaigns.pause.create"
      }
    },
    "/v1/campaigns/{id}/resume": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Resume campaign",
        "description": "Resume a paused campaign. 409 if not `paused`. Requires `campaigns:write`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "resumed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "audience_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "running",
                            "paused",
                            "complete_sent",
                            "complete_delivered",
                            "aborted"
                          ]
                        },
                        "total_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "sent_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "delivered_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "read_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "failed_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "from": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "started_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "completed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "aborted_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "audience_id",
                        "status",
                        "total_count",
                        "sent_count",
                        "delivered_count",
                        "read_count",
                        "failed_count",
                        "from",
                        "created_at",
                        "started_at",
                        "completed_at",
                        "aborted_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "campaigns.resume.create"
      }
    },
    "/v1/campaigns/{id}/cancel": {
      "post": {
        "tags": [
          "Campaigns"
        ],
        "summary": "Cancel campaign",
        "description": "Cancel a campaign. 409 if already terminal. Requires `campaigns:write`.",
        "security": [
          {
            "BearerAuth": [
              "campaigns:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "aborted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string"
                        },
                        "audience_id": {
                          "type": "string"
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "running",
                            "paused",
                            "complete_sent",
                            "complete_delivered",
                            "aborted"
                          ]
                        },
                        "total_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "sent_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "delivered_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "read_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "failed_count": {
                          "type": "integer",
                          "minimum": 0
                        },
                        "from": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "started_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "completed_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "aborted_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "audience_id",
                        "status",
                        "total_count",
                        "sent_count",
                        "delivered_count",
                        "read_count",
                        "failed_count",
                        "from",
                        "created_at",
                        "started_at",
                        "completed_at",
                        "aborted_at"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "campaigns.cancel.create"
      }
    },
    "/v1/messages": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "List messages (all chats)",
        "description": "Offset-paginated list of messages across the whole account. Pass `chatId` to scope to a single chat, or omit it to search across all chats. Supports free-text search (`searchToken`), date range (`since`/`until`), and message-kind filtering (`messageTypes`). Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "pattern": "^\\d+(?:-\\d+)?@(?:c\\.us|s\\.whatsapp\\.net|g\\.us|lid|broadcast|newsletter)$"
            },
            "description": "Optional WhatsApp JID to scope results to a single chat. Omit to search across all chats."
          },
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search token; when set, only items whose name matches are returned."
          },
          {
            "name": "order",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "enum": [
                "asc",
                "desc"
              ]
            },
            "description": "Result ordering. asc = oldest-first; desc = newest-first (default)."
          },
          {
            "name": "since",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Lower bound (ISO 8601). Only messages with timestamp >= since."
          },
          {
            "name": "until",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "format": "date-time"
            },
            "description": "Upper bound (ISO 8601). Only messages with timestamp <= until."
          },
          {
            "name": "messageTypes",
            "in": "query",
            "required": false,
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "enum": [
                  "chat",
                  "image",
                  "video",
                  "document",
                  "audio",
                  "ptt",
                  "sticker",
                  "gif",
                  "ptv",
                  "poll_creation",
                  "location",
                  "vcard",
                  "revoked"
                ]
              }
            },
            "description": "Filter to specific message kinds. Comma-separated or repeated. Useful for \"all PDFs\" (`document`) or \"images today\" (`image`). System events (gp2/revoked/newsletter_notification) are excluded by default unless explicitly listed here.",
            "style": "form",
            "explode": false
          },
          {
            "name": "loadFromPhoneIfNeeded",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "When the local store is exhausted, fetch older messages from the phone (chrome only)."
          },
          {
            "name": "includeMediaContent",
            "in": "query",
            "required": false,
            "schema": {
              "type": "boolean"
            },
            "description": "Include inline media payload on rows (heavy; default false — use /messages/{key}/media)."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of messages to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 200,
              "default": 50
            },
            "description": "Max messages to return."
          }
        ],
        "responses": {
          "200": {
            "description": "messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "chat_id": {
                            "type": "string"
                          },
                          "from": {
                            "type": "string"
                          },
                          "author": {
                            "type": "string",
                            "nullable": true
                          },
                          "timestamp": {
                            "type": "string",
                            "format": "date-time",
                            "nullable": true
                          },
                          "text": {
                            "type": "string",
                            "nullable": true
                          },
                          "type": {
                            "type": "string"
                          },
                          "from_me": {
                            "type": "boolean"
                          },
                          "ack": {
                            "type": "integer",
                            "nullable": true
                          },
                          "media_url": {
                            "type": "string",
                            "nullable": true
                          },
                          "caption": {
                            "type": "string",
                            "nullable": true
                          },
                          "filename": {
                            "type": "string",
                            "nullable": true
                          },
                          "link_preview": {
                            "type": "object",
                            "properties": {
                              "title": {
                                "type": "string",
                                "nullable": true
                              },
                              "description": {
                                "type": "string",
                                "nullable": true
                              },
                              "canonical_url": {
                                "type": "string",
                                "nullable": true
                              },
                              "thumbnail": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "title",
                              "description",
                              "canonical_url",
                              "thumbnail"
                            ],
                            "additionalProperties": false,
                            "nullable": true
                          }
                        },
                        "required": [
                          "key",
                          "chat_id",
                          "from",
                          "timestamp",
                          "text",
                          "type",
                          "from_me",
                          "ack",
                          "media_url",
                          "caption",
                          "filename"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.list"
      }
    },
    "/v1/messages/{chat_id}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Send message",
        "description": "Send a message immediately to a specific chat. The body is the same FLAT shape as `POST /v1/scheduled-messages` minus `to` (derived from the URL path) and `sendAt` (this endpoint is fire-and-forget). Set `type` to `text`, `media`, or `poll`. The dispatch is direct — no DB row is created; the response carries the WhatsApp wire key under `key`. For scheduled or queue-managed sends use `POST /v1/scheduled-messages` instead. Requires `messages:write`.\n\n### Sending media (`type: \"media\"`)\n\nProvide the media **one** of these ways:\n\n- **`mediaUrl`** — a public `https://` URL to the file.\n- **`mediaBase64`** — the file bytes base64-encoded (or a `data:` URL), inline in the JSON body.\n- **Upload a file** — send the request as `multipart/form-data` with the file in a **`mediaFile`** part. See the cURL example below.\n\nIf both `mediaUrl` and `mediaBase64` are present, `mediaUrl` wins. Optional: `mediaFilename` (display name) and `mediaKind` (`image` · `video` · `audio` · `document` · `sticker` · `voice` · `gif`; auto-detected otherwise).\n\n> In the Body panel, the **Attach a file** control has a content-type dropdown next to it. Pick `application/json` to inline a small file as base64 in `mediaBase64`, or `multipart/form-data` to upload the raw file (no 10 MB JSON-body limit) — then just press **Send**. The cURL below is the multipart equivalent.\n\n```bash\ncurl -X POST \"https://api.blueticks.co/v1/messages/120363000000000000@g.us\" \\\n  -H \"Authorization: Bearer $BLUETICKS_API_KEY\" \\\n  -F \"type=media\" \\\n  -F \"text=Here is the file\" \\\n  -F \"mediaFile=@/path/to/photo.png\"\n```\n\n### Mentioning contacts\n\nMentions are written **inline in `text`** — there is no separate field. Use `@[Display Name](<jid>)`:\n\n```\nHi @[Joni Naor](972544325389@c.us) this is a test\n```",
        "security": [
          {
            "BearerAuth": [
              "messages:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "type": {
                    "type": "string",
                    "enum": [
                      "text",
                      "media",
                      "poll"
                    ]
                  },
                  "text": {
                    "type": "string",
                    "maxLength": 4096,
                    "description": "Text body (required for type=text) or optional media caption (type=media). Up to 4096 chars. Mention a contact inline with `@[Display Name](<jid>)`, e.g. `Hi @[Joni Naor](972544325389@c.us)`."
                  },
                  "mediaUrl": {
                    "type": "string",
                    "maxLength": 2048,
                    "description": "Media source URL (https only). One of mediaUrl or mediaBase64 is required for media sends; mediaUrl wins when both are present."
                  },
                  "mediaBase64": {
                    "type": "string",
                    "maxLength": 15728640,
                    "description": "Raw media bytes, base64-encoded (or a data: URL). Used when mediaUrl is absent. For a file upload, send multipart/form-data with a `mediaFile` part instead — it is converted to this."
                  },
                  "mediaKind": {
                    "type": "string",
                    "enum": [
                      "image",
                      "video",
                      "audio",
                      "document",
                      "sticker",
                      "voice",
                      "gif"
                    ],
                    "description": "Media kind (image · video · audio · document · sticker · voice · gif). Optional — auto-detected from the URL / content-type when omitted."
                  },
                  "mediaFilename": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Filename shown on the attachment (type=media). Optional — derived from the URL / uploaded file when omitted."
                  },
                  "pollQuestion": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 255,
                    "description": "Poll question (type=poll). Required for poll sends."
                  },
                  "pollOptions": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 100
                    },
                    "description": "Poll options (type=poll). 2–12 items."
                  },
                  "pollAllowMultiple": {
                    "type": "boolean",
                    "description": "Allow selecting multiple poll options (type=poll). Default false."
                  },
                  "replyTo": {
                    "type": "string",
                    "maxLength": 256,
                    "description": "Wire `key` of a prior message to quote-reply (from MessageResponse.key). Empty string = no reply."
                  },
                  "secret": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 256,
                    "description": "Opaque caller id stored on the message `secret` and carried into the WhatsApp messageSecret."
                  }
                },
                "required": [
                  "type"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "sent",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string",
                          "nullable": true
                        },
                        "key": {
                          "type": "string",
                          "nullable": true
                        },
                        "to": {
                          "type": "string"
                        },
                        "type": {
                          "type": "string",
                          "enum": [
                            "text",
                            "media",
                            "poll"
                          ],
                          "description": "Message kind that was sent."
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaUrl": {
                          "type": "string",
                          "nullable": true
                        },
                        "mediaKind": {
                          "type": "string",
                          "enum": [
                            "image",
                            "video",
                            "audio",
                            "document",
                            "sticker",
                            "voice",
                            "gif"
                          ],
                          "nullable": true
                        },
                        "pollQuestion": {
                          "type": "string",
                          "nullable": true
                        },
                        "status": {
                          "type": "string",
                          "enum": [
                            "pending",
                            "confirmed",
                            "received",
                            "read",
                            "played",
                            "failed"
                          ]
                        },
                        "sendAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "createdAt": {
                          "type": "string",
                          "format": "date-time"
                        },
                        "confirmedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "receivedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "readAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "playedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failedAt": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "failureReason": {
                          "type": "string",
                          "nullable": true
                        },
                        "linkPreview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonicalUrl": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonicalUrl",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "key",
                        "to",
                        "type",
                        "text",
                        "mediaUrl",
                        "mediaKind",
                        "pollQuestion",
                        "status",
                        "sendAt",
                        "createdAt",
                        "confirmedAt",
                        "receivedAt",
                        "readAt",
                        "playedAt",
                        "failedAt",
                        "failureReason"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.create"
      }
    },
    "/v1/messages/{waMessageKey}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Get message",
        "description": "Fetch a single message by its complete WhatsApp message key. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "waMessageKey",
            "in": "path",
            "required": true,
            "description": "The complete WhatsApp message key (`<fromMe>_<chatJid>_<id>[_<participant>]`), e.g. `false_120363426216988013@g.us_3EB0659D13650092D677AD_188450464616609@lid`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "description": "Optional. Only used to find the message faster — when you pass a bare message id instead of the complete key, `chatId` lets the server rebuild the full key. If you pass the complete `waMessageKey` you can omit it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "message",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "key": {
                          "type": "string"
                        },
                        "chat_id": {
                          "type": "string"
                        },
                        "from": {
                          "type": "string"
                        },
                        "author": {
                          "type": "string",
                          "nullable": true
                        },
                        "timestamp": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "text": {
                          "type": "string",
                          "nullable": true
                        },
                        "type": {
                          "type": "string"
                        },
                        "from_me": {
                          "type": "boolean"
                        },
                        "ack": {
                          "type": "integer",
                          "nullable": true
                        },
                        "media_url": {
                          "type": "string",
                          "nullable": true
                        },
                        "caption": {
                          "type": "string",
                          "nullable": true
                        },
                        "filename": {
                          "type": "string",
                          "nullable": true
                        },
                        "link_preview": {
                          "type": "object",
                          "properties": {
                            "title": {
                              "type": "string",
                              "nullable": true
                            },
                            "description": {
                              "type": "string",
                              "nullable": true
                            },
                            "canonical_url": {
                              "type": "string",
                              "nullable": true
                            },
                            "thumbnail": {
                              "type": "string",
                              "nullable": true
                            }
                          },
                          "required": [
                            "title",
                            "description",
                            "canonical_url",
                            "thumbnail"
                          ],
                          "additionalProperties": false,
                          "nullable": true
                        }
                      },
                      "required": [
                        "key",
                        "chat_id",
                        "from",
                        "timestamp",
                        "text",
                        "type",
                        "from_me",
                        "ack",
                        "media_url",
                        "caption",
                        "filename"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.get"
      }
    },
    "/v1/groups/{id}/members": {
      "post": {
        "tags": [
          "Groups"
        ],
        "summary": "Add member to group",
        "description": "Add a participant to the group by chat_id (JID) or phone number in international format (e.g. +14155551234). Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "chat_id": {
                    "type": "string"
                  },
                  "participants": {
                    "type": "array",
                    "items": {
                      "type": "string"
                    },
                    "minItems": 1,
                    "maxItems": 256
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "updated group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.members.create"
      }
    },
    "/v1/groups/{id}/members/me": {
      "delete": {
        "tags": [
          "Groups"
        ],
        "summary": "Leave group",
        "description": "Leave the group as the authenticated identity. Idempotent — succeeds with 204 even if already not a member. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "204": {
            "description": "left"
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.members.me.delete"
      }
    },
    "/v1/groups/{id}/members/{chatId}": {
      "delete": {
        "tags": [
          "Groups"
        ],
        "summary": "Remove member from group",
        "description": "Remove a participant from the group. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "updated group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.members.delete"
      }
    },
    "/v1/groups/{id}/members/{chatId}/admin": {
      "post": {
        "tags": [
          "Groups"
        ],
        "summary": "Promote member to admin",
        "description": "Grant admin privileges to a group member. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "updated group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.members.admin.create"
      },
      "delete": {
        "tags": [
          "Groups"
        ],
        "summary": "Demote admin to member",
        "description": "Revoke admin privileges from a group member. Requires `groups:write`.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "updated group",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.members.admin.delete"
      }
    },
    "/v1/groups/{id}/picture": {
      "put": {
        "tags": [
          "Groups"
        ],
        "summary": "Set group picture",
        "description": "Replace the group picture. Provide the image as `file_data_url` (base64 data URL, PNG/JPEG, ≤20 MiB) or `url` (https). You can also upload a file as `multipart/form-data` with a `file` part. Requires `groups:write`.\n\n> In the Body panel, the **Attach a file** control has a content-type dropdown: `application/json` inlines the file as base64 in `file_data_url`, or `multipart/form-data` uploads the raw file — then press **Send**.",
        "security": [
          {
            "BearerAuth": [
              "groups:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "file_data_url": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 20971520
                  },
                  "url": {
                    "type": "string",
                    "format": "uri",
                    "maxLength": 2048
                  },
                  "file_name": {
                    "type": "string",
                    "maxLength": 255
                  },
                  "file_mime_type": {
                    "type": "string",
                    "maxLength": 127
                  }
                },
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "picture updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "id": {
                          "type": "string"
                        },
                        "name": {
                          "type": "string",
                          "nullable": true
                        },
                        "description": {
                          "type": "string",
                          "nullable": true
                        },
                        "owner": {
                          "type": "string",
                          "nullable": true
                        },
                        "created_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "last_message_at": {
                          "type": "string",
                          "format": "date-time",
                          "nullable": true
                        },
                        "participant_count": {
                          "type": "integer",
                          "minimum": 0,
                          "nullable": true
                        },
                        "announce": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "restrict": {
                          "type": "boolean",
                          "nullable": true
                        },
                        "participants": {
                          "type": "array",
                          "items": {
                            "type": "object",
                            "properties": {
                              "chat_id": {
                                "type": "string"
                              },
                              "is_admin": {
                                "type": "boolean"
                              },
                              "is_super_admin": {
                                "type": "boolean"
                              },
                              "name": {
                                "type": "string",
                                "nullable": true
                              }
                            },
                            "required": [
                              "chat_id",
                              "is_admin",
                              "is_super_admin",
                              "name"
                            ],
                            "additionalProperties": false
                          },
                          "nullable": true
                        }
                      },
                      "required": [
                        "id",
                        "name",
                        "description",
                        "owner",
                        "created_at",
                        "last_message_at",
                        "participant_count",
                        "announce",
                        "restrict",
                        "participants"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "groups.picture.update"
      }
    },
    "/v1/chats/{chat_id}/participants": {
      "get": {
        "tags": [
          "Chats"
        ],
        "summary": "List chat participants",
        "description": "For group chats, returns the participant list (paginated). For DMs, returns the single counterparty. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "searchToken",
            "in": "query",
            "required": false,
            "schema": {
              "type": "string",
              "maxLength": 200
            },
            "description": "Search token; when set, only participants whose resolved name or phone/JID matches (case-insensitive substring) are returned, and `total` reflects the matched count."
          },
          {
            "name": "skip",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 0,
              "default": 0
            },
            "description": "Number of participants to skip before the page (default 0)."
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 500,
              "default": 100
            },
            "description": "Max participants to return."
          }
        ],
        "responses": {
          "200": {
            "description": "participants",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "chat_id": {
                            "type": "string"
                          },
                          "is_admin": {
                            "type": "boolean"
                          },
                          "is_super_admin": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "chat_id",
                          "is_admin"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "chats.participants.list"
      }
    },
    "/v1/chats/{chat_id}/mark_read": {
      "post": {
        "tags": [
          "Chats"
        ],
        "summary": "Mark chat as read",
        "description": "Clears the unread badge on the connected engine for the given chat. Requires `chats:write`.",
        "security": [
          {
            "BearerAuth": [
              "chats:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "marked read",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "ok"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "chats.markread.create"
      }
    },
    "/v1/chats/{chat_id}/open": {
      "post": {
        "tags": [
          "Chats"
        ],
        "summary": "Open chat in engine",
        "description": "Brings the chat to the foreground on the connected WhatsApp Web client (creates the chat if it doesn`t exist yet for the engine). Useful before issuing follow-up reads on a fresh JID. Requires `chats:write`.",
        "security": [
          {
            "BearerAuth": [
              "chats:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "opened",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "chat_id": {
                          "type": "string"
                        }
                      },
                      "required": [
                        "chat_id"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "chats.open.create"
      }
    },
    "/v1/messages/ack/{waMessageKey}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Get message delivery status",
        "description": "Returns the WhatsApp ack value for a sent message: -1=error, 0=pending, 1=server, 2=device, 3=read, 4=played. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "waMessageKey",
            "in": "path",
            "required": true,
            "description": "The complete WhatsApp message key (`<fromMe>_<chatJid>_<id>[_<participant>]`), e.g. `false_120363426216988013@g.us_3EB0659D13650092D677AD_188450464616609@lid`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "description": "Optional. Only used to find the message faster — when you pass a bare message id instead of the complete key, `chatId` lets the server rebuild the full key. If you pass the complete `waMessageKey` you can omit it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "ack",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ack": {
                          "type": "integer",
                          "nullable": true,
                          "description": "-1=error, 0=pending, 1=server, 2=device, 3=read, 4=played; null when no engine response."
                        }
                      },
                      "required": [
                        "ack"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.ack.get"
      }
    },
    "/v1/messages/reactions/{waMessageKey}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "React to message",
        "description": "Add or replace your reaction to a message. Pass an empty `emoji` string to remove. Requires `chats:write`.",
        "security": [
          {
            "BearerAuth": [
              "chats:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "waMessageKey",
            "in": "path",
            "required": true,
            "description": "The complete WhatsApp message key (`<fromMe>_<chatJid>_<id>[_<participant>]`), e.g. `false_120363426216988013@g.us_3EB0659D13650092D677AD_188450464616609@lid`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "description": "Optional. Only used to find the message faster — when you pass a bare message id instead of the complete key, `chatId` lets the server rebuild the full key. If you pass the complete `waMessageKey` you can omit it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "emoji": {
                    "type": "string",
                    "minLength": 0,
                    "maxLength": 32
                  }
                },
                "required": [
                  "emoji"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "reaction set",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "ok": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "ok"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.reactions.create"
      }
    },
    "/v1/messages/load_older/{chat_id}": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Load older messages",
        "description": "Asks the engine to pull older history from the connected phone for chats that haven`t been fully synced yet. Use this once before paginating with `since` if you need messages older than what`s already cached. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "load result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "total_messages": {
                          "type": "integer",
                          "nullable": true
                        },
                        "added": {
                          "type": "integer",
                          "nullable": true
                        },
                        "can_load_more": {
                          "type": "boolean"
                        }
                      },
                      "required": [
                        "total_messages",
                        "added",
                        "can_load_more"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.loadolder.create"
      }
    },
    "/v1/messages/media_url/{waMessageKey}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Get message media URL",
        "description": "Returns a hosted URL for the message media without inlining bytes. Faster + cheaper than `media` when the caller can fetch the URL themselves. Same `media_unavailable` semantics. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "waMessageKey",
            "in": "path",
            "required": true,
            "description": "The complete WhatsApp message key (`<fromMe>_<chatJid>_<id>[_<participant>]`), e.g. `false_120363426216988013@g.us_3EB0659D13650092D677AD_188450464616609@lid`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "description": "Optional. Only used to find the message faster — when you pass a bare message id instead of the complete key, `chatId` lets the server rebuild the full key. If you pass the complete `waMessageKey` you can omit it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "media url",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "nullable": true,
                          "description": "Hosted URL for the media bytes, or null if the engine could not produce one."
                        }
                      },
                      "required": [
                        "url"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.mediaurl.get"
      }
    },
    "/v1/messages/acks": {
      "post": {
        "tags": [
          "Messages"
        ],
        "summary": "Batch get message acks",
        "description": "Get delivery status for up to 200 sent messages in one call. Useful for campaign dashboards / status reconciliation. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "message_keys": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "minLength": 1
                    },
                    "minItems": 1,
                    "maxItems": 200
                  },
                  "chat_id": {
                    "type": "string",
                    "minLength": 1
                  }
                },
                "required": [
                  "message_keys"
                ],
                "additionalProperties": false
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ack data",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "ack": {
                            "type": "integer",
                            "nullable": true,
                            "description": "-1=error, 0=pending, 1=server, 2=device, 3=read, 4=played; null when the engine could not determine."
                          }
                        },
                        "required": [
                          "key",
                          "ack"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.acks"
      }
    },
    "/v1/messages/media/{waMessageKey}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "Get message media",
        "description": "Download the media attached to a WhatsApp message (image, video, document, audio).\nReturns either a hosted URL (`url`) or inline `data_base64`, plus mimetype + filename.\n\nCAVEAT: for own-sent newsletter media (messages you sent to a `@newsletter` chat), the bytes returned are a WA-generated preview JPEG (~7KB) rather than the original you uploaded — WA releases the original blob from memory immediately after the unencrypted upload. The response will include `original_quality:false` when this fallback is in effect; the caller can warn the user or decide to retry from a different source.\n\nRequires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "waMessageKey",
            "in": "path",
            "required": true,
            "description": "The complete WhatsApp message key (`<fromMe>_<chatJid>_<id>[_<participant>]`), e.g. `false_120363426216988013@g.us_3EB0659D13650092D677AD_188450464616609@lid`.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chatId",
            "in": "query",
            "required": false,
            "description": "Optional. Only used to find the message faster — when you pass a bare message id instead of the complete key, `chatId` lets the server rebuild the full key. If you pass the complete `waMessageKey` you can omit it.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "media",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "object",
                      "properties": {
                        "url": {
                          "type": "string",
                          "nullable": true
                        },
                        "mimetype": {
                          "type": "string",
                          "nullable": true
                        },
                        "filename": {
                          "type": "string",
                          "nullable": true
                        },
                        "data_base64": {
                          "type": "string",
                          "nullable": true
                        },
                        "original_quality": {
                          "type": "boolean",
                          "nullable": true,
                          "description": "Set to false when the bytes returned are NOT the original sender uploaded — i.e. WA released the original from memory and we synthesized from a smaller WA-generated preview (#113). Currently only happens for own-sent newsletter media (messages you sent to a @newsletter chat). When absent or true, the bytes are the genuine original. Consumers can use this to warn users / decide whether to retry from a different source."
                        },
                        "media_unavailable": {
                          "type": "string",
                          "enum": [
                            "expired",
                            "fetching",
                            "awaiting_sender",
                            "error",
                            "no_media"
                          ],
                          "nullable": true,
                          "description": "Set when the bytes could not be downloaded or never existed. \"expired\" = WA aged the file out of CDN retention (typically older than ~30 days for documents) and there is nothing to retry. \"fetching\" = WA is mid-download from its CDN — transient, the server already retried for ~10s; calling again in a few seconds usually resolves to bytes. \"awaiting_sender\" = WA's CDN does not have the file but has asked the sender's device to reupload it. The reupload only completes when the sender's WhatsApp client is open and online; closed/backgrounded apps block it indefinitely. Tell the user to ask the sender to open WhatsApp; do not poll. \"error\" = unexpected failure; \"no_media\" = the message is text-only / revoked / location / vcard, i.e. it never carried media — caller should not have invoked this tool on this messageKey. Absent when bytes were not needed or when the fetch succeeded."
                        }
                      },
                      "required": [
                        "url",
                        "mimetype",
                        "filename",
                        "data_base64",
                        "original_quality",
                        "media_unavailable"
                      ],
                      "additionalProperties": false
                    }
                  },
                  "required": [
                    "success",
                    "data"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.media.get"
      }
    },
    "/v1/messages/pinned/{chat_id}": {
      "get": {
        "tags": [
          "Messages"
        ],
        "summary": "List pinned messages",
        "description": "List the currently pinned messages in a chat. Requires `chats:read`.",
        "security": [
          {
            "BearerAuth": [
              "chats:read"
            ]
          }
        ],
        "parameters": [
          {
            "name": "chat_id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "pinned messages",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "success": {
                      "type": "boolean",
                      "enum": [
                        true
                      ],
                      "description": "Always `true` on success responses."
                    },
                    "data": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "key": {
                            "type": "string"
                          },
                          "chat_id": {
                            "type": "string"
                          },
                          "text": {
                            "type": "string",
                            "nullable": true
                          }
                        },
                        "required": [
                          "key",
                          "chat_id",
                          "text"
                        ],
                        "additionalProperties": false
                      }
                    },
                    "limit": {
                      "type": "integer",
                      "description": "Page size echoed back from the request."
                    },
                    "skip": {
                      "type": "integer",
                      "description": "Offset echoed back from the request."
                    },
                    "total": {
                      "type": "integer",
                      "description": "Total number of items matching the query, across all pages."
                    }
                  },
                  "required": [
                    "success",
                    "data",
                    "limit",
                    "skip",
                    "total"
                  ],
                  "additionalProperties": false
                }
              }
            }
          },
          "400": {
            "description": "Bad request — invalid params or body.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing or invalid API key.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "API key lacks the required scope.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Resource not found.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed — see `error.details` for per-field issues.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit exceeded — back off and retry.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal server error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "operationId": "messages.pinned.get"
      }
    }
  },
  "components": {
    "securitySchemes": {
      "BearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "bt_<env>_..."
      }
    },
    "schemas": {
      "AccountResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable identifier for the account."
          },
          "name": {
            "type": "string",
            "description": "Account display name."
          },
          "user_email": {
            "type": "string",
            "nullable": true,
            "description": "Email address of the user the API key belongs to, or null if unavailable."
          },
          "timezone": {
            "type": "string",
            "nullable": true,
            "description": "IANA timezone (e.g. \"America/New_York\"), or null if unset."
          },
          "created_at": {
            "type": "string",
            "format": "date-time",
            "description": "RFC 3339 timestamp of account creation."
          }
        },
        "required": [
          "id",
          "name",
          "user_email",
          "timezone",
          "created_at"
        ]
      },
      "AppendContactsRequest": {
        "type": "object",
        "properties": {
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "to": {
                  "type": "string",
                  "description": "Recipient. Either a phone number in international format (e.g. +14155551234) or a WhatsApp JID (e.g. 14155551234@c.us). Stored in international format."
                },
                "variables": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string",
                    "maxLength": 1024
                  },
                  "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
                }
              },
              "required": [
                "to"
              ],
              "additionalProperties": false
            },
            "minItems": 1,
            "maxItems": 1000
          }
        },
        "required": [
          "contacts"
        ],
        "additionalProperties": false
      },
      "AudienceResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "contact_count": {
            "type": "integer",
            "minimum": 0
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "contact_count",
          "created_at"
        ],
        "additionalProperties": false
      },
      "ContactInput": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string",
            "description": "Recipient. Either a phone number in international format (e.g. +14155551234) or a WhatsApp JID (e.g. 14155551234@c.us). Stored in international format."
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 1024
            },
            "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
          }
        },
        "required": [
          "to"
        ],
        "additionalProperties": false
      },
      "ContactResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "to": {
            "type": "string"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string"
            }
          },
          "added_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "to",
          "variables",
          "added_at"
        ],
        "additionalProperties": false
      },
      "CreateAudienceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          },
          "contacts": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "to": {
                  "type": "string",
                  "description": "Recipient. Either a phone number in international format (e.g. +14155551234) or a WhatsApp JID (e.g. 14155551234@c.us). Stored in international format."
                },
                "variables": {
                  "type": "object",
                  "additionalProperties": {
                    "type": "string",
                    "maxLength": 1024
                  },
                  "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
                }
              },
              "required": [
                "to"
              ],
              "additionalProperties": false
            },
            "maxItems": 1000
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "PatchAudienceRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "PatchContactRequest": {
        "type": "object",
        "properties": {
          "to": {
            "type": "string"
          },
          "variables": {
            "type": "object",
            "additionalProperties": {
              "type": "string",
              "maxLength": 1024
            },
            "description": "Per-contact substitution values used by campaign templates.\nEach key becomes a token usable as `{key}` in a campaign `text`. Lookup is case-insensitive (e.g. `{firstName}` resolves `firstname`).\nBuilt-in tokens always available regardless of variables: `{whatsappname}`, `{displayname}`, `{phone}`, `{mobile}`. Setting a variable with the same name overrides the built-in.\nStorage: keys are persisted as text-cell column titles on the audience board, so values flow back via audiences.get under the same names.\nLimits: at most 32 keys per contact; values up to 1024 chars; keys must match /^[A-Za-z_][A-Za-z0-9_]{0,31}$/."
          }
        },
        "additionalProperties": false
      },
      "CampaignResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "audience_id": {
            "type": "string"
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "running",
              "paused",
              "complete_sent",
              "complete_delivered",
              "aborted"
            ]
          },
          "total_count": {
            "type": "integer",
            "minimum": 0
          },
          "sent_count": {
            "type": "integer",
            "minimum": 0
          },
          "delivered_count": {
            "type": "integer",
            "minimum": 0
          },
          "read_count": {
            "type": "integer",
            "minimum": 0
          },
          "failed_count": {
            "type": "integer",
            "minimum": 0
          },
          "from": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "started_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "completed_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "aborted_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "name",
          "audience_id",
          "status",
          "total_count",
          "sent_count",
          "delivered_count",
          "read_count",
          "failed_count",
          "from",
          "created_at",
          "started_at",
          "completed_at",
          "aborted_at"
        ],
        "additionalProperties": false
      },
      "CampaignStatus": {
        "type": "string",
        "enum": [
          "pending",
          "running",
          "paused",
          "complete_sent",
          "complete_delivered",
          "aborted"
        ]
      },
      "CreateCampaignRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 120,
            "description": "Display name for the campaign."
          },
          "audience_id": {
            "type": "string",
            "minLength": 1,
            "description": "ID of the audience to target. Each audience contact contributes one outgoing message."
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096,
            "description": "Message body. Supports per-contact substitution using single-brace tokens like `{firstName}` or `{product}`.\nResolution rules (case-insensitive, whitespace stripped):\n  - Built-ins always available: `{whatsappname}` (WA profile name), `{displayname}` (firstname+lastname fallback), `{phone}` / `{mobile}`.\n  - Custom variables: every property attached to a contact via audiences.append_contacts becomes a token of the same name.\n  - Unresolved tokens are left as literal `{token}` in the sent message.\nTemplates use SINGLE braces `{var}` — `{{var}}` is treated as literal text."
          },
          "media_url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Public https URL of an image/video/document to attach."
          },
          "media_caption": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1024,
            "description": "Caption for the media attachment. Requires media_url."
          },
          "from": {
            "type": "string",
            "pattern": "^\\+[1-9]\\d{6,14}$",
            "description": "Sender phone in international format (e.g. +14155551234). When omitted, the workspace default sender is used."
          },
          "on_missing_variable": {
            "type": "string",
            "enum": [
              "fail",
              "skip"
            ],
            "description": "Behavior when a template references a variable that is not present on a contact:\n  - `fail` (default): reject the request at create time; no messages are sent. Returns 400 with `data.examples` listing offending contacts.\n  - `skip`: accept the campaign; contacts missing variables receive the message with literal `{token}` left in place."
          }
        },
        "required": [
          "name",
          "audience_id"
        ],
        "additionalProperties": false
      },
      "BatchMessageAckEntry": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "ack": {
            "type": "integer",
            "nullable": true,
            "description": "-1=error, 0=pending, 1=server, 2=device, 3=read, 4=played; null when the engine could not determine."
          }
        },
        "required": [
          "key",
          "ack"
        ],
        "additionalProperties": false
      },
      "BatchMessageAcksRequest": {
        "type": "object",
        "properties": {
          "message_keys": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1
            },
            "minItems": 1,
            "maxItems": 200
          },
          "chat_id": {
            "type": "string",
            "minLength": 1
          }
        },
        "required": [
          "message_keys"
        ],
        "additionalProperties": false
      },
      "ChangeLabelsRequest": {
        "type": "object",
        "properties": {
          "label_ids": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64
            },
            "maxItems": 50,
            "description": "Full replacement set of label ids for this chat."
          }
        },
        "required": [
          "label_ids"
        ],
        "additionalProperties": false
      },
      "Chat": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "is_group": {
            "type": "boolean"
          },
          "is_newsletter": {
            "type": "boolean"
          },
          "last_message_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "unread_count": {
            "type": "integer",
            "nullable": true,
            "minimum": 0
          },
          "marked_unread": {
            "type": "boolean"
          }
        },
        "required": [
          "id",
          "name",
          "is_group",
          "is_newsletter",
          "last_message_at",
          "unread_count",
          "marked_unread"
        ],
        "additionalProperties": false
      },
      "ChatId": {
        "type": "string",
        "pattern": "^\\d+(?:-\\d+)?@(?:c\\.us|s\\.whatsapp\\.net|g\\.us|lid|broadcast|newsletter)$"
      },
      "ChatLabel": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "color": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "color"
        ],
        "additionalProperties": false
      },
      "ChatMutationResult": {
        "type": "object",
        "properties": {
          "result": {
            "type": "boolean",
            "description": "`true` when WAWeb accepted the mutation; `false` when WAWeb refused or the feature is unavailable on this account."
          },
          "error": {
            "type": "string",
            "description": "Set when `result === false`. The literal `wa_business_required` signals the connected account is not a WhatsApp Business account; any other value is the underlying engine diagnostic."
          }
        },
        "required": [
          "result"
        ],
        "additionalProperties": false
      },
      "ChatNoteRequest": {
        "type": "object",
        "properties": {
          "note": {
            "type": "string",
            "maxLength": 4096,
            "description": "Free-text note. Empty string clears the note."
          }
        },
        "required": [
          "note"
        ],
        "additionalProperties": false
      },
      "ChatRef": {
        "type": "object",
        "properties": {
          "chat_id": {
            "type": "string"
          }
        },
        "required": [
          "chat_id"
        ],
        "additionalProperties": false
      },
      "GetChatParticipantsQuery": {
        "type": "object",
        "properties": {
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token; when set, only participants whose resolved name or phone/JID matches (case-insensitive substring) are returned, and `total` reflects the matched count."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 500,
            "default": 100,
            "description": "Max participants to return."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of participants to skip before the page (default 0)."
          }
        },
        "additionalProperties": false
      },
      "ListChatsQuery": {
        "type": "object",
        "properties": {
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token; when set, only items whose name matches are returned."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Page size (1-200, default 50)."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of items to skip before the page (default 0)."
          },
          "filter": {
            "type": "string",
            "enum": [
              "groups",
              "contacts",
              "newsletters"
            ],
            "description": "Restrict to one chat kind."
          },
          "include_last_message": {
            "type": "boolean",
            "description": "Include the last message snippet on each chat row."
          },
          "include_extended_info": {
            "type": "boolean",
            "description": "Include extended chat metadata (engine-side opt-in)."
          },
          "include_without_name": {
            "type": "boolean",
            "description": "Include chats with no resolved name (default: skipped)."
          }
        },
        "additionalProperties": false
      },
      "LoadOlderResult": {
        "type": "object",
        "properties": {
          "total_messages": {
            "type": "integer",
            "nullable": true
          },
          "added": {
            "type": "integer",
            "nullable": true
          },
          "can_load_more": {
            "type": "boolean"
          }
        },
        "required": [
          "total_messages",
          "added",
          "can_load_more"
        ],
        "additionalProperties": false
      },
      "Media": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true
          },
          "mimetype": {
            "type": "string",
            "nullable": true
          },
          "filename": {
            "type": "string",
            "nullable": true
          },
          "data_base64": {
            "type": "string",
            "nullable": true
          },
          "original_quality": {
            "type": "boolean",
            "nullable": true,
            "description": "Set to false when the bytes returned are NOT the original sender uploaded — i.e. WA released the original from memory and we synthesized from a smaller WA-generated preview (#113). Currently only happens for own-sent newsletter media (messages you sent to a @newsletter chat). When absent or true, the bytes are the genuine original. Consumers can use this to warn users / decide whether to retry from a different source."
          },
          "media_unavailable": {
            "type": "string",
            "nullable": true,
            "enum": [
              "expired",
              "fetching",
              "awaiting_sender",
              "error",
              "no_media"
            ],
            "description": "Set when the bytes could not be downloaded or never existed. \"expired\" = WA aged the file out of CDN retention (typically older than ~30 days for documents) and there is nothing to retry. \"fetching\" = WA is mid-download from its CDN — transient, the server already retried for ~10s; calling again in a few seconds usually resolves to bytes. \"awaiting_sender\" = WA's CDN does not have the file but has asked the sender's device to reupload it. The reupload only completes when the sender's WhatsApp client is open and online; closed/backgrounded apps block it indefinitely. Tell the user to ask the sender to open WhatsApp; do not poll. \"error\" = unexpected failure; \"no_media\" = the message is text-only / revoked / location / vcard, i.e. it never carried media — caller should not have invoked this tool on this messageKey. Absent when bytes were not needed or when the fetch succeeded."
          }
        },
        "required": [
          "url",
          "mimetype",
          "filename",
          "data_base64",
          "original_quality",
          "media_unavailable"
        ],
        "additionalProperties": false
      },
      "MediaUrl": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "nullable": true,
            "description": "Hosted URL for the media bytes, or null if the engine could not produce one."
          }
        },
        "required": [
          "url"
        ],
        "additionalProperties": false
      },
      "MessageAck": {
        "type": "object",
        "properties": {
          "ack": {
            "type": "integer",
            "nullable": true,
            "description": "-1=error, 0=pending, 1=server, 2=device, 3=read, 4=played; null when no engine response."
          }
        },
        "required": [
          "ack"
        ],
        "additionalProperties": false
      },
      "MessageKey": {
        "type": "string",
        "minLength": 1,
        "maxLength": 512
      },
      "MessagesQuery": {
        "type": "object",
        "properties": {
          "order": {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ],
            "description": "Result ordering. asc = oldest-first; desc = newest-first (default)."
          },
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token; when set, only items whose name matches are returned."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Max messages to return."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of messages to skip before the page (default 0)."
          },
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "Lower bound (ISO 8601). Only messages with timestamp >= since."
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "description": "Upper bound (ISO 8601). Only messages with timestamp <= until."
          },
          "messageTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "chat",
                "image",
                "video",
                "document",
                "audio",
                "ptt",
                "sticker",
                "gif",
                "ptv",
                "poll_creation",
                "location",
                "vcard",
                "revoked"
              ]
            },
            "description": "Filter to specific message kinds. Comma-separated or repeated. Useful for \"all PDFs\" (`document`) or \"images today\" (`image`). System events (gp2/revoked/newsletter_notification) are excluded by default unless explicitly listed here."
          },
          "loadFromPhoneIfNeeded": {
            "type": "boolean",
            "description": "When the local store is exhausted, fetch older messages from the phone (chrome only)."
          },
          "includeMediaContent": {
            "type": "boolean",
            "description": "Include inline media payload on rows (heavy; default false — use /messages/{key}/media)."
          },
          "chatId": {
            "type": "string",
            "pattern": "^\\d+(?:-\\d+)?@(?:c\\.us|s\\.whatsapp\\.net|g\\.us|lid|broadcast|newsletter)$",
            "description": "Optional WhatsApp JID to scope results to a single chat. Omit to search across all chats."
          }
        },
        "additionalProperties": false
      },
      "MuteChatRequest": {
        "type": "object",
        "properties": {
          "unmute_at": {
            "type": "string",
            "format": "date-time",
            "description": "ISO 8601 timestamp at which the chat auto-unmutes. Omit for \"forever\"."
          }
        },
        "additionalProperties": false
      },
      "MuteState": {
        "type": "object",
        "properties": {
          "is_muted": {
            "type": "boolean"
          },
          "mute_expiration_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        },
        "required": [
          "is_muted",
          "mute_expiration_at"
        ],
        "additionalProperties": false
      },
      "OkResult": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "enum": [
              true
            ]
          }
        },
        "required": [
          "ok"
        ],
        "additionalProperties": false
      },
      "Participant": {
        "type": "object",
        "properties": {
          "chat_id": {
            "type": "string"
          },
          "is_admin": {
            "type": "boolean"
          },
          "is_super_admin": {
            "type": "boolean"
          }
        },
        "required": [
          "chat_id",
          "is_admin"
        ],
        "additionalProperties": false
      },
      "PinnedMessage": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "chat_id": {
            "type": "string"
          },
          "text": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "key",
          "chat_id",
          "text"
        ],
        "additionalProperties": false
      },
      "PublicMessage": {
        "type": "object",
        "properties": {
          "key": {
            "type": "string"
          },
          "chat_id": {
            "type": "string"
          },
          "from": {
            "type": "string"
          },
          "author": {
            "type": "string",
            "nullable": true
          },
          "timestamp": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "type": {
            "type": "string"
          },
          "from_me": {
            "type": "boolean"
          },
          "ack": {
            "type": "integer",
            "nullable": true
          },
          "media_url": {
            "type": "string",
            "nullable": true
          },
          "caption": {
            "type": "string",
            "nullable": true
          },
          "filename": {
            "type": "string",
            "nullable": true
          },
          "link_preview": {
            "type": "object",
            "nullable": true,
            "properties": {
              "title": {
                "type": "string",
                "nullable": true
              },
              "description": {
                "type": "string",
                "nullable": true
              },
              "canonical_url": {
                "type": "string",
                "nullable": true
              },
              "thumbnail": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "title",
              "description",
              "canonical_url",
              "thumbnail"
            ]
          }
        },
        "required": [
          "key",
          "chat_id",
          "from",
          "timestamp",
          "text",
          "type",
          "from_me",
          "ack",
          "media_url",
          "caption",
          "filename"
        ],
        "additionalProperties": false
      },
      "QueryMessagesQuery": {
        "type": "object",
        "properties": {
          "order": {
            "type": "string",
            "enum": [
              "asc",
              "desc"
            ],
            "description": "Result ordering. asc = oldest-first; desc = newest-first (default)."
          },
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token; when set, only items whose name matches are returned."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Max messages to return."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of messages to skip before the page (default 0)."
          },
          "since": {
            "type": "string",
            "format": "date-time",
            "description": "Lower bound (ISO 8601). Only messages with timestamp >= since."
          },
          "until": {
            "type": "string",
            "format": "date-time",
            "description": "Upper bound (ISO 8601). Only messages with timestamp <= until."
          },
          "messageTypes": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "chat",
                "image",
                "video",
                "document",
                "audio",
                "ptt",
                "sticker",
                "gif",
                "ptv",
                "poll_creation",
                "location",
                "vcard",
                "revoked"
              ]
            },
            "description": "Filter to specific message kinds. Comma-separated or repeated. Useful for \"all PDFs\" (`document`) or \"images today\" (`image`). System events (gp2/revoked/newsletter_notification) are excluded by default unless explicitly listed here."
          },
          "loadFromPhoneIfNeeded": {
            "type": "boolean",
            "description": "When the local store is exhausted, fetch older messages from the phone (chrome only)."
          },
          "includeMediaContent": {
            "type": "boolean",
            "description": "Include inline media payload on rows (heavy; default false — use /messages/{key}/media)."
          }
        },
        "additionalProperties": false
      },
      "ReactRequest": {
        "type": "object",
        "properties": {
          "emoji": {
            "type": "string",
            "minLength": 0,
            "maxLength": 32
          }
        },
        "required": [
          "emoji"
        ],
        "additionalProperties": false
      },
      "UnifiedSearchQuery": {
        "type": "object",
        "properties": {
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token matched against contact and chat names."
          },
          "types": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "contacts",
                "chats",
                "newsletters"
              ]
            },
            "description": "Restrict results to these kinds. Comma-separated or repeated. Default: all."
          }
        },
        "additionalProperties": false
      },
      "EngineListResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "connected": {
                  "type": "boolean",
                  "description": "Whether this engine is currently online and serving requests."
                },
                "state": {
                  "type": "string",
                  "nullable": true,
                  "description": "Engine-side connection state (e.g. CONNECTED, OPENING, PAIRING). Null when unknown."
                },
                "stream": {
                  "type": "string",
                  "nullable": true,
                  "description": "Underlying WA stream state. Null when unknown."
                },
                "has_synced": {
                  "type": "boolean",
                  "nullable": true,
                  "description": "Whether the engine has completed its initial history sync."
                }
              },
              "required": [
                "connected",
                "state",
                "stream",
                "has_synced"
              ],
              "additionalProperties": false
            },
            "description": "Engines connected to this workspace. Empty when no engine is paired."
          },
          "message": {
            "type": "string",
            "description": "Human-readable note (e.g. why the array is empty). Present only when useful."
          }
        },
        "required": [
          "data"
        ],
        "additionalProperties": false
      },
      "EngineStatus": {
        "type": "object",
        "properties": {
          "connected": {
            "type": "boolean",
            "description": "Whether this engine is currently online and serving requests."
          },
          "state": {
            "type": "string",
            "nullable": true,
            "description": "Engine-side connection state (e.g. CONNECTED, OPENING, PAIRING). Null when unknown."
          },
          "stream": {
            "type": "string",
            "nullable": true,
            "description": "Underlying WA stream state. Null when unknown."
          },
          "has_synced": {
            "type": "boolean",
            "nullable": true,
            "description": "Whether the engine has completed its initial history sync."
          }
        },
        "required": [
          "connected",
          "state",
          "stream",
          "has_synced"
        ],
        "additionalProperties": false
      },
      "AddMemberRequest": {
        "type": "object",
        "properties": {
          "chat_id": {
            "type": "string"
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 256
          }
        },
        "additionalProperties": false
      },
      "CreateGroupRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "participants": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "minItems": 1,
            "maxItems": 256
          }
        },
        "required": [
          "name",
          "participants"
        ],
        "additionalProperties": false
      },
      "Group": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "owner": {
            "type": "string",
            "nullable": true
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "last_message_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "participant_count": {
            "type": "integer",
            "nullable": true,
            "minimum": 0
          },
          "announce": {
            "type": "boolean",
            "nullable": true
          },
          "restrict": {
            "type": "boolean",
            "nullable": true
          },
          "participants": {
            "type": "array",
            "nullable": true,
            "items": {
              "type": "object",
              "properties": {
                "chat_id": {
                  "type": "string"
                },
                "is_admin": {
                  "type": "boolean"
                },
                "is_super_admin": {
                  "type": "boolean"
                },
                "name": {
                  "type": "string",
                  "nullable": true
                }
              },
              "required": [
                "chat_id",
                "is_admin",
                "is_super_admin",
                "name"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "owner",
          "created_at",
          "last_message_at",
          "participant_count",
          "announce",
          "restrict",
          "participants"
        ],
        "additionalProperties": false
      },
      "GroupId": {
        "type": "string",
        "pattern": "^\\d+(?:-\\d+)?@g\\.us$"
      },
      "GroupParticipant": {
        "type": "object",
        "properties": {
          "chat_id": {
            "type": "string"
          },
          "is_admin": {
            "type": "boolean"
          },
          "is_super_admin": {
            "type": "boolean"
          },
          "name": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "chat_id",
          "is_admin",
          "is_super_admin",
          "name"
        ],
        "additionalProperties": false
      },
      "ListGroupsQuery": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Page size (1-200, default 50)."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of items to skip before the page (default 0)."
          },
          "searchToken": {
            "type": "string",
            "minLength": 1,
            "maxLength": 128,
            "description": "Search token; when set, only items whose name matches are returned."
          }
        },
        "additionalProperties": false
      },
      "MemberChatId": {
        "type": "string"
      },
      "SetPictureRequest": {
        "type": "object",
        "properties": {
          "file_data_url": {
            "type": "string",
            "minLength": 1,
            "maxLength": 20971520
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri"
          },
          "file_name": {
            "type": "string",
            "maxLength": 255
          },
          "file_mime_type": {
            "type": "string",
            "maxLength": 127
          }
        },
        "additionalProperties": false
      },
      "UpdateGroupRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "settings": {
            "type": "object",
            "properties": {
              "announce": {
                "type": "boolean"
              },
              "restrict": {
                "type": "boolean"
              },
              "edit_info_admins_only": {
                "type": "boolean"
              }
            },
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      },
      "Error": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always `false` on error responses."
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code (e.g. `invalid_request`, `authentication_required`, `not_found`, `rate_limited`, `internal_error`)."
              },
              "message": {
                "type": "string",
                "description": "Human-readable description of what went wrong."
              },
              "request_id": {
                "type": "string",
                "nullable": true,
                "description": "Server-assigned request id; pass this when filing support tickets so engineering can trace the failure."
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string",
                      "description": "Dotted path to the offending field within the request body."
                    },
                    "code": {
                      "type": "string",
                      "description": "Zod-derived issue code (e.g. `invalid_type`, `too_small`)."
                    },
                    "message": {
                      "type": "string",
                      "description": "Human-readable validation message."
                    }
                  },
                  "required": [
                    "path",
                    "code",
                    "message"
                  ],
                  "additionalProperties": false
                },
                "description": "Per-field validation issues. Present on 400/422 when the request body failed Zod parsing."
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "success",
          "error"
        ],
        "additionalProperties": false,
        "description": "Standard error response envelope. Every 4xx/5xx response from the v1 API carries this exact shape."
      },
      "ErrorEnvelope": {
        "type": "object",
        "properties": {
          "success": {
            "type": "boolean",
            "enum": [
              false
            ],
            "description": "Always `false` on error responses."
          },
          "error": {
            "type": "object",
            "properties": {
              "code": {
                "type": "string",
                "description": "Stable machine-readable error code (e.g. `invalid_request`, `authentication_required`, `not_found`, `rate_limited`, `internal_error`)."
              },
              "message": {
                "type": "string",
                "description": "Human-readable description of what went wrong."
              },
              "request_id": {
                "type": "string",
                "nullable": true,
                "description": "Server-assigned request id; pass this when filing support tickets so engineering can trace the failure."
              },
              "details": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "path": {
                      "type": "string",
                      "description": "Dotted path to the offending field within the request body."
                    },
                    "code": {
                      "type": "string",
                      "description": "Zod-derived issue code (e.g. `invalid_type`, `too_small`)."
                    },
                    "message": {
                      "type": "string",
                      "description": "Human-readable validation message."
                    }
                  },
                  "required": [
                    "path",
                    "code",
                    "message"
                  ],
                  "additionalProperties": false
                },
                "description": "Per-field validation issues. Present on 400/422 when the request body failed Zod parsing."
              }
            },
            "required": [
              "code",
              "message",
              "request_id"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "success",
          "error"
        ],
        "additionalProperties": false,
        "description": "Standard error response envelope. Every 4xx/5xx response from the v1 API carries this exact shape."
      },
      "ValidationDetail": {
        "type": "object",
        "properties": {
          "path": {
            "type": "string",
            "description": "Dotted path to the offending field within the request body."
          },
          "code": {
            "type": "string",
            "description": "Zod-derived issue code (e.g. `invalid_type`, `too_small`)."
          },
          "message": {
            "type": "string",
            "description": "Human-readable validation message."
          }
        },
        "required": [
          "path",
          "code",
          "message"
        ],
        "additionalProperties": false
      },
      "PaginatedResponse": {
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {}
            },
            "description": "Page of items; the item shape is endpoint-specific."
          },
          "limit": {
            "type": "integer",
            "description": "Page size echoed back from the request."
          },
          "skip": {
            "type": "integer",
            "description": "Offset echoed back from the request."
          },
          "total": {
            "type": "integer",
            "description": "Total number of items matching the query, across all pages."
          }
        },
        "required": [
          "data",
          "limit",
          "skip",
          "total"
        ],
        "additionalProperties": false,
        "description": "Offset-paginated response envelope. Every v1 list endpoint returns this shape (inside the `success`/`data` wrapper)."
      },
      "CreateNewsletterRequest": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "description": {
            "type": "string",
            "maxLength": 2048
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "ListNewslettersQuery": {
        "type": "object",
        "properties": {
          "searchToken": {
            "type": "string",
            "maxLength": 200,
            "description": "Search token; when set, only newsletters whose name matches (case-insensitive substring) are returned, and `total` reflects the matched count."
          },
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Page size (1-200, default 50)."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of items to skip before the page (default 0)."
          }
        }
      },
      "NewsletterId": {
        "type": "string",
        "pattern": "^\\d+@newsletter$",
        "description": "Newsletter JID, e.g. 12345@newsletter."
      },
      "NewsletterResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Newsletter JID, e.g. 120363201733549020@newsletter."
          },
          "name": {
            "type": "string",
            "description": "Display name of the newsletter / WhatsApp channel."
          },
          "description": {
            "type": "string",
            "nullable": true,
            "description": "Optional description."
          },
          "owner": {
            "type": "string",
            "nullable": true,
            "description": "Owner JID, if returned by the engine."
          },
          "created_at": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "subscribers": {
            "type": "integer",
            "nullable": true,
            "minimum": 0
          },
          "invite": {
            "type": "string",
            "nullable": true,
            "description": "Invite code (suffix of https://whatsapp.com/channel/<invite>)."
          },
          "verification": {
            "type": "string",
            "nullable": true,
            "enum": [
              "VERIFIED",
              "UNVERIFIED"
            ]
          }
        },
        "required": [
          "id",
          "name",
          "description",
          "owner",
          "created_at",
          "subscribers",
          "invite",
          "verification"
        ],
        "additionalProperties": false
      },
      "PingConnection": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "description": "Stable id of the live engine session (its MQTT presence client id)."
          },
          "type": {
            "type": "string",
            "enum": [
              "gateway",
              "regular"
            ],
            "description": "Engine kind. \"gateway\" = a remote, server-side engine (Blueticks 24/7 gateway / baileys pod). \"regular\" = the user's own WhatsApp Web browser extension."
          },
          "connected": {
            "type": "boolean",
            "enum": [
              true
            ],
            "description": "Always true — an entry appears only while its presence heartbeat is live."
          }
        },
        "required": [
          "id",
          "type",
          "connected"
        ],
        "additionalProperties": false
      },
      "PingResponse": {
        "type": "object",
        "properties": {
          "api": {
            "type": "string",
            "enum": [
              "ok"
            ],
            "description": "Blueticks API server liveness. \"ok\" means the API server is up and served this request."
          },
          "account_id": {
            "type": "string",
            "description": "The account (workspace) the API key belongs to."
          },
          "whatsapp_connections": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "description": "Stable id of the live engine session (its MQTT presence client id)."
                },
                "type": {
                  "type": "string",
                  "enum": [
                    "gateway",
                    "regular"
                  ],
                  "description": "Engine kind. \"gateway\" = a remote, server-side engine (Blueticks 24/7 gateway / baileys pod). \"regular\" = the user's own WhatsApp Web browser extension."
                },
                "connected": {
                  "type": "boolean",
                  "enum": [
                    true
                  ],
                  "description": "Always true — an entry appears only while its presence heartbeat is live."
                }
              },
              "required": [
                "id",
                "type",
                "connected"
              ],
              "additionalProperties": false
            },
            "description": "WhatsApp engines currently connected for this account. Empty means no WhatsApp is connected."
          },
          "message": {
            "type": "string",
            "description": "Present only when whatsapp_connections is empty; explains the empty state."
          }
        },
        "required": [
          "api",
          "account_id",
          "whatsapp_connections"
        ],
        "additionalProperties": false
      },
      "LinkPreviewResponse": {
        "type": "object",
        "properties": {
          "title": {
            "type": "string",
            "nullable": true
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "canonicalUrl": {
            "type": "string",
            "nullable": true
          },
          "thumbnail": {
            "type": "string",
            "nullable": true
          }
        },
        "required": [
          "title",
          "description",
          "canonicalUrl",
          "thumbnail"
        ],
        "additionalProperties": false
      },
      "ListMessagesQuery": {
        "type": "object",
        "properties": {
          "limit": {
            "type": "integer",
            "minimum": 1,
            "maximum": 200,
            "default": 50,
            "description": "Page size (1-200, default 50)."
          },
          "skip": {
            "type": "integer",
            "nullable": true,
            "minimum": 0,
            "default": 0,
            "description": "Number of items to skip before the page (default 0)."
          },
          "chatId": {
            "type": "string",
            "pattern": "^[0-9]+(?:-[0-9]+)?@(?:c\\.us|g\\.us|newsletter)$",
            "description": "Filter to messages addressed to this WhatsApp JID. Matches the recipient stored on the queued/scheduled doc — for sends to a phone number, the JID is `<phone>@c.us`."
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "received",
              "read",
              "played",
              "failed"
            ],
            "description": "Filter by lifecycle status: `pending` (accepted, waiting), `confirmed` (WhatsApp accepted — has waMessageKey), `received` (double grey tick), `read` (double blue tick), `played` (voice played), `failed`."
          },
          "searchToken": {
            "type": "string",
            "minLength": 1,
            "maxLength": 200,
            "description": "Search token; when set, only items whose name matches are returned."
          }
        },
        "additionalProperties": false
      },
      "MediaKind": {
        "type": "string",
        "enum": [
          "image",
          "video",
          "audio",
          "document",
          "sticker",
          "voice",
          "gif"
        ]
      },
      "MessageId": {
        "type": "string",
        "pattern": "^[0-9a-fA-F]{24}$"
      },
      "MessageResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "nullable": true
          },
          "key": {
            "type": "string",
            "nullable": true
          },
          "to": {
            "type": "string"
          },
          "type": {
            "type": "string",
            "enum": [
              "text",
              "media",
              "poll"
            ],
            "description": "Message kind that was sent."
          },
          "text": {
            "type": "string",
            "nullable": true
          },
          "mediaUrl": {
            "type": "string",
            "nullable": true
          },
          "mediaKind": {
            "type": "string",
            "nullable": true,
            "enum": [
              "image",
              "video",
              "audio",
              "document",
              "sticker",
              "voice",
              "gif"
            ]
          },
          "pollQuestion": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "pending",
              "confirmed",
              "received",
              "read",
              "played",
              "failed"
            ]
          },
          "sendAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "createdAt": {
            "type": "string",
            "format": "date-time"
          },
          "confirmedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "receivedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "readAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "playedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "failedAt": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          },
          "failureReason": {
            "type": "string",
            "nullable": true
          },
          "linkPreview": {
            "type": "object",
            "nullable": true,
            "properties": {
              "title": {
                "type": "string",
                "nullable": true
              },
              "description": {
                "type": "string",
                "nullable": true
              },
              "canonicalUrl": {
                "type": "string",
                "nullable": true
              },
              "thumbnail": {
                "type": "string",
                "nullable": true
              }
            },
            "required": [
              "title",
              "description",
              "canonicalUrl",
              "thumbnail"
            ],
            "additionalProperties": false
          }
        },
        "required": [
          "id",
          "key",
          "to",
          "type",
          "text",
          "mediaUrl",
          "mediaKind",
          "pollQuestion",
          "status",
          "sendAt",
          "createdAt",
          "confirmedAt",
          "receivedAt",
          "readAt",
          "playedAt",
          "failedAt",
          "failureReason"
        ],
        "additionalProperties": false
      },
      "MessageStatus": {
        "type": "string",
        "enum": [
          "pending",
          "confirmed",
          "received",
          "read",
          "played",
          "failed"
        ]
      },
      "PatchMessageRequest": {
        "type": "object",
        "properties": {
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 4096,
            "description": "New text body. Replaces the previous text/caption."
          },
          "mediaUrl": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Replace the attached media URL (https only)."
          },
          "mediaCaption": {
            "type": "string",
            "minLength": 1,
            "maxLength": 1024,
            "description": "Replace the media's caption. When set alongside `text`, `text` wins."
          },
          "sendAt": {
            "type": "string",
            "format": "date-time",
            "description": "Reschedule. ISO 8601 datetime (UTC) in the future."
          }
        },
        "additionalProperties": false
      },
      "SendInChatRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "text",
              "media",
              "poll"
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 4096,
            "description": "Text body (required for type=text) or optional media caption (type=media). Up to 4096 chars. Mention a contact inline with `@[Display Name](<jid>)`, e.g. `Hi @[Joni Naor](972544325389@c.us)`."
          },
          "mediaUrl": {
            "type": "string",
            "maxLength": 2048,
            "description": "Media source URL (https only). One of mediaUrl or mediaBase64 is required for media sends; mediaUrl wins when both are present."
          },
          "mediaBase64": {
            "type": "string",
            "maxLength": 15728640,
            "description": "Raw media bytes, base64-encoded (or a data: URL). Used when mediaUrl is absent. For a file upload, send multipart/form-data with a `mediaFile` part instead — it is converted to this."
          },
          "mediaKind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "document",
              "sticker",
              "voice",
              "gif"
            ],
            "description": "Media kind (image · video · audio · document · sticker · voice · gif). Optional — auto-detected from the URL / content-type when omitted."
          },
          "mediaFilename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Filename shown on the attachment (type=media). Optional — derived from the URL / uploaded file when omitted."
          },
          "pollQuestion": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Poll question (type=poll). Required for poll sends."
          },
          "pollOptions": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Poll options (type=poll). 2–12 items."
          },
          "pollAllowMultiple": {
            "type": "boolean",
            "description": "Allow selecting multiple poll options (type=poll). Default false."
          },
          "replyTo": {
            "type": "string",
            "maxLength": 256,
            "description": "Wire `key` of a prior message to quote-reply (from MessageResponse.key). Empty string = no reply."
          },
          "secret": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "Opaque caller id stored on the message `secret` and carried into the WhatsApp messageSecret."
          }
        },
        "required": [
          "type"
        ],
        "additionalProperties": false
      },
      "SendMessageRequest": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "text",
              "media",
              "poll"
            ]
          },
          "text": {
            "type": "string",
            "maxLength": 4096,
            "description": "Text body (required for type=text) or optional media caption (type=media). Up to 4096 chars. Mention a contact inline with `@[Display Name](<jid>)`, e.g. `Hi @[Joni Naor](972544325389@c.us)`."
          },
          "mediaUrl": {
            "type": "string",
            "maxLength": 2048,
            "description": "Media source URL (https only). One of mediaUrl or mediaBase64 is required for media sends; mediaUrl wins when both are present."
          },
          "mediaBase64": {
            "type": "string",
            "maxLength": 15728640,
            "description": "Raw media bytes, base64-encoded (or a data: URL). Used when mediaUrl is absent. For a file upload, send multipart/form-data with a `mediaFile` part instead — it is converted to this."
          },
          "mediaKind": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "audio",
              "document",
              "sticker",
              "voice",
              "gif"
            ],
            "description": "Media kind (image · video · audio · document · sticker · voice · gif). Optional — auto-detected from the URL / content-type when omitted."
          },
          "mediaFilename": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Filename shown on the attachment (type=media). Optional — derived from the URL / uploaded file when omitted."
          },
          "pollQuestion": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "description": "Poll question (type=poll). Required for poll sends."
          },
          "pollOptions": {
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 100
            },
            "description": "Poll options (type=poll). 2–12 items."
          },
          "pollAllowMultiple": {
            "type": "boolean",
            "description": "Allow selecting multiple poll options (type=poll). Default false."
          },
          "to": {
            "type": "string"
          },
          "sendAt": {
            "type": "string",
            "format": "date-time"
          },
          "replyTo": {
            "type": "string",
            "maxLength": 256,
            "description": "Wire `key` of a prior message to quote-reply (from MessageResponse.key). Empty string = no reply."
          },
          "secret": {
            "type": "string",
            "minLength": 1,
            "maxLength": 256,
            "description": "Opaque caller id stored on the message `secret` and carried into the WhatsApp messageSecret."
          }
        },
        "required": [
          "type",
          "to"
        ],
        "additionalProperties": false
      },
      "CreateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.queued",
                "message.sending",
                "message.delivered",
                "message.failed",
                "message.read",
                "session.connected",
                "session.disconnected",
                "campaign.started",
                "campaign.paused",
                "campaign.resumed",
                "campaign.completed",
                "campaign.aborted",
                "new_message_received_webhook",
                "message_reaction_webhook",
                "ack_changed_webhook",
                "participant_joined_via_link_webhook",
                "participant_added_by_admin_webhook",
                "participant_left_group_webhook",
                "participant_kicked_from_group_webhook",
                "group_admin_changed_webhook",
                "group_name_changed_webhook",
                "group_description_changed_webhook",
                "group_message_pinned_webhook",
                "poll_vote_webhook",
                "reply_to_my_message_webhook",
                "message_deleted_revoked_webhook",
                "message_edited_webhook"
              ]
            },
            "minItems": 1
          },
          "description": {
            "type": "string",
            "maxLength": 120
          }
        },
        "required": [
          "url",
          "events"
        ],
        "additionalProperties": false
      },
      "UpdateWebhookRequest": {
        "type": "object",
        "properties": {
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string",
              "enum": [
                "message.queued",
                "message.sending",
                "message.delivered",
                "message.failed",
                "message.read",
                "session.connected",
                "session.disconnected",
                "campaign.started",
                "campaign.paused",
                "campaign.resumed",
                "campaign.completed",
                "campaign.aborted",
                "new_message_received_webhook",
                "message_reaction_webhook",
                "ack_changed_webhook",
                "participant_joined_via_link_webhook",
                "participant_added_by_admin_webhook",
                "participant_left_group_webhook",
                "participant_kicked_from_group_webhook",
                "group_admin_changed_webhook",
                "group_name_changed_webhook",
                "group_description_changed_webhook",
                "group_message_pinned_webhook",
                "poll_vote_webhook",
                "reply_to_my_message_webhook",
                "message_deleted_revoked_webhook",
                "message_edited_webhook"
              ]
            },
            "minItems": 1
          },
          "description": {
            "type": "string",
            "nullable": true,
            "maxLength": 120
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ]
          }
        },
        "additionalProperties": false
      },
      "WebhookCreateResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          },
          "secret": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "description",
          "status",
          "created_at",
          "secret"
        ],
        "additionalProperties": false
      },
      "WebhookResponse": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "url": {
            "type": "string"
          },
          "events": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "description": {
            "type": "string",
            "nullable": true
          },
          "status": {
            "type": "string",
            "enum": [
              "enabled",
              "disabled"
            ]
          },
          "created_at": {
            "type": "string",
            "format": "date-time"
          }
        },
        "required": [
          "id",
          "url",
          "events",
          "description",
          "status",
          "created_at"
        ],
        "additionalProperties": false
      }
    }
  }
}