# Listar status

GET /status-posts

Os status (stories) que a inbox vê: os dos contatos (`chat_id: status@broadcast`) e os dos grupos (`chat_id` é o grupo), numa lista só, do mais novo ao mais antigo, no formato do evento `status_post.received` (o status de grupo já vem desembrulhado). Vêm os das últimas 24 horas, como no WhatsApp. Status de grupo de campanha que ainda não saiu (agendado, na fila ou com falha) não entra. A foto e o vídeo trazem a miniatura (`thumbnail`), para mostrar a prévia sem baixar a mídia.

Paginação por cursor, como em `GET /messages`.

## Autenticação

```json
[
  {
    "token": []
  }
]
```

```json
{
  "token": {
    "name": "token",
    "type": "apiKey",
    "in": "header"
  }
}
```

## Parâmetros

```json
[
  {
    "name": "limit",
    "in": "query",
    "schema": {
      "type": "integer",
      "minimum": 1,
      "maximum": 200,
      "default": 50
    },
    "description": "Itens por página (1 a 200; padrão 50)."
  },
  {
    "name": "cursor",
    "in": "query",
    "schema": {
      "type": "string"
    },
    "description": "O `next_cursor` da página anterior. Sem ele, vem a primeira página."
  }
]
```

## Respostas

```json
{
  "200": {
    "description": "Os status.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioStatusPostList"
        }
      }
    }
  },
  "400": {
    "description": "`limit` fora de 1 a 200 ou `cursor` inválido.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "invalid_request",
          "message": "limit deve ser de 1 a 200."
        }
      }
    }
  },
  "401": {
    "description": "Token inválido.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unauthorized",
          "message": "Token inválido."
        }
      }
    }
  },
  "429": {
    "$ref": "#/components/responses/RateLimited"
  },
  "500": {
    "description": "falha ao buscar os status.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "internal_error",
          "message": "falha ao buscar os status."
        }
      }
    }
  },
  "501": {
    "$ref": "#/components/responses/CloudUnsupported"
  }
}
```

**Estado:** Disponível

## Compatibilidade de canais

| Canal | Compatível | Observação |
|---|---|---|
| WhatsApp (Web) | Sim |  |
| WhatsApp (API oficial) | Não | A API oficial não publica status. |
| Instagram | Não |  |
| Messenger | Não |  |
| Telegram | Não |  |

## Eventos que esta rota gera

Nenhum. Esta rota não gera evento no webhook (nem em `GET /events`): o resultado vem só na resposta.

## Antes e depois (uazapi → Orkesio)

Na uazapi: `POST /message/find`.

- Rota própria: antes, uma busca em `status@broadcast` e outra pelo tipo `GroupStatusMessage`, com o status de grupo embrulhado.

## #/components/schemas/OrkesioStatusPostList

```json
{
  "type": "object",
  "properties": {
    "status_posts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioMessage"
      },
      "description": "Os status, do mais novo ao mais antigo, no formato da mensagem."
    },
    "next_cursor": {
      "type": "string",
      "description": "Cursor da próxima página: mande em `cursor`. Ausente na última página."
    }
  },
  "required": [
    "status_posts"
  ],
  "additionalProperties": false,
  "description": "Página de status (stories)."
}
```

