Editar mensagem

PATCH /messages

Troca o texto de uma mensagem enviada pela inbox (o texto ou a legenda). O WhatsApp só aceita edição até 15 minutos depois do envio. Quem recebe vê "editada"; o evento message.updated (change: edited) avisa.

Autenticação

[
  {
    "token": []
  }
]
{
  "token": {
    "name": "token",
    "type": "apiKey",
    "in": "header"
  }
}

Corpo da requisição

{
  "required": true,
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "message_id",
          "text"
        ],
        "properties": {
          "message_id": {
            "type": "string",
            "description": "A mensagem: o `id` dela."
          },
          "text": {
            "type": "string",
            "minLength": 1,
            "description": "O texto novo. Substitui o texto inteiro (ou a legenda, em mídia)."
          }
        }
      },
      "example": {
        "message_id": "3EB0A1B2C3D4E5F60718",
        "text": "Seu pedido sai amanhã de manhã."
      }
    }
  }
}

Respostas

{
  "200": {
    "description": "A mensagem editada.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioMessage"
        },
        "example": {
          "id": "3EB05DCE1D4036FCE241C6",
          "chat_id": "5511999999999@s.whatsapp.net",
          "author": {
            "id": "5511888888888@s.whatsapp.net",
            "name": "Loja"
          },
          "direction": "out",
          "sent_by": "api",
          "sent_at": "2026-10-17T12:00:00.000Z",
          "status": "read",
          "category": "conversation",
          "type": "text",
          "text": "Seu pedido sai amanhã de manhã.",
          "edited": true
        }
      }
    }
  },
  "400": {
    "description": "A mensagem não pode ser editada (post de status de grupo, ou mensagem de canal que não saiu pela api).",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "invalid_request",
          "message": "Só dá para editar mensagem enviada pela inbox."
        }
      }
    }
  },
  "401": {
    "description": "Token inválido ou ausente.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unauthorized",
          "message": "Token inválido."
        }
      }
    }
  },
  "404": {
    "description": "Mensagem não encontrada.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "not_found",
          "message": "Mensagem não encontrada."
        }
      }
    }
  },
  "429": {
    "$ref": "#/components/responses/RateLimited"
  },
  "500": {
    "description": "O WhatsApp recusou a edição; o motivo vem em `message`.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "send_failed",
          "message": "O WhatsApp recusou o pedido."
        }
      }
    }
  },
  "501": {
    "$ref": "#/components/responses/CloudUnsupported"
  },
  "503": {
    "description": "Inbox desconectada do WhatsApp.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "disconnected",
          "message": "WhatsApp desconectado."
        }
      }
    }
  }
}

Estado: Disponível

Compatibilidade de canais

CanalCompatívelObservação
WhatsApp (Web)Sim
WhatsApp (API oficial)NãoA API oficial não edita mensagens.
InstagramNão
MessengerNão
TelegramEm parteSó as mensagens enviadas pela inbox; no Telegram Business, até 48 horas depois.

Eventos que esta rota gera

O que chega no seu webhook (ou em GET /events) depois desta rota.

message.updated: change: edited

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "message.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "change": "edited",
    "message": {
      "id": "3EB05DCE1D4036FCE241C6",
      "chat_id": "5511999999999@s.whatsapp.net",
      "author": {
        "id": "5511888888888@s.whatsapp.net",
        "name": "Loja"
      },
      "direction": "out",
      "sent_by": "api",
      "sent_at": "2026-10-17T12:00:00.000Z",
      "category": "conversation",
      "type": "text",
      "text": "Seu pedido sai amanhã.",
      "track_source": "crm",
      "track_id": "42",
      "edited": true
    },
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "lid": "123456789012345@lid",
      "type": "direct"
    }
  }
}

Antes e depois (uazapi → Orkesio)

Na uazapi: POST /message/edit.

  • id → message_id; responde a mensagem no formato novo.

#/components/schemas/OrkesioMessage

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

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

#/components/schemas/OrkesioContactCard

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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

{
  "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 · O que funciona em cada canal · O que muda da uazapi