{
  "openapi": "3.0.3",
  "info": {
    "title": "AndraiBot WhatsApp API",
    "version": "1.0.0",
    "description": "Bearer tokens are app scoped. All operations enforce current account grants. New apps are denied until explicitly granted. Sends require expected linked identity and idempotency key. Uncertain sends must never be automatically retried."
  },
  "servers": [
    {
      "url": "/"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/v1/accounts": {
      "get": {
        "operationId": "listAccounts",
        "summary": "List explicitly granted accounts",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Account"
                  }
                },
                "example": [
                  {
                    "id": 1,
                    "name": "Operations",
                    "status": {
                      "state": "connected",
                      "account": "40700000000@s.whatsapp.net",
                      "name": "Operations",
                      "syncing": false
                    }
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/v1/accounts/{accountId}": {
      "get": {
        "operationId": "accountStatus",
        "summary": "Read granted connection status; no QR data",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                },
                "example": {
                  "state": "connected",
                  "account": "40700000000@s.whatsapp.net",
                  "name": "Operations",
                  "syncing": false
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/conversations": {
      "get": {
        "operationId": "listConversations",
        "summary": "Discover destinations with send OR read permission",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Conversation"
                  }
                },
                "example": [
                  {
                    "jid": "123456@g.us",
                    "name": "Operations",
                    "kind": "group",
                    "phone": "",
                    "updatedAt": "2026-10-22T12:00:00Z"
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/v1/accounts/{accountId}/refresh": {
      "post": {
        "operationId": "refreshConversations",
        "summary": "Refresh discovery for a granted account",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OK"
                },
                "example": {
                  "ok": true
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "accountId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/v1/channels": {
      "get": {
        "operationId": "listChannels",
        "summary": "List private app-owned channels on granted accounts",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Channel"
                  }
                },
                "example": [
                  {
                    "id": 7,
                    "accountId": 1,
                    "account": "40700000000@s.whatsapp.net",
                    "name": "Operations",
                    "jid": "123456@g.us",
                    "destination": "123456@g.us",
                    "kind": "group",
                    "createdAt": "2026-10-22T12:00:00Z"
                  }
                ]
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      },
      "post": {
        "operationId": "createChannel",
        "summary": "Create private channel; does not grant destination permission",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Channel"
                },
                "example": {
                  "id": 7,
                  "accountId": 1,
                  "account": "40700000000@s.whatsapp.net",
                  "name": "Operations",
                  "jid": "123456@g.us",
                  "destination": "123456@g.us",
                  "kind": "group",
                  "createdAt": "2026-10-22T12:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/CreateChannel"
              },
              "example": {
                "accountId": 1,
                "expectedAccount": "40700000000@s.whatsapp.net",
                "name": "Operations",
                "jid": "123456@g.us"
              }
            }
          }
        }
      }
    },
    "/v1/channels/{channelId}": {
      "get": {
        "operationId": "getChannel",
        "summary": "Retrieve private channel",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Channel"
                },
                "example": {
                  "id": 7,
                  "accountId": 1,
                  "account": "40700000000@s.whatsapp.net",
                  "name": "Operations",
                  "jid": "123456@g.us",
                  "destination": "123456@g.us",
                  "kind": "group",
                  "createdAt": "2026-10-22T12:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "channelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      },
      "patch": {
        "operationId": "renameChannel",
        "summary": "Rename private channel",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Channel"
                },
                "example": {
                  "id": 7,
                  "accountId": 1,
                  "account": "40700000000@s.whatsapp.net",
                  "name": "Operations",
                  "jid": "123456@g.us",
                  "destination": "123456@g.us",
                  "kind": "group",
                  "createdAt": "2026-10-22T12:00:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "channelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/RenameChannel"
              },
              "example": {
                "name": "Dispatch"
              }
            }
          }
        }
      },
      "delete": {
        "operationId": "deleteChannel",
        "summary": "Delete private channel; receipts remain",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/OK"
                },
                "example": {
                  "ok": true
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "channelId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "integer",
              "minimum": 1
            }
          }
        ]
      }
    },
    "/v1/deliveries": {
      "post": {
        "operationId": "sendText",
        "summary": "Send text with mandatory app prefix and durable idempotency",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                },
                "example": {
                  "id": 19,
                  "accountId": 1,
                  "account": "40700000000@s.whatsapp.net",
                  "destination": "123456@g.us",
                  "state": "sent",
                  "messageId": "WA-ACK-ID",
                  "timestamp": "2026-10-22T12:01:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "Idempotency-Key",
            "in": "header",
            "required": true,
            "schema": {
              "type": "string",
              "minLength": 1,
              "maxLength": 200,
              "pattern": "^[A-Za-z0-9._:-]{1,200}$"
            },
            "example": "invoice-batch-581"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SendRequest"
              },
              "example": {
                "accountId": 1,
                "expectedAccount": "40700000000@s.whatsapp.net",
                "channelId": 7,
                "text": "Report ready"
              }
            }
          }
        }
      }
    },
    "/v1/deliveries/{key}": {
      "get": {
        "operationId": "deliveryOutcome",
        "summary": "Read recorded outcome by idempotency key with current send permission",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Delivery"
                },
                "example": {
                  "id": 19,
                  "accountId": 1,
                  "account": "40700000000@s.whatsapp.net",
                  "destination": "123456@g.us",
                  "state": "sent",
                  "messageId": "WA-ACK-ID",
                  "timestamp": "2026-10-22T12:01:00Z"
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "key",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ]
      }
    },
    "/v1/messages": {
      "get": {
        "operationId": "pollMessages",
        "summary": "Poll newly received text with current read permissions",
        "responses": {
          "200": {
            "description": "Recorded result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Page"
                },
                "example": {
                  "items": [],
                  "cursor": "opaque-durable-cursor",
                  "hasMore": false
                }
              }
            }
          },
          "400": {
            "description": "Validation error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, revoked or suspended bearer token",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "403": {
            "description": "Permission denied",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "App-owned resource not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Account mismatch, uncertain delivery or idempotency conflict",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "410": {
            "description": "Cursor expired or invalid; restart explicitly without cursor",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal failure",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Account unavailable",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        },
        "parameters": [
          {
            "name": "cursor",
            "in": "query",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100,
              "default": 50
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer"
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "code",
              "message"
            ],
            "properties": {
              "code": {
                "type": "string",
                "enum": [
                  "validation",
                  "unauthorized",
                  "permission_denied",
                  "not_found",
                  "account_unavailable",
                  "account_mismatch",
                  "delivery_uncertain",
                  "idempotency_conflict",
                  "cursor_expired",
                  "internal_error"
                ]
              },
              "message": {
                "type": "string"
              }
            }
          },
          "delivery": {
            "$ref": "#/components/schemas/Delivery"
          }
        }
      },
      "Status": {
        "type": "object",
        "required": [
          "state",
          "account",
          "name",
          "syncing"
        ],
        "properties": {
          "state": {
            "type": "string"
          },
          "account": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "syncing": {
            "type": "boolean"
          },
          "lastSync": {
            "type": "string",
            "format": "date-time"
          },
          "error": {
            "type": "string"
          }
        },
        "example": {
          "state": "connected",
          "account": "40700000000@s.whatsapp.net",
          "name": "Operations",
          "syncing": false
        }
      },
      "Account": {
        "type": "object",
        "required": [
          "id",
          "name"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "name": {
            "type": "string"
          },
          "status": {
            "$ref": "#/components/schemas/Status"
          },
          "state": {
            "type": "string"
          }
        },
        "example": {
          "id": 1,
          "name": "Operations",
          "status": {
            "state": "connected",
            "account": "40700000000@s.whatsapp.net",
            "name": "Operations",
            "syncing": false
          }
        }
      },
      "Conversation": {
        "type": "object",
        "required": [
          "jid",
          "name",
          "kind",
          "phone",
          "updatedAt"
        ],
        "properties": {
          "jid": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "phone": {
            "type": "string"
          },
          "updatedAt": {
            "type": "string"
          }
        },
        "example": {
          "jid": "123456@g.us",
          "name": "Operations",
          "kind": "group",
          "phone": "",
          "updatedAt": "2026-10-22T12:00:00Z"
        }
      },
      "Channel": {
        "type": "object",
        "required": [
          "id",
          "accountId",
          "account",
          "name",
          "jid",
          "destination",
          "kind",
          "createdAt"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "account": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "jid": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "createdAt": {
            "type": "string"
          }
        },
        "example": {
          "id": 7,
          "accountId": 1,
          "account": "40700000000@s.whatsapp.net",
          "name": "Operations",
          "jid": "123456@g.us",
          "destination": "123456@g.us",
          "kind": "group",
          "createdAt": "2026-10-22T12:00:00Z"
        }
      },
      "Delivery": {
        "type": "object",
        "required": [
          "id",
          "accountId",
          "account",
          "destination",
          "state",
          "messageId"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "account": {
            "type": "string"
          },
          "destination": {
            "type": "string"
          },
          "messageId": {
            "type": "string"
          },
          "state": {
            "type": "string",
            "enum": [
              "sent",
              "uncertain"
            ]
          },
          "timestamp": {
            "type": "string",
            "format": "date-time"
          }
        },
        "example": {
          "id": 19,
          "accountId": 1,
          "account": "40700000000@s.whatsapp.net",
          "destination": "123456@g.us",
          "state": "sent",
          "messageId": "WA-ACK-ID",
          "timestamp": "2026-10-22T12:01:00Z"
        }
      },
      "SendRequest": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "accountId",
          "expectedAccount",
          "text"
        ],
        "properties": {
          "accountId": {
            "type": "integer",
            "minimum": 1
          },
          "expectedAccount": {
            "type": "string",
            "minLength": 1
          },
          "channelId": {
            "type": "integer",
            "minimum": 1
          },
          "destination": {
            "type": "string"
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "maxLength": 64000
          }
        },
        "oneOf": [
          {
            "required": [
              "channelId"
            ],
            "not": {
              "required": [
                "destination"
              ]
            }
          },
          {
            "required": [
              "destination"
            ],
            "not": {
              "required": [
                "channelId"
              ]
            }
          }
        ],
        "example": {
          "accountId": 1,
          "expectedAccount": "40700000000@s.whatsapp.net",
          "channelId": 7,
          "text": "Report ready"
        }
      },
      "Incoming": {
        "type": "object",
        "required": [
          "id",
          "accountId",
          "account",
          "jid",
          "sender",
          "messageId",
          "timestamp",
          "text"
        ],
        "properties": {
          "id": {
            "type": "integer",
            "format": "int64"
          },
          "accountId": {
            "type": "integer",
            "format": "int64"
          },
          "account": {
            "type": "string"
          },
          "jid": {
            "type": "string"
          },
          "sender": {
            "type": "string"
          },
          "messageId": {
            "type": "string"
          },
          "timestamp": {
            "type": "string"
          },
          "text": {
            "type": "string"
          }
        },
        "example": {
          "id": 12,
          "accountId": 1,
          "account": "40700000000@s.whatsapp.net",
          "jid": "123456@g.us",
          "sender": "40712345678@s.whatsapp.net",
          "messageId": "WA-IN-ID",
          "timestamp": "2026-10-22T12:00:00Z",
          "text": "Received"
        }
      },
      "Page": {
        "type": "object",
        "required": [
          "items",
          "cursor",
          "hasMore"
        ],
        "properties": {
          "items": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Incoming"
            }
          },
          "cursor": {
            "type": "string"
          },
          "hasMore": {
            "type": "boolean"
          }
        },
        "example": {
          "items": [],
          "cursor": "opaque-durable-cursor",
          "hasMore": false
        }
      },
      "OK": {
        "type": "object",
        "required": [
          "ok"
        ],
        "properties": {
          "ok": {
            "type": "boolean"
          }
        },
        "example": {
          "ok": true
        }
      },
      "CreateChannel": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "accountId",
          "expectedAccount",
          "name",
          "jid"
        ],
        "properties": {
          "accountId": {
            "type": "integer",
            "minimum": 1
          },
          "expectedAccount": {
            "type": "string",
            "minLength": 1
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          },
          "jid": {
            "type": "string"
          }
        },
        "example": {
          "accountId": 1,
          "expectedAccount": "40700000000@s.whatsapp.net",
          "name": "Operations",
          "jid": "123456@g.us"
        }
      },
      "RenameChannel": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "name"
        ],
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "maxLength": 100
          }
        },
        "example": {
          "name": "Dispatch"
        }
      }
    }
  }
}