## #/components/schemas/OrkesioMessage

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id da mensagem no canal: no WhatsApp, o id do WhatsApp; na API oficial, o `wamid`; no Instagram e no Messenger, o `mid`; no Telegram, a conversa e o número da mensagem (`<conversa>_<número>`, e `b<conversa>_<número>` no Telegram Business). É único dentro da inbox: a mesma mensagem pode chegar com o mesmo `id` em duas inboxes (um grupo com dois números seus), então guarde pela inbox e pelo `id`. Busca e ações valem para o número atual da inbox."
    },
    "chat_id": {
      "type": "string",
      "description": "Id da conversa (o `id` de `GET /chats/{chat_id}`). Em grupo, o grupo; quem escreveu vem em `author`. No webhook e no `/events`, a conversa vem inteira ao lado da mensagem, em `data.chat`."
    },
    "author": {
      "$ref": "#/components/schemas/OrkesioParticipant"
    },
    "direction": {
      "type": "string",
      "enum": [
        "in",
        "out"
      ],
      "description": "`in`: escrita pelo contato. `out`: escrita pela inbox."
    },
    "sent_by": {
      "type": "string",
      "enum": [
        "api",
        "automation",
        "campaign",
        "phone",
        "web",
        "user"
      ],
      "description": "Só em `out`: quem mandou. `api` (rota de envio), `automation` (IA, fluxo ou resposta rápida, com `automation`), `campaign` (disparo em massa, com `campaign_id`), `phone` (o celular), `web` (outro aparelho conectado, como o WhatsApp Web ou o Desktop) ou `user` (pessoa logada no painel; **em breve**, com o login por usuário, junto do campo `user`)."
    },
    "sent_at": {
      "type": "string",
      "format": "date-time",
      "description": "Quando a mensagem foi enviada. ISO 8601 em UTC com milissegundos."
    },
    "status": {
      "type": "string",
      "enum": [
        "scheduled",
        "queued",
        "pending",
        "sent",
        "delivered",
        "read",
        "played",
        "failed"
      ],
      "description": "Estado atual (busca e resposta do envio). `scheduled` e `queued` são envios que ainda não saíram. As mudanças chegam em `message.status`."
    },
    "error": {
      "$ref": "#/components/schemas/OrkesioError"
    },
    "scheduled_at": {
      "type": "string",
      "format": "date-time",
      "description": "Quando o envio agendado sai (só em `scheduled`). ISO 8601 em UTC com milissegundos."
    },
    "campaign_id": {
      "type": "string",
      "description": "A campanha (`/campaigns`) que enviou ou vai enviar a mensagem: o `id` dela, para acompanhar ou cancelar."
    },
    "deleted": {
      "type": "boolean",
      "description": "Apagada para todos."
    },
    "pinned": {
      "type": "boolean",
      "description": "Fixada na conversa."
    },
    "pinned_until": {
      "type": "string",
      "format": "date-time",
      "description": "Fixada até, quando o prazo é conhecido (fixações a partir desta versão). ISO 8601 em UTC com milissegundos."
    },
    "forwarded_from": {
      "type": "object",
      "properties": {
        "newsletter_id": {
          "type": "string",
          "description": "Canal de origem."
        },
        "name": {
          "type": "string",
          "description": "Nome do canal."
        }
      },
      "additionalProperties": false,
      "description": "**Só WhatsApp.** Encaminhada de uma newsletter do WhatsApp: qual.",
      "x-only": "whatsapp"
    },
    "category": {
      "type": "string",
      "enum": [
        "conversation",
        "call",
        "reaction",
        "event",
        "unsent"
      ],
      "description": "A classe da mensagem, dada pela api (não deduza do `type`): `conversation` (balão da conversa, apagado inclusive), `call` (ligação), `reaction`, `event` (registro que não é balão: edição, voto de enquete, fixar, aviso de grupo e os `system`) ou `unsent` (envio que ainda não chegou ao canal: agendado, na fila, enviando, com falha ou cancelado). Só `conversation` não apagada aceita resposta, reação, edição e fixar. O `kind` de `interactive_reply`, `share` e `system` é outro campo."
    },
    "type": {
      "type": "string",
      "enum": [
        "text",
        "image",
        "video",
        "audio",
        "voice",
        "document",
        "sticker",
        "location",
        "contacts",
        "poll",
        "poll_vote",
        "buttons",
        "list",
        "carousel",
        "location_request",
        "flow",
        "interactive_reply",
        "order",
        "product",
        "payment",
        "group_invite",
        "newsletter_invite",
        "event_response",
        "sticker_pack",
        "video_note",
        "live_location",
        "scheduled_call",
        "album",
        "share",
        "story_mention",
        "event",
        "reaction",
        "call",
        "group_participant",
        "system",
        "unavailable",
        "template",
        "unknown"
      ],
      "description": "Tipo da mensagem: diz quais campos do tipo vêm soltos na mensagem (`text`, `url`, `latitude`, `choices`...)."
    },
    "album_id": {
      "type": "string",
      "description": "O álbum de que esta mídia faz parte: o `id` da mensagem `album`. Várias fotos e vídeos enviados juntos chegam como um álbum mais uma mensagem por mídia, cada uma com este campo."
    },
    "reply_to": {
      "type": "string",
      "description": "A mensagem respondida: o `id` dela. O resumo (quem, tipo, prévia) vem em `quoted`."
    },
    "quoted": {
      "allOf": [
        {
          "$ref": "#/components/schemas/OrkesioMessageRef"
        }
      ],
      "readOnly": true,
      "description": "Resumo da mensagem respondida (`author`, `direction`, `type`, `preview`), para mostrar sem buscar; vem quando a api conhece a citada. Resposta a um story do Instagram: `quoted.story`, sem `reply_to`."
    },
    "reactions": {
      "type": "array",
      "readOnly": true,
      "description": "As reações que a mensagem recebeu, uma linha por emoji (mais reações primeiro): o último emoji de cada pessoa vale. Vem na busca (`GET /messages`), contando as reações de até 7 dias depois da mensagem mais nova da página naquela conversa (numa conversa muito movimentada a conta pode ficar incompleta); os eventos mandam cada reação como uma mensagem `reaction`. Ausente sem reação.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "emoji",
          "count",
          "mine"
        ],
        "properties": {
          "emoji": {
            "type": "string",
            "description": "O emoji."
          },
          "count": {
            "type": "integer",
            "description": "Quantas pessoas reagiram com ele."
          },
          "mine": {
            "type": "boolean",
            "description": "A inbox está entre quem reagiu com este emoji."
          }
        }
      }
    },
    "mentions": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Número ou LID mencionado."
      },
      "description": "Menções."
    },
    "forwarded": {
      "type": "boolean",
      "description": "Encaminhada."
    },
    "edited": {
      "type": "boolean",
      "description": "Já foi editada (o texto é o da última edição)."
    },
    "device": {
      "type": "string",
      "enum": [
        "android",
        "ios",
        "web",
        "desktop"
      ],
      "description": "**Só WhatsApp.** Aparelho de quem enviou, quando dá para saber (só `whatsapp_web`).",
      "x-only": "whatsapp"
    },
    "referral": {
      "$ref": "#/components/schemas/OrkesioReferral"
    },
    "track_source": {
      "type": "string",
      "description": "**Seu** rastreamento: o `track_source` que você mandou no envio, devolvido aqui para reconhecer a mensagem. Só em mensagem enviada (`direction: out`). Não confundir com `referral`, que vem da Meta."
    },
    "track_id": {
      "type": "string",
      "description": "O `track_id` que você mandou no envio."
    },
    "send_request": {
      "type": "object",
      "additionalProperties": true,
      "description": "Só no `GET /messages`, nas mensagens enviadas pela API nos últimos 7 dias: o pedido do envio como foi guardado (opções, texto antes de trocar os placeholders), sem o base64 dos arquivos."
    },
    "automation": {
      "type": "object",
      "properties": {
        "agent_id": {
          "type": "string",
          "description": "Agente de IA que respondeu."
        },
        "flow_id": {
          "type": "string",
          "description": "Fluxo que enviou."
        },
        "turn": {
          "type": "string",
          "description": "Só no `GET /messages`, nas mensagens que a IA mandou: o `id` da mensagem do contato que a rodada respondeu, onde fica o registro completo."
        },
        "outcome": {
          "type": "object",
          "additionalProperties": false,
          "description": "Só no `GET /messages`, na mensagem do contato que a IA respondeu: o que a rodada da IA fez.",
          "properties": {
            "status": {
              "type": "string",
              "enum": [
                "sent",
                "cancelled",
                "error",
                "empty"
              ],
              "description": "`sent` (enviou algo), `cancelled` (descartada: a conversa pausou ou um fluxo começou), `error` (o provedor falhou) ou `empty` (nada a enviar)."
            },
            "texts": {
              "type": "integer",
              "description": "Textos enviados."
            },
            "audio": {
              "type": "boolean",
              "description": "Respondeu em áudio."
            },
            "menus": {
              "type": "integer",
              "description": "Menus enviados."
            },
            "files": {
              "type": "integer",
              "description": "Arquivos enviados."
            },
            "handoff": {
              "type": "string",
              "description": "O resumo, quando chamou um humano."
            },
            "lead": {
              "type": "array",
              "items": {
                "type": "string"
              },
              "description": "O que gravou no lead (`lead_email = ana@x.com`)."
            },
            "detail": {
              "type": "string",
              "description": "Por que cancelou, ou o erro."
            }
          }
        },
        "request": {
          "description": "Só no `GET /messages`, na mensagem do contato que a IA respondeu: o pedido mandado ao provedor da IA, como foi gravado."
        },
        "response": {
          "description": "Só no `GET /messages`, na mensagem do contato que a IA respondeu: a resposta do provedor da IA, como foi gravada."
        }
      },
      "additionalProperties": false,
      "description": "Qual automação mandou (`sent_by: automation`): `agent_id` é o agente de IA; `flow_id`, o fluxo. Também na mensagem do contato que a IA respondeu, com o `agent_id`. No `GET /messages` vem a rodada da IA: nas mensagens que a IA mandou, `turn`; na mensagem do contato, o registro completo (`outcome`, `request`, `response`)."
    },
    "warning": {
      "type": "object",
      "description": "Só na resposta do `POST /messages`, quando parte do envio falhou (`partial_send`, Messenger e Instagram). A mensagem saiu.",
      "properties": {
        "error": {
          "type": "string",
          "example": "partial_send"
        },
        "message": {
          "type": "string",
          "example": "A mídia foi enviada, mas a legenda não (meta: (#100) ...). Mande a legenda como texto."
        }
      },
      "required": [
        "error",
        "message"
      ]
    },
    "display_text": {
      "type": "string",
      "readOnly": true,
      "description": "Tudo o que aparece na tela num texto só, com a formatação do WhatsApp (`*negrito*`, `_itálico_`): cabeçalho, texto, rodapé, opções. Montado pela api para n8n, IA e CRM; não existe no envio."
    }
  },
  "required": [
    "id",
    "chat_id",
    "author",
    "direction",
    "sent_at",
    "type"
  ],
  "description": "Mensagem. Os campos do tipo (`text`, `url`, `latitude`, `choices`...) ficam soltos, ao lado dos campos da mensagem; `type` diz quais valem. Campos vazios ficam fora do JSON.",
  "oneOf": [
    {
      "properties": {
        "type": {
          "const": "template"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentTemplate"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "text"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentText"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "image"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentImage"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "video"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentVideo"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "audio"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentAudio"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "voice"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentVoice"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "document"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentDocument"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "sticker"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentSticker"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "location"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentLocation"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "contacts"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentContacts"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "poll"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentPoll"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "poll_vote"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentPollVote"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "buttons"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentButtons"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "list"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentList"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "carousel"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentCarousel"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "location_request"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentLocationRequest"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "flow"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentFlow"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "interactive_reply"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentInteractiveReply"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "order"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentOrder"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "product"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentProduct"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "payment"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentPayment"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "group_invite"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentGroupInvite"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "newsletter_invite"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentNewsletterInvite"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "event_response"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentEventResponse"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "sticker_pack"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentStickerPack"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "video_note"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentVideoNote"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "live_location"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentLiveLocation"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "scheduled_call"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentScheduledCall"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "album"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentAlbum"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "share"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentShare"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "story_mention"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentStoryMention"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "event"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentEvent"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "reaction"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentReaction"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "call"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentCall"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "group_participant"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentGroupParticipant"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "system"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentSystem"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "const": "unavailable"
        }
      },
      "allOf": [
        {
          "$ref": "#/components/schemas/MessageContentUnavailable"
        }
      ]
    },
    {
      "properties": {
        "type": {
          "enum": [
            "unknown"
          ]
        }
      }
    }
  ],
  "unevaluatedProperties": false
}
```

## #/components/schemas/OrkesioParticipant

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Identificador da pessoa no canal (opaco). No WhatsApp é `<número>@s.whatsapp.net` ou `<BSUID>@bsuid`; em outros canais, o id deles. Não conte com ele ser telefone: use `phone`."
    },
    "phone": {
      "type": "string",
      "description": "Telefone (só dígitos), quando o canal informa."
    },
    "username": {
      "type": "string",
      "description": "Nome de usuário (@), quando o canal informa."
    },
    "lid": {
      "type": "string",
      "description": "**Só WhatsApp.** LID, quando conhecido.",
      "x-only": "whatsapp"
    },
    "name": {
      "type": "string",
      "description": "Nome visível (push name), quando conhecido."
    },
    "picture_url": {
      "type": "string",
      "description": "Foto de perfil, quando conhecida."
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false,
  "description": "Pessoa: autor de mensagem, participante de grupo, quem fez uma ação."
}
```

## #/components/schemas/OrkesioError

```json
{
  "type": "object",
  "properties": {
    "error": {
      "type": "string",
      "description": "Código estável do erro, em inglês e `snake_case`. Os de uso geral: `invalid_request` (400): pedido inválido: JSON malformado, campo desconhecido ou valor fora do permitido (o detalhe em `message`; o campo em `field`, quando é um só); `unauthorized` (401): `token` ou `admintoken` ausente ou inválido; `forbidden` (403): o token não pode fazer isso (no servidor de demonstração, por exemplo); `not_admin` (403): o WhatsApp recusou por falta de permissão no grupo ou na newsletter; `account_restricted` (403): o WhatsApp restringiu a conta de iniciar conversas novas (mandar para quem já conversa continua valendo; até quando, em `GET /inbox/limits`); `new_chat_limit` (403): a conta atingiu a cota do WhatsApp de conversas novas neste ciclo (veja `GET /inbox/limits`); os dois também no `error` de `OrkesioMessage` e de `message.status`, e não adianta repetir o envio; `payment_required` (403): na API oficial, a Meta recusou o envio por um problema no pagamento da conta do WhatsApp Business (erro 131042 da Meta); acerte a forma de pagamento no gerenciador da Meta, porque repetir não adianta; também no `error` de `OrkesioMessage` e de `message.status`; `whatsapp_rejected` (400): o WhatsApp recusou a mudança pedida (o campo, em `field`, quando é um só); `not_found` (404): o recurso não existe nesta inbox; `conflict` (409): o recurso já existe ou mudou (id em uso, inbox de outro canal); `inbox_not_paired` (409): a inbox ainda não conectou um número; `payload_too_large` (413): o corpo passou do limite; `canceled` e `expired`: só no `error` de `OrkesioMessage` e de `message.status` (envio cancelado antes de sair, ou que passou do prazo na fila); `rate_limited` (429): muitos pedidos; espere o `Retry-After`; `internal_error` (500): falha inesperada na api; tente de novo; `send_failed` (500): o envio falhou (o motivo em `message`); também no `error` de `OrkesioMessage` e de `message.status`; `unsupported_for_channel` (501): o canal da inbox não atende esta rota ou este tipo de mensagem; `meta_error` (502): a Meta recusou ou não respondeu; `disconnected` (503): a inbox está desconectada (sem sessão do WhatsApp, ou token do canal oficial vencido); `unavailable` (503 ou 504): o WhatsApp não respondeu a tempo, ou algo em andamento impede agora; tente de novo. Cada rota lista os códigos próprios dela (`outside_window`, `number_invalid`, `flow_invalid`...). A lista pode crescer: trate código desconhecido pelo status HTTP."
    },
    "message": {
      "type": "string",
      "description": "Descrição para pessoas (às vezes o texto do WhatsApp ou da Meta). Não compare o texto: use `error`."
    },
    "field": {
      "type": "string",
      "description": "O campo do pedido que causou o erro, quando é um só (por exemplo, o campo que o WhatsApp recusou num `PATCH`)."
    }
  },
  "required": [
    "error",
    "message"
  ],
  "additionalProperties": true,
  "description": "O objeto de erro da Orkesio, o mesmo em todo lugar: o corpo das respostas de erro e o `error` de `OrkesioMessage`, `message.status` e `message.failed`. Algumas rotas juntam campos próprios (`request_id`, `errors`...)."
}
```

## #/components/schemas/OrkesioMessageRef

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id da mensagem (o mesmo `id` da mensagem)."
    },
    "author": {
      "$ref": "#/components/schemas/OrkesioParticipant"
    },
    "direction": {
      "type": "string",
      "enum": [
        "in",
        "out"
      ],
      "description": "O lado da mensagem, como `OrkesioMessage.direction`: `in` (recebida) ou `out` (da inbox). Vem quando a api sabe quem mandou."
    },
    "type": {
      "type": "string",
      "description": "Tipo da mensagem (mesma lista de `type`). `story` quando a resposta é a um story do Instagram (veja `story`)."
    },
    "preview": {
      "type": "string",
      "description": "Texto ou legenda, para mostrar sem buscar a mensagem."
    },
    "story": {
      "type": "object",
      "x-only": "instagram",
      "description": "**Só Instagram.** O contato respondeu a um story da conta. O link do story expira.",
      "properties": {
        "url": {
          "type": "string",
          "description": "Link do story (expira)."
        },
        "id": {
          "type": "string",
          "description": "Id do story."
        }
      }
    }
  },
  "additionalProperties": false,
  "description": "Referência a uma mensagem, com resumo opcional (`author`, `direction`, `type`, `preview`) para mostrar sem buscar. O resumo vem quando a api conhece a mensagem; em `message.status` e `group.receipts` vem só o id. Numa resposta a story (Instagram) vem `story` em vez de `id`."
}
```

## #/components/schemas/OrkesioReferral

```json
{
  "type": "object",
  "properties": {
    "source_type": {
      "type": "string",
      "description": "Tipo da origem informado pela Meta: `ad` (anúncio) ou `post` (publicação).",
      "enum": [
        "ad",
        "post"
      ]
    },
    "source_id": {
      "type": "string",
      "description": "Id do anúncio ou da publicação na Meta."
    },
    "source_url": {
      "type": "string",
      "description": "Link do anúncio ou da publicação."
    },
    "headline": {
      "type": "string",
      "description": "Título do anúncio."
    },
    "body": {
      "type": "string",
      "description": "Texto do anúncio."
    },
    "media_type": {
      "type": "string",
      "enum": [
        "image",
        "video"
      ],
      "description": "Mídia do anúncio."
    },
    "media_url": {
      "type": "string",
      "description": "Link da imagem ou do vídeo do anúncio."
    },
    "thumbnail_url": {
      "type": "string",
      "description": "Miniatura do anúncio."
    },
    "ctwa_clid": {
      "type": "string",
      "description": "Id do clique no anúncio (click-to-WhatsApp). É o que se devolve à Meta (API de Conversões) para atribuir venda ou lead ao anúncio. Não vem em anúncio de Status."
    },
    "welcome_message": {
      "type": "string",
      "description": "Mensagem de boas-vindas configurada no anúncio, quando houver."
    }
  },
  "additionalProperties": false,
  "description": "Origem do contato vinda da Meta: a conversa começou por um anúncio ou uma publicação (click-to-WhatsApp). Igual nos dois canais: no `whatsapp_web` sai do `externalAdReply` da mensagem; no `whatsapp_cloud`, do `referral` da Meta."
}
```

## #/components/schemas/MessageContentTemplate

```json
{
  "title": "modelo",
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O corpo do modelo, já com os parâmetros."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    }
  }
}
```

## #/components/schemas/MessageContentText

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto da mensagem (com a formatação do WhatsApp)."
    },
    "style": {
      "type": "object",
      "properties": {
        "background_color": {
          "type": "string",
          "description": "Cor do fundo."
        },
        "text_color": {
          "type": "string",
          "description": "Cor do texto."
        },
        "font": {
          "type": "integer",
          "description": "Fonte."
        }
      },
      "additionalProperties": false,
      "description": "Só em post de status de texto."
    },
    "link_preview": {
      "type": "object",
      "properties": {
        "url": {
          "type": "string",
          "description": "Link."
        },
        "title": {
          "type": "string",
          "description": "Título."
        },
        "description": {
          "type": "string",
          "description": "Descrição."
        },
        "thumbnail": {
          "type": "string",
          "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca não a traz."
        }
      },
      "required": [
        "url"
      ],
      "additionalProperties": false
    }
  },
  "required": [
    "text"
  ],
  "title": "texto"
}
```

## #/components/schemas/MessageContentImage

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "imagem"
}
```

## #/components/schemas/MessageContentVideo

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "vídeo"
}
```

## #/components/schemas/MessageContentAudio

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "áudio"
}
```

## #/components/schemas/MessageContentVoice

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "voz"
}
```

## #/components/schemas/MessageContentDocument

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "documento"
}
```

## #/components/schemas/MessageContentSticker

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "figurinha"
}
```

## #/components/schemas/MessageContentLocation

```json
{
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "description": "Latitude."
    },
    "longitude": {
      "type": "number",
      "description": "Longitude."
    },
    "name": {
      "type": "string",
      "description": "O nome do lugar."
    },
    "address": {
      "type": "string",
      "description": "Endereço."
    },
    "url": {
      "type": "string",
      "description": "Link."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura do mapa, JPEG em base64."
    }
  },
  "required": [
    "latitude",
    "longitude"
  ],
  "title": "localização"
}
```

## #/components/schemas/MessageContentContacts

```json
{
  "type": "object",
  "required": [
    "contacts"
  ],
  "properties": {
    "contacts": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioContactCard"
      },
      "description": "Contatos compartilhados."
    }
  },
  "title": "contatos"
}
```

## #/components/schemas/OrkesioContactCard

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Nome exibido."
    },
    "phones": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "number": {
            "type": "string",
            "description": "Número."
          },
          "wa_id": {
            "type": "string",
            "description": "Número no WhatsApp, quando informado."
          }
        },
        "required": [
          "number"
        ],
        "additionalProperties": false
      },
      "description": "Telefones."
    },
    "vcard": {
      "type": "string",
      "description": "vCard completo."
    }
  },
  "required": [
    "name"
  ],
  "additionalProperties": false,
  "description": "Contato compartilhado."
}
```

## #/components/schemas/MessageContentPoll

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A pergunta."
    },
    "choices": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Opção."
      },
      "description": "Opções."
    },
    "selectable_count": {
      "type": "integer",
      "description": "Quantas opções podem ser escolhidas (0 = várias)."
    },
    "results": {
      "type": "object",
      "readOnly": true,
      "additionalProperties": false,
      "required": [
        "options",
        "my_vote"
      ],
      "description": "Os votos: vem na busca (`GET /messages`), contando os de até 7 dias depois da mensagem mais nova da página naquela conversa (numa conversa muito movimentada a conta pode ficar incompleta); nos eventos, cada voto chega como mensagem `poll_vote`. O último voto de cada pessoa vale.",
      "properties": {
        "options": {
          "type": "array",
          "description": "Todas as opções, na ordem da enquete, com quantos votos cada uma tem.",
          "items": {
            "type": "object",
            "additionalProperties": false,
            "required": [
              "name",
              "count"
            ],
            "properties": {
              "name": {
                "type": "string",
                "description": "A opção."
              },
              "count": {
                "type": "integer",
                "description": "Quantos votos."
              }
            }
          }
        },
        "my_vote": {
          "type": "array",
          "items": {
            "type": "string"
          },
          "description": "As opções que a inbox escolheu (vazio: não votou ou tirou o voto)."
        }
      }
    }
  },
  "required": [
    "text",
    "choices"
  ],
  "title": "enquete"
}
```

## #/components/schemas/MessageContentPollVote

```json
{
  "type": "object",
  "properties": {
    "poll": {
      "$ref": "#/components/schemas/OrkesioMessageRef"
    },
    "choices": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Opção."
      },
      "description": "Opções escolhidas (vazio = voto retirado)."
    }
  },
  "required": [
    "poll",
    "choices"
  ],
  "title": "voto na enquete"
}
```

## #/components/schemas/MessageContentButtons

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto principal, acima das opções. Quando a mensagem tem cabeçalho em texto, ele vem na primeira linha, como se manda."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo do cabeçalho, quando ele é uma mídia (imagem, vídeo ou documento)."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo do cabeçalho (documentos)."
    },
    "choices": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioOption"
      },
      "description": "Opções do menu ou botões."
    }
  },
  "required": [],
  "title": "botões"
}
```

## #/components/schemas/OrkesioOption

```json
{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id."
    },
    "title": {
      "type": "string",
      "description": "Título."
    },
    "description": {
      "type": "string",
      "description": "Descrição."
    },
    "action": {
      "type": "string",
      "enum": [
        "reply",
        "url",
        "call",
        "copy"
      ],
      "description": "O que o botão faz."
    },
    "value": {
      "type": "string",
      "description": "Link, telefone ou código, conforme `action`."
    },
    "section": {
      "type": "string",
      "description": "Seção (listas)."
    }
  },
  "required": [
    "title"
  ],
  "additionalProperties": false,
  "description": "Opção de menu ou botão."
}
```

## #/components/schemas/MessageContentList

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto principal, acima das opções. Quando a mensagem tem cabeçalho em texto, ele vem na primeira linha, como se manda."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo do cabeçalho, quando ele é uma mídia (imagem, vídeo ou documento)."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo do cabeçalho (documentos)."
    },
    "choices": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioOption"
      },
      "description": "Opções do menu ou botões."
    },
    "button_text": {
      "type": "string",
      "description": "O texto do botão que abre a lista."
    }
  },
  "required": [],
  "title": "lista"
}
```

## #/components/schemas/MessageContentCarousel

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto principal, acima das opções. Quando a mensagem tem cabeçalho em texto, ele vem na primeira linha, como se manda."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo do cabeçalho, quando ele é uma mídia (imagem, vídeo ou documento)."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo do cabeçalho (documentos)."
    },
    "choices": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioOption"
      },
      "description": "Opções do menu ou botões."
    },
    "cards": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "type": {
            "type": "string",
            "enum": [
              "image",
              "video",
              "document"
            ],
            "description": "O tipo da mídia do cartão."
          },
          "mime_type": {
            "type": "string",
            "description": "Tipo do arquivo."
          },
          "size": {
            "type": "integer",
            "description": "Tamanho em bytes, quando o canal informa."
          },
          "sha256": {
            "type": "string",
            "description": "SHA-256 do arquivo em base64, quando o canal informa."
          },
          "url": {
            "type": "string",
            "description": "Link do arquivo do cartão, depois de baixado com `POST /messages/media` e `item: cards.N` (N = posição do cartão, a partir de 0)."
          },
          "filename": {
            "type": "string",
            "description": "Nome do arquivo (documentos)."
          },
          "duration_seconds": {
            "type": "integer",
            "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
          },
          "width": {
            "type": "integer",
            "description": "Largura em pixels, quando o canal informa."
          },
          "height": {
            "type": "integer",
            "description": "Altura em pixels, quando o canal informa."
          },
          "view_once": {
            "type": "boolean",
            "description": "Visualização única."
          },
          "animated": {
            "type": "boolean",
            "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
          },
          "thumbnail": {
            "type": "string",
            "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
          },
          "transcription": {
            "type": "string",
            "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
          },
          "text": {
            "type": "string",
            "description": "Texto."
          },
          "choices": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/OrkesioOption"
            },
            "description": "Botões do card."
          }
        },
        "additionalProperties": false
      },
      "description": "Cards (carrossel): a mídia (`type` e os campos da mídia), o `text` e os `choices` de cada cartão."
    }
  },
  "required": [],
  "title": "carrossel"
}
```

## #/components/schemas/MessageContentLocationRequest

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto principal, acima das opções. Quando a mensagem tem cabeçalho em texto, ele vem na primeira linha, como se manda."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo do cabeçalho, quando ele é uma mídia (imagem, vídeo ou documento)."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo do cabeçalho (documentos)."
    },
    "choices": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioOption"
      },
      "description": "Opções do menu ou botões."
    }
  },
  "required": [],
  "title": "pedido de localização"
}
```

## #/components/schemas/MessageContentFlow

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto principal, acima do botão. Quando a mensagem tem cabeçalho em texto, ele vem na primeira linha, como se manda."
    },
    "footer": {
      "type": "string",
      "description": "Rodapé."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo do cabeçalho, quando ele é uma mídia (imagem, vídeo ou documento)."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo do cabeçalho (documentos)."
    },
    "button_text": {
      "type": "string",
      "description": "O texto do botão que abre o Flow."
    },
    "flow_id": {
      "type": "string",
      "description": "Id do Flow na Meta (o Flow publicado no WhatsApp Manager da sua conta)."
    },
    "flow_name": {
      "type": "string",
      "description": "Nome do Flow na Meta (informativo: o Flow é o do `flow_id`)."
    },
    "flow_token": {
      "type": "string",
      "description": "O identificador da conversa no Flow, que volta na resposta do contato."
    },
    "flow_action": {
      "type": "string",
      "enum": [
        "navigate",
        "data_exchange"
      ],
      "description": "Como o Flow abre: `navigate` (na tela de `flow_action_payload.screen`) ou `data_exchange` (pelo endpoint de dados)."
    },
    "flow_action_payload": {
      "type": "object",
      "additionalProperties": false,
      "properties": {
        "screen": {
          "type": "string",
          "description": "Tela em que o Flow abre (só `navigate`)."
        },
        "data": {
          "type": "object",
          "additionalProperties": true,
          "description": "Dados iniciais da tela, no formato que o Flow espera."
        }
      },
      "description": "A tela inicial e os dados dela, no formato da Meta."
    },
    "mode": {
      "type": "string",
      "enum": [
        "published",
        "draft"
      ],
      "description": "`published` (o Flow publicado) ou `draft` (o rascunho)."
    }
  },
  "required": [],
  "title": "Flow"
}
```

## #/components/schemas/MessageContentInteractiveReply

```json
{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "button",
        "list",
        "flow",
        "quick_reply",
        "postback",
        "template_button",
        "callback"
      ],
      "description": "Origem: botão, lista, Flow, resposta rápida, postback (Messenger/Instagram), botão de template ou callback (Telegram)."
    },
    "option_id": {
      "type": "string",
      "description": "Id da opção escolhida."
    },
    "text": {
      "type": "string",
      "description": "O título da opção escolhida."
    },
    "description": {
      "type": "string",
      "description": "Descrição da opção (listas)."
    },
    "payload": {
      "type": "string",
      "description": "Dados devolvidos pelo botão."
    },
    "response": {
      "type": "object",
      "additionalProperties": true,
      "description": "Respostas do formulário (Flow), já como objeto."
    }
  },
  "required": [
    "kind"
  ],
  "title": "resposta de botão ou lista",
  "description": "A resposta do contato a botões, lista ou carrossel. No Messenger e no Instagram (quando chegarem), o clique num botão (postback) também chega aqui: o botão em `option_id` e o dado dele em `payload`."
}
```

## #/components/schemas/MessageContentOrder

```json
{
  "type": "object",
  "properties": {
    "item_count": {
      "type": "integer",
      "description": "Itens."
    },
    "total": {
      "type": "number",
      "description": "Valor total."
    },
    "currency": {
      "type": "string",
      "description": "Moeda."
    },
    "text": {
      "type": "string",
      "description": "Mensagem do pedido."
    }
  },
  "x-only": "whatsapp",
  "title": "pedido"
}
```

## #/components/schemas/MessageContentProduct

```json
{
  "type": "object",
  "properties": {
    "product_id": {
      "type": "string",
      "description": "Id do produto."
    },
    "name": {
      "type": "string",
      "description": "O nome do produto, como o `name` do catálogo (`GET /catalog/products`)."
    },
    "description": {
      "type": "string",
      "description": "Descrição."
    },
    "price": {
      "type": "number",
      "description": "Preço em unidades da moeda (`19.99`). O catálogo usa a string em milésimos do WhatsApp (`\"19990\"`)."
    },
    "sale_price": {
      "type": "number",
      "description": "Preço promocional, em unidades da moeda."
    },
    "currency": {
      "type": "string",
      "description": "Moeda."
    },
    "url": {
      "type": "string",
      "description": "Link."
    },
    "image": {
      "$ref": "#/components/schemas/MessageContentImage"
    }
  },
  "x-only": "whatsapp",
  "title": "produto"
}
```

## #/components/schemas/MessageContentPayment

```json
{
  "type": "object",
  "properties": {
    "reference_id": {
      "type": "string",
      "description": "Referência do pedido."
    },
    "amount": {
      "type": "number",
      "description": "Valor."
    },
    "currency": {
      "type": "string",
      "description": "Moeda."
    },
    "text": {
      "type": "string",
      "description": "A nota da cobrança."
    },
    "items": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string",
            "description": "Item."
          },
          "quantity": {
            "type": "number",
            "description": "Quantidade."
          },
          "amount": {
            "type": "number",
            "description": "Valor do item."
          }
        },
        "required": [
          "name"
        ],
        "additionalProperties": false
      },
      "description": "Itens."
    },
    "pix": {
      "type": "object",
      "properties": {
        "key": {
          "type": "string",
          "description": "Chave PIX."
        },
        "key_type": {
          "type": "string",
          "description": "Tipo da chave."
        },
        "merchant_name": {
          "type": "string",
          "description": "Recebedor."
        }
      },
      "additionalProperties": false
    },
    "boleto": {
      "type": "string",
      "description": "Linha digitável do boleto."
    },
    "link": {
      "type": "string",
      "description": "Link de pagamento."
    },
    "card": {
      "type": "boolean",
      "description": "Pagamento por cartão."
    },
    "payment_status": {
      "type": "string",
      "description": "Status do pagamento, quando informado."
    }
  },
  "x-only": "whatsapp",
  "title": "cobrança"
}
```

## #/components/schemas/MessageContentGroupInvite

```json
{
  "type": "object",
  "properties": {
    "group_id": {
      "type": "string",
      "description": "Grupo."
    },
    "name": {
      "type": "string",
      "description": "Nome do grupo."
    },
    "code": {
      "type": "string",
      "description": "Código do convite."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Validade. ISO 8601 em UTC com milissegundos."
    },
    "text": {
      "type": "string",
      "description": "A legenda do convite."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura, JPEG em base64."
    }
  },
  "required": [
    "code"
  ],
  "x-only": "whatsapp",
  "title": "convite de grupo"
}
```

## #/components/schemas/MessageContentNewsletterInvite

```json
{
  "type": "object",
  "properties": {
    "newsletter_id": {
      "type": "string",
      "description": "Canal (`<id>@newsletter`)."
    },
    "name": {
      "type": "string",
      "description": "Nome do canal."
    },
    "role": {
      "type": "string",
      "enum": [
        "admin",
        "follower"
      ],
      "description": "Convite para ser admin ou para seguir."
    },
    "text": {
      "type": "string",
      "description": "A legenda do convite."
    },
    "expires_at": {
      "type": "string",
      "format": "date-time",
      "description": "Validade. ISO 8601 em UTC com milissegundos."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura, JPEG em base64."
    }
  },
  "required": [
    "newsletter_id"
  ],
  "x-only": "whatsapp",
  "title": "convite de newsletter"
}
```

## #/components/schemas/MessageContentEventResponse

```json
{
  "type": "object",
  "properties": {
    "event": {
      "$ref": "#/components/schemas/OrkesioMessageRef"
    },
    "response": {
      "type": "string",
      "enum": [
        "going",
        "not_going",
        "maybe"
      ],
      "description": "Resposta ao convite."
    }
  },
  "required": [
    "event",
    "response"
  ],
  "title": "resposta a evento"
}
```

## #/components/schemas/MessageContentStickerPack

```json
{
  "type": "object",
  "properties": {
    "name": {
      "type": "string",
      "description": "Nome do pacote."
    },
    "publisher": {
      "type": "string",
      "description": "Autor."
    },
    "count": {
      "type": "integer",
      "description": "Figurinhas no pacote."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura, JPEG em base64."
    }
  },
  "x-only": "whatsapp",
  "title": "pacote de figurinhas"
}
```

## #/components/schemas/MessageContentVideoNote

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "mime_type": {
      "type": "string",
      "description": "Tipo do arquivo."
    },
    "size": {
      "type": "integer",
      "description": "Tamanho em bytes, quando o canal informa."
    },
    "sha256": {
      "type": "string",
      "description": "SHA-256 do arquivo em base64, quando o canal informa."
    },
    "url": {
      "type": "string",
      "description": "Link do arquivo no servidor da inbox, quando já baixado. O evento `message.updated` com `change: media_ready` avisa quando fica pronto."
    },
    "filename": {
      "type": "string",
      "description": "Nome do arquivo (documentos)."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos (áudio e vídeo), quando o canal informa."
    },
    "width": {
      "type": "integer",
      "description": "Largura em pixels, quando o canal informa."
    },
    "height": {
      "type": "integer",
      "description": "Altura em pixels, quando o canal informa."
    },
    "view_once": {
      "type": "boolean",
      "description": "Visualização única."
    },
    "animated": {
      "type": "boolean",
      "description": "Figurinha animada, ou vídeo que toca como GIF (em loop e sem som)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura JPEG em base64. Vem **só no aviso em tempo real** (webhook e SSE): não é gravada, então a busca e o `GET /status-posts` não a trazem (use o `url`)."
    },
    "transcription": {
      "type": "string",
      "description": "Transcrição (áudio e voz), quando feita com `transcribe` no download. Fica aqui, não em `text`."
    }
  },
  "title": "vídeo redondo"
}
```

## #/components/schemas/MessageContentLiveLocation

```json
{
  "type": "object",
  "properties": {
    "latitude": {
      "type": "number",
      "description": "Latitude."
    },
    "longitude": {
      "type": "number",
      "description": "Longitude."
    },
    "text": {
      "type": "string",
      "description": "A legenda."
    },
    "accuracy": {
      "type": "integer",
      "description": "Precisão em metros, quando informada."
    },
    "sequence": {
      "type": "integer",
      "description": "Número da atualização (cresce a cada nova posição)."
    },
    "thumbnail": {
      "type": "string",
      "description": "Miniatura do mapa, JPEG em base64."
    }
  },
  "required": [
    "latitude",
    "longitude"
  ],
  "x-only": "whatsapp",
  "title": "localização ao vivo"
}
```

## #/components/schemas/MessageContentScheduledCall

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O título da ligação."
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Quando começa. ISO 8601 em UTC com milissegundos."
    },
    "video": {
      "type": "boolean",
      "description": "Chamada de vídeo."
    }
  },
  "required": [
    "start_at"
  ],
  "x-only": "whatsapp",
  "title": "ligação agendada"
}
```

## #/components/schemas/MessageContentAlbum

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O texto que veio junto com as mídias, quando o canal manda."
    },
    "images": {
      "type": "integer",
      "description": "Quantas fotos vêm no álbum."
    },
    "videos": {
      "type": "integer",
      "description": "Quantos vídeos vêm no álbum."
    }
  },
  "description": "Várias fotos e vídeos enviados juntos. Esta mensagem traz a contagem; cada mídia chega como uma mensagem própria, com `album_id` apontando para esta.",
  "title": "álbum"
}
```

## #/components/schemas/MessageContentShare

```json
{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "post",
        "reel",
        "story",
        "product",
        "link",
        "music"
      ],
      "description": "O que foi compartilhado: `post`, `reel` ou `story` (Instagram), `link` (Messenger), `music` (WhatsApp)."
    },
    "url": {
      "type": "string",
      "description": "Link."
    },
    "title": {
      "type": "string",
      "description": "Título."
    },
    "shared_id": {
      "type": "string",
      "description": "Id do conteúdo no canal."
    }
  },
  "required": [
    "kind"
  ],
  "title": "compartilhamento",
  "description": "Algo compartilhado na conversa: post, reel ou story (Instagram), link (Messenger) ou música (WhatsApp)."
}
```

## #/components/schemas/MessageContentStoryMention

```json
{
  "type": "object",
  "properties": {
    "url": {
      "type": "string",
      "description": "Link do story (pode expirar)."
    },
    "story_id": {
      "type": "string",
      "description": "Id do story."
    }
  },
  "x-only": "instagram",
  "title": "menção em story",
  "description": "O contato marcou a conta num story do Instagram. A mídia do story fica em `url` por pouco tempo."
}
```

## #/components/schemas/MessageContentEvent

```json
{
  "type": "object",
  "properties": {
    "text": {
      "type": "string",
      "description": "O nome do evento."
    },
    "description": {
      "type": "string",
      "description": "Descrição."
    },
    "start_at": {
      "type": "string",
      "format": "date-time",
      "description": "Início. ISO 8601 em UTC com milissegundos."
    },
    "end_at": {
      "type": "string",
      "format": "date-time",
      "description": "Fim. ISO 8601 em UTC com milissegundos."
    },
    "location": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "Nome do local."
        },
        "address": {
          "type": "string",
          "description": "Endereço."
        },
        "latitude": {
          "type": "number",
          "description": "Latitude."
        },
        "longitude": {
          "type": "number",
          "description": "Longitude."
        }
      },
      "additionalProperties": false
    },
    "join_link": {
      "type": "string",
      "description": "Link da chamada."
    },
    "canceled": {
      "type": "boolean",
      "description": "Cancelado."
    }
  },
  "required": [
    "text"
  ],
  "x-only": "whatsapp",
  "title": "evento"
}
```

## #/components/schemas/MessageContentReaction

```json
{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "react",
        "unreact"
      ],
      "description": "Pôs ou tirou a reação."
    },
    "emoji": {
      "type": "string",
      "description": "Emoji (vazio em `unreact`)."
    },
    "target": {
      "$ref": "#/components/schemas/OrkesioMessageRef"
    }
  },
  "required": [
    "action",
    "emoji",
    "target"
  ],
  "title": "reação"
}
```

## #/components/schemas/MessageContentCall

```json
{
  "type": "object",
  "properties": {
    "video": {
      "type": "boolean",
      "description": "Ligação de vídeo."
    },
    "result": {
      "type": "string",
      "enum": [
        "missed",
        "answered",
        "answered_elsewhere",
        "rejected",
        "busy",
        "failed",
        "unknown"
      ],
      "description": "Resultado."
    },
    "duration_seconds": {
      "type": "integer",
      "description": "Duração em segundos."
    }
  },
  "required": [
    "result"
  ],
  "title": "ligação"
}
```

## #/components/schemas/MessageContentGroupParticipant

```json
{
  "type": "object",
  "properties": {
    "action": {
      "type": "string",
      "enum": [
        "joined",
        "added",
        "left",
        "removed",
        "promoted",
        "demoted"
      ],
      "description": "`joined` (entrou pelo link), `added` (foi adicionado), `left` (saiu), `removed` (foi removido), `promoted`/`demoted` (virou ou deixou de ser admin)."
    },
    "participants": {
      "type": "array",
      "items": {
        "$ref": "#/components/schemas/OrkesioParticipant"
      },
      "description": "Participantes afetados."
    },
    "by": {
      "$ref": "#/components/schemas/OrkesioParticipant"
    }
  },
  "required": [
    "action",
    "participants"
  ],
  "x-only": "whatsapp",
  "title": "participantes do grupo"
}
```

## #/components/schemas/MessageContentSystem

```json
{
  "type": "object",
  "properties": {
    "kind": {
      "type": "string",
      "enum": [
        "ephemeral_changed",
        "history_sync",
        "group_status",
        "pin",
        "edit",
        "revoke",
        "poll_result",
        "poll_option_added",
        "status_interaction",
        "other"
      ],
      "description": "O que aconteceu."
    },
    "text": {
      "type": "string",
      "description": "Descrição para exibir."
    }
  },
  "required": [
    "kind"
  ],
  "title": "aviso do sistema"
}
```

## #/components/schemas/MessageContentUnavailable

```json
{
  "type": "object",
  "properties": {
    "reason": {
      "type": "string",
      "enum": [
        "undecryptable",
        "absent",
        "unsupported"
      ],
      "description": "`undecryptable`: o WhatsApp ainda vai reenviar; `absent`: o celular não tem a mensagem; `unsupported`: canal que não repassa esse tipo ou que a api ainda não traduz (API oficial do WhatsApp, Instagram e Messenger: enquete, mídia temporária; Telegram: enquete, dado, cobrança, jogo, story, checklist e mídia paga)."
    },
    "media_type": {
      "type": "string",
      "description": "Tipo esperado, quando se sabe."
    }
  },
  "required": [
    "reason"
  ],
  "x-only": "whatsapp",
  "title": "indisponível"
}
```

## #/components/responses/RateLimited

```json
{
  "description": "`rate_limited`: passou do limite de chamadas desta inbox (ou do admin); espere o tempo do header `Retry-After` e tente de novo.",
  "headers": {
    "Retry-After": {
      "description": "Segundos até poder chamar de novo.",
      "schema": {
        "type": "integer",
        "minimum": 1
      }
    }
  },
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/OrkesioError"
      },
      "example": {
        "error": "rate_limited",
        "message": "Muitas requisições."
      }
    }
  }
}
```

## #/components/responses/CloudUnsupported

```json
{
  "description": "`unsupported_for_channel`: o canal da inbox não atende esta rota (rota só do WhatsApp Web numa inbox oficial, ou rota da API oficial numa inbox do WhatsApp Web). O canal está em `Inbox.channel`.",
  "content": {
    "application/json": {
      "schema": {
        "$ref": "#/components/schemas/OrkesioError"
      },
      "example": {
        "error": "unsupported_for_channel",
        "message": "Esta rota não está disponível no canal da inbox."
      }
    }
  }
}
```

## Guias relacionados

[Visão geral](/docs/overview) · [O que funciona em cada canal](/docs/canais) · [O que muda da uazapi](/docs/o-que-muda)
