Alterar a conversa

PATCH /chats

Muda a conversa. Só os campos enviados mudam.

  • No WhatsApp (archived, pinned, muted_until, unread, ephemeral_seconds, labels, add_labels, remove_labels, notes): vale em todos os aparelhos da conta e vai um campo por pedido, sem outro junto (400 one_change_per_request, nada muda).
  • No atendimento (automation_paused_until, ai_memory_from, assigned_to, ticket_open): vale para a conversa, não para o lead: o mesmo contato em outra inbox segue com o dele. Podem ir juntos.

Responde a conversa depois da mudança, no formato de GET /chats.

Para mexer em uma etiqueta sem mandar a lista inteira, use add_labels ou remove_labels (um dos dois por pedido, como os outros campos do WhatsApp). Se o WhatsApp falhar no meio de uma lista, as etiquetas anteriores já ficaram; repetir o pedido é seguro.

Autenticação

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

Corpo da requisição

{
  "required": true,
  "content": {
    "application/json": {
      "schema": {
        "type": "object",
        "additionalProperties": false,
        "minProperties": 2,
        "description": "Só os campos enviados mudam.",
        "properties": {
          "chat_id": {
            "type": "string",
            "description": "A conversa: o `chat.id` (número ou id do WhatsApp; o número sozinho também vale)."
          },
          "automation_paused_until": {
            "description": "Pausa a automação (IA, gatilhos e fluxos) nesta conversa: até uma data (ISO), `forever` (até alguém religar) ou `null` (religa agora, e apaga o motivo do pedido de humano).",
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "string",
                "const": "forever"
              },
              {
                "type": "null"
              }
            ]
          },
          "ai_memory_from": {
            "description": "A IA passa a ler a conversa só a partir desta data (`now` = agora); `null` desfaz. Serve para começar um atendimento novo sem o que foi dito antes.",
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "string",
                "const": "now"
              },
              {
                "type": "null"
              }
            ]
          },
          "assigned_to": {
            "description": "Quem atende a conversa: o id do atendente; `null` ou `\"\"` tira o responsável.",
            "anyOf": [
              {
                "type": "string"
              },
              {
                "type": "null"
              }
            ]
          },
          "ticket_open": {
            "type": "boolean",
            "description": "`true` abre o atendimento; `false` fecha. Não aceita `null`."
          },
          "archived": {
            "type": "boolean",
            "description": "`true` arquiva (e desafixa: conversa arquivada não fica fixada); `false` desarquiva. Não mexe nas mensagens. Não aceita `null`."
          },
          "pinned": {
            "type": "boolean",
            "description": "`true` fixa no topo da lista; `false` desafixa. Não aceita `null`."
          },
          "muted_until": {
            "description": "Silencia as notificações até uma data (ISO, no futuro), `forever` (para sempre) ou `null` (tira o silêncio).",
            "anyOf": [
              {
                "type": "string",
                "format": "date-time"
              },
              {
                "type": "string",
                "const": "forever"
              },
              {
                "type": "null"
              }
            ]
          },
          "unread": {
            "type": "boolean",
            "description": "`false` marca como lida: zera as não lidas e confirma a leitura das até 10 últimas mensagens recebidas (o contato vê os tiques azuis, se a confirmação estiver ligada). `true` marca como não lida, sem desfazer confirmações já enviadas. Na resposta, `unread_count` vem pelo menos `1`. Não aceita `null`."
          },
          "ephemeral_seconds": {
            "type": "integer",
            "enum": [
              0,
              86400,
              604800,
              7776000
            ],
            "description": "Mensagens temporárias, só em conversa individual: `0` desliga; `86400` (1 dia), `604800` (7 dias) ou `7776000` (90 dias). Em grupo, use `PATCH /groups`. Não aceita `null`."
          },
          "labels": {
            "type": "array",
            "items": {
              "type": "string"
            },
            "description": "O conjunto completo de etiquetas da conversa (o `id` de `GET /labels/list`); as que não estiverem aqui saem. `[]` tira todas."
          },
          "add_labels": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Põe estas etiquetas (o `id` de `GET /labels/list`) e mantém as outras. Etiqueta que não existe dá 400 com `field`, antes de mudar qualquer coisa."
          },
          "remove_labels": {
            "type": "array",
            "minItems": 1,
            "items": {
              "type": "string",
              "minLength": 1
            },
            "description": "Tira estas etiquetas e mantém as outras. Etiqueta que não existe dá 400 com `field`, antes de mudar qualquer coisa."
          },
          "notes": {
            "type": "string",
            "description": "A anotação da conversa (as notas do WhatsApp Business). `\"\"` apaga."
          }
        },
        "anyOf": [
          {
            "description": "Só o atendimento (os campos podem ir juntos).",
            "not": {
              "anyOf": [
                {
                  "required": [
                    "archived"
                  ]
                },
                {
                  "required": [
                    "pinned"
                  ]
                },
                {
                  "required": [
                    "muted_until"
                  ]
                },
                {
                  "required": [
                    "unread"
                  ]
                },
                {
                  "required": [
                    "ephemeral_seconds"
                  ]
                },
                {
                  "required": [
                    "labels"
                  ]
                },
                {
                  "required": [
                    "notes"
                  ]
                },
                {
                  "required": [
                    "add_labels"
                  ]
                },
                {
                  "required": [
                    "remove_labels"
                  ]
                }
              ]
            }
          },
          {
            "description": "Um campo só (um do WhatsApp vai sozinho).",
            "maxProperties": 2
          }
        ],
        "required": [
          "chat_id"
        ]
      },
      "example": {
        "chat_id": "5511999999999@s.whatsapp.net",
        "archived": true
      }
    }
  }
}

Respostas

{
  "200": {
    "description": "A conversa depois da mudança.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioChat"
        },
        "example": {
          "id": "5511999999999@s.whatsapp.net",
          "lid": "123456789012345@lid",
          "type": "direct",
          "name": "Maria Souza",
          "unread_count": 0,
          "awaiting_reply": false,
          "archived": true,
          "pinned": false,
          "labels": [
            "10"
          ],
          "last_message_at": "2026-10-17T12:00:00.000Z",
          "blocked": false,
          "ephemeral_seconds": 0,
          "lead_id": "r1a2b3c4d5e6f7"
        }
      }
    }
  },
  "400": {
    "description": "Corpo inválido, mais de um campo do WhatsApp no pedido (`one_change_per_request`), `muted_until` no passado ou `ephemeral_seconds` em grupo.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "examples": {
          "invalid_request": {
            "summary": "Valor inválido",
            "value": {
              "error": "invalid_request",
              "message": "muted_until aceita data ISO no futuro, forever ou null."
            }
          },
          "one_change_per_request": {
            "summary": "Mais de um campo do WhatsApp",
            "value": {
              "error": "one_change_per_request",
              "message": "Mande um campo do WhatsApp por pedido: archived, pinned, muted_until, unread ou ephemeral_seconds."
            }
          }
        }
      }
    }
  },
  "401": {
    "description": "Token inválido ou ausente.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unauthorized",
          "message": "Token inválido."
        }
      }
    }
  },
  "404": {
    "description": "Conversa não encontrada.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "not_found",
          "message": "Conversa não encontrada."
        }
      }
    }
  },
  "409": {
    "description": "`conflict`: com `notes`, o histórico ainda está chegando do celular; tente de novo em instantes.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "conflict",
          "message": "O histórico ainda está chegando do celular. Tente de novo em instantes."
        }
      }
    }
  },
  "429": {
    "$ref": "#/components/responses/RateLimited"
  },
  "500": {
    "description": "O WhatsApp recusou ou a operação falhou.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "internal_error",
          "message": "Erro ao falar com o WhatsApp; tente de novo."
        }
      }
    }
  },
  "501": {
    "description": "Na API oficial só a automação muda: os campos do WhatsApp não existem lá.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "unsupported_for_channel",
          "message": "Não disponível neste canal."
        }
      }
    }
  },
  "503": {
    "description": "`disconnected`: a inbox está desconectada do WhatsApp.",
    "content": {
      "application/json": {
        "schema": {
          "$ref": "#/components/schemas/OrkesioError"
        },
        "example": {
          "error": "disconnected",
          "message": "Inbox desconectada do WhatsApp."
        }
      }
    }
  }
}

Estado: Disponível

Compatibilidade de canais

CanalCompatívelObservação
WhatsApp (Web)Sim
WhatsApp (API oficial)Em parteSó o atendimento (automation_paused_until, ai_memory_from, assigned_to, ticket_open); os campos do WhatsApp respondem 501.
InstagramEm parteSó o atendimento (automation_paused_until, ai_memory_from, assigned_to, ticket_open); os campos do WhatsApp respondem 501.
MessengerEm parteSó o atendimento (automation_paused_until, ai_memory_from, assigned_to, ticket_open); os campos do WhatsApp respondem 501.
TelegramEm parteSó o atendimento (automation_paused_until, ai_memory_from, assigned_to, ticket_open); os campos do WhatsApp respondem 501.

Eventos que esta rota gera

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

chat.updated: changes: [automation_paused_until]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "automation_paused_until": "forever"
    },
    "changes": [
      "automation_paused_until"
    ]
  }
}

chat.updated: changes: [assigned_to, ticket_open]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "assigned_to": "att_7",
      "ticket_open": true
    },
    "changes": [
      "assigned_to",
      "ticket_open"
    ]
  }
}

chat.updated: changes: [archived]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": true,
      "unread_count": 0
    },
    "changes": [
      "archived"
    ]
  }
}

chat.updated: changes: [pinned]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "pinned": true
    },
    "changes": [
      "pinned"
    ]
  }
}

chat.updated: changes: [muted_until]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "muted_until": "2026-10-18T12:00:00.000Z"
    },
    "changes": [
      "muted_until"
    ]
  }
}

chat.updated: changes: [unread_count]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0
    },
    "changes": [
      "unread_count"
    ]
  }
}

chat.updated: changes: [ephemeral_seconds]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "ephemeral_seconds": 86400
    },
    "changes": [
      "ephemeral_seconds"
    ]
  }
}

chat.updated: changes: [labels]

{
  "id": "evt_01JAB3K9ZQ7V0M4T8R2X6WYD5H",
  "type": "chat.updated",
  "created_at": "2026-10-17T12:00:00.000Z",
  "inbox": {
    "id": "r0269625d29bfbd",
    "name": "loja",
    "phone": "5511888888888",
    "channel": "whatsapp_web"
  },
  "data": {
    "chat": {
      "id": "5511999999999@s.whatsapp.net",
      "type": "direct",
      "name": "Maria",
      "archived": false,
      "unread_count": 0,
      "labels": [
        "10"
      ]
    },
    "changes": [
      "labels"
    ]
  }
}

Antes e depois (uazapi → Orkesio)

Na uazapi: POST /chat/editLead, POST /chat/archive, POST /chat/pin, POST /chat/mute, POST /chat/read, POST /chat/ephemeral, POST /chat/labels, POST /chat/notes/edit.

  • chatbot_disableUntil (ms, -1, 0) → automation_paused_until (data ISO, forever ou null); chatbot_agentResetMemoryAt → ai_memory_from (data ISO, now ou null).
  • lead_assignedAttendant_id → assigned_to e lead_isTicketOpen → ticket_open: são do atendimento da conversa (o lead guarda só quem é o cliente).
  • POST /chat/archive → archived; POST /chat/pin → pinned; POST /chat/read → unread (o inverso de read).
  • POST /chat/mute → muted_until (data ISO, forever ou null; antes só 8 horas, 1 semana ou para sempre).
  • POST /chat/ephemeral → ephemeral_seconds (0, 86400, 604800 ou 7776000; antes também 1d, 7d, 90d).
  • Responde a conversa (antes response em texto).
  • labels (antes PATCH /chats (labels)) e notes (antes PATCH /chats (notes)), campos do WhatsApp, um por pedido.

#/components/schemas/OrkesioChat

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id da conversa: o id nativo do canal com o sufixo dele. WhatsApp: `<número>@s.whatsapp.net`, `<id>@g.us` (grupo), `<id>@newsletter`, `status@broadcast` ou, na API oficial, `<BSUID>@bsuid` para contato sem telefone. Nos outros canais: `<psid>@messenger`, `<igsid>@instagram`, `<id>@telegram` (conversa com o bot) e `<id>@telegram-business` (conversa da sua conta, pelo Telegram Business); o post comentado é `<id da mídia>@instagram_post` ou `<id do post>@facebook_post` (no Facebook o id do post tem `_`, como `110198307512345_987654321`). Guarde como veio, sem montar a partir de outro campo."
    },
    "lid": {
      "type": "string",
      "description": "**Só WhatsApp.** LID da conversa, quando conhecido (só no `whatsapp_web`).",
      "x-only": "whatsapp"
    },
    "type": {
      "type": "string",
      "enum": [
        "direct",
        "group",
        "broadcast",
        "newsletter",
        "channel",
        "status",
        "post"
      ],
      "description": "Tipo da conversa. `newsletter` é newsletter do WhatsApp (o que o app chama de Canal); `channel` fica para os canais de transmissão do Telegram, que ainda não chegam. `post` é um post do Instagram ou da Página do Facebook: os comentários são as mensagens."
    },
    "name": {
      "type": "string",
      "description": "Nome para exibir: em conversa direta, o `contact_name` (agenda do celular) ou, sem ele, o `push_name` (perfil do contato); em grupo ou canal, o nome do grupo ou do canal. Não é um nome a mais: é um dos outros, já escolhido. No post, o começo da legenda."
    },
    "contact_name": {
      "type": "string",
      "description": "**Só WhatsApp.** Só em conversa direta: o nome salvo na agenda do celular; ausente quando o número não está salvo.",
      "x-only": "whatsapp"
    },
    "push_name": {
      "type": "string",
      "description": "**Só WhatsApp.** Só em conversa direta: o nome que o contato usa no perfil do WhatsApp, quando conhecido.",
      "x-only": "whatsapp"
    },
    "username": {
      "type": "string",
      "description": "Só em conversa direta: o nome de usuário do contato (o @, sem o `@`), quando ele tem e o canal informa. No WhatsApp, vem no `GET /chats/{chat_id}`; no Instagram e no Telegram, em toda conversa, depois que a pessoa escreve."
    },
    "unread_count": {
      "type": "integer",
      "description": "Quantas mensagens não lidas a conversa tem."
    },
    "awaiting_reply": {
      "type": "boolean",
      "description": "O contato espera resposta: a última mensagem é dele e ninguém concluiu a conversa."
    },
    "assigned_to": {
      "type": "string",
      "description": "Quem atende esta conversa: o id do atendente. Ausente = sem responsável. É da conversa, não do lead: o mesmo contato pode ter outro responsável em outra inbox."
    },
    "ticket_open": {
      "type": "boolean",
      "description": "Atendimento aberto nesta conversa."
    },
    "reply_window_until": {
      "type": "string",
      "format": "date-time",
      "description": "Até quando dá para mandar mensagem livre: 24 horas depois da última mensagem do contato (reação e edição não contam). Depois disso, só template (API oficial) ou mensagem com tag (Messenger, Instagram). Vem nos canais oficiais (API oficial do WhatsApp, Instagram, Messenger, Telegram Business), na lista, no detalhe, no `chat.updated`, em `message.received` e em `message.sent`; ausente no WhatsApp Web e na conversa com o bot do Telegram, que não têm janela, e quando a janela já fechou."
    },
    "archived": {
      "type": "boolean",
      "description": "Arquivada."
    },
    "pinned": {
      "type": "boolean",
      "description": "Fixada."
    },
    "muted_until": {
      "type": "string",
      "format": "date-time",
      "description": "Silenciada até; ausente quando não está silenciada. ISO 8601 em UTC com milissegundos."
    },
    "labels": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Id da etiqueta (o `id` de `GET /labels/list`, como em `PATCH /chats` (`labels`))."
      },
      "description": "**Só WhatsApp.** Etiquetas do WhatsApp Business (ids), como no celular. As tags do CRM são outras, em `lead.tags`.",
      "x-only": "whatsapp"
    },
    "last_message_at": {
      "type": "string",
      "format": "date-time",
      "description": "Última mensagem. ISO 8601 em UTC com milissegundos."
    },
    "picture_url": {
      "type": "string",
      "description": "Foto completa da conversa (do contato ou do grupo), quando conhecida."
    },
    "picture_preview_url": {
      "type": "string",
      "description": "Miniatura da foto, quando conhecida (use nas listas)."
    },
    "blocked": {
      "type": "boolean",
      "description": "Contato bloqueado."
    },
    "follows_business": {
      "type": "boolean",
      "description": "**Só Instagram.** O contato segue a conta da empresa. Vem quando a api já leu o perfil do contato: na mensagem recebida (uma vez por dia) ou no `GET /chats/{chat_id}`, que lê na hora se faltar. A lista e os eventos mostram só o que já foi lido; sem o campo, a Meta ainda não disse.",
      "x-only": "instagram"
    },
    "verified": {
      "type": "boolean",
      "description": "**Só Instagram.** O contato tem selo de verificado. Vem como `follows_business`.",
      "x-only": "instagram"
    },
    "ephemeral_seconds": {
      "type": "integer",
      "description": "**Só WhatsApp.** Mensagens temporárias: duração em segundos (`0` = desligado).",
      "x-only": "whatsapp"
    },
    "last_message_preview": {
      "type": "string",
      "description": "Texto ou legenda da última mensagem, para listas."
    },
    "last_message_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 última mensagem (os mesmos de `type` da mensagem), para o ícone da lista. A conversa guarda só o nome do tipo, sem o conteúdo: áudio e mensagem de voz vêm os dois como `audio`, e as mensagens interativas como `buttons`, `list` ou `template` (carrossel, flow, cobrança e pedido de localização vêm como `buttons`). A ligação também é prévia (`call`) e sobe a conversa, como no WhatsApp, sem somar não lida. A entrada e saída de membro do grupo não é prévia. Ausente quando não se sabe."
    },
    "last_message_direction": {
      "type": "string",
      "enum": [
        "in",
        "out"
      ],
      "description": "Quem mandou a última mensagem, como em `direction` da mensagem: `in`, o contato (no grupo, um participante); `out`, a inbox (o \"Você:\" da lista). Ausente quando não se sabe."
    },
    "last_message_author": {
      "$ref": "#/components/schemas/OrkesioParticipant",
      "description": "Quem mandou a última mensagem (`id`, `phone` quando é um número). `name` vem no grupo (o nome que o participante mostra, quando conhecido) e na conversa direta quando foi o contato. Ausente quando não se sabe. Para a prévia \"Ana: oi\" da lista."
    },
    "group": {
      "type": "object",
      "description": "**Só WhatsApp.** Só em grupo: o resumo do grupo, com os mesmos campos de `GET /groups/{group_id}`.",
      "properties": {
        "is_admin": {
          "type": "boolean",
          "description": "A inbox é administradora."
        },
        "is_member": {
          "type": "boolean",
          "description": "A inbox ainda participa."
        },
        "announce": {
          "type": "boolean",
          "description": "Só administradores mandam mensagem."
        },
        "community": {
          "type": "boolean",
          "description": "É uma comunidade."
        },
        "parent_community": {
          "type": "object",
          "description": "A comunidade a que o grupo pertence.",
          "additionalProperties": false,
          "required": [
            "id"
          ],
          "properties": {
            "id": {
              "type": "string",
              "description": "Id da comunidade (`<id>@g.us`)."
            },
            "name": {
              "type": "string",
              "description": "Nome da comunidade, quando conhecido."
            },
            "picture_url": {
              "type": "string",
              "description": "Foto completa, quando conhecida."
            },
            "picture_preview_url": {
              "type": "string",
              "description": "Miniatura da foto, quando conhecida (use nas listas)."
            },
            "default_subgroup_id": {
              "type": "string",
              "description": "Id do grupo de avisos da comunidade, quando conhecido."
            }
          }
        }
      },
      "x-only": "whatsapp"
    },
    "lead_id": {
      "type": "string",
      "description": "Id do lead do contato. Toda conversa direta tem; grupo, canal e status não."
    },
    "lead": {
      "$ref": "#/components/schemas/OrkesioLead",
      "description": "O CRM do contato da conversa (no `GET /chats`, no `GET /chats/{chat_id}` e no `chat.updated`). Em `message.received` e `message.sent`, vem ao lado da conversa, em `data.lead`. Ausente em grupo, canal e status."
    },
    "automation_paused_until": {
      "description": "Pausada até (ISO), `forever` (até alguém religar) ou ausente (ligada).",
      "anyOf": [
        {
          "type": "string",
          "format": "date-time"
        },
        {
          "type": "string",
          "const": "forever"
        }
      ]
    },
    "automation_pause_reason": {
      "type": "string",
      "description": "Por que a automação pausou sozinha: pedido de humano (IA ou fluxo) ou limite de respostas da IA. Ausente quando foi pausada à mão ou está ligada."
    },
    "ai_memory_from": {
      "type": "string",
      "format": "date-time",
      "description": "A IA lê a conversa só a partir daqui; ausente = toda a conversa."
    },
    "notes": {
      "type": "string",
      "description": "A anotação da conversa (as notas do WhatsApp Business). Sem anotação: ausente na lista e nos eventos, vazia no `GET /chats/{chat_id}`."
    },
    "automation": {
      "type": "object",
      "additionalProperties": false,
      "required": [
        "active"
      ],
      "description": "Se a IA atende a conversa agora: a IA ligada, a conversa sem pausa e sem fluxo esperando resposta, e o gatilho que pegaria a próxima mensagem do contato (o de maior prioridade, sem palavra-chave, cujo filtro combina) é de um agente. Vem em `GET /chats`, `GET /chats/{chat_id}`, `message.received` e `message.sent`. Nos eventos, fica de fora quando não deu para ler a tempo (vem na próxima mensagem e no `GET /chats`); o `chat.updated` não traz.",
      "properties": {
        "active": {
          "type": "boolean",
          "description": "A IA responde a próxima mensagem do contato."
        },
        "agent": {
          "type": "object",
          "additionalProperties": false,
          "required": [
            "id"
          ],
          "description": "O agente que atende (com `active`).",
          "properties": {
            "id": {
              "type": "string",
              "description": "Id do agente (`/chatbot/agents`)."
            },
            "name": {
              "type": "string",
              "description": "Nome do agente."
            }
          }
        }
      }
    },
    "post": {
      "type": "object",
      "additionalProperties": false,
      "description": "Só em `type: post` (Instagram e Messenger), e só no `GET /chats/{chat_id}`: o post comentado, buscado na Meta na hora. A lista e os eventos trazem só o nome (o começo da legenda) e a foto (a miniatura). Os comentários são as mensagens da conversa; a resposta a outro comentário vem em `reply_to`.",
      "properties": {
        "url": {
          "type": "string",
          "description": "Link do post (permalink)."
        },
        "caption": {
          "type": "string",
          "description": "Legenda (no Facebook, o texto do post)."
        },
        "media_type": {
          "type": "string",
          "description": "Instagram: `image`, `video` ou `carousel_album`; `reels` e `ad` vêm em `product_type`."
        },
        "product_type": {
          "type": "string",
          "description": "Só Instagram: `feed`, `reels` ou `ad`."
        },
        "thumbnail_url": {
          "type": "string",
          "description": "Miniatura (pode expirar)."
        },
        "created_at": {
          "type": "string",
          "format": "date-time",
          "description": "Quando o post foi publicado."
        }
      }
    },
    "ad": {
      "type": "object",
      "additionalProperties": false,
      "description": "O último clique em anúncio que trouxe o contato (anúncio de \"enviar mensagem\" no WhatsApp, no Messenger ou no Instagram): os campos do `referral` da mensagem que veio do anúncio, mais `clicked_at`. Fica na conversa mesmo depois que as mensagens antigas são apagadas; outro clique mais novo troca. Ausente se o contato nunca veio de anúncio. Use o `ctwa_clid` para mandar conversões para a Meta ([Conversões para a Meta](/docs/conversoes-meta)).",
      "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."
        },
        "clicked_at": {
          "type": "string",
          "format": "date-time",
          "description": "Quando chegou a mensagem do clique."
        }
      }
    }
  },
  "required": [
    "id",
    "type"
  ],
  "additionalProperties": false,
  "description": "Conversa. Em grupo, `id` e `name` identificam o grupo, e quem escreveu vem no `author` da mensagem. Em `message.received` e `message.sent` (webhook e `/events`), `data.chat` traz o resumo da conversa, como no `GET /chats/{chat_id}` (o `lead` vem ao lado, em `data.lead`): não lidas, arquivada, etiquetas, pausa da automação, `automation`, janela de resposta, `lead_id`. Sob carga, o resumo pode ser o de antes desta mensagem. Nos outros eventos de mensagem, só `id`, `lid`, `type` e `name`: o estado muda em `chat.updated` e vem no histórico."
}

#/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/OrkesioLead

{
  "type": "object",
  "properties": {
    "id": {
      "type": "string",
      "description": "Id do lead na Orkesio. Opaco: guarde como veio, sem montar a partir de outro campo. Hoje é o id interno da conversa onde o lead nasceu."
    },
    "phone": {
      "type": "string",
      "description": "Telefone do contato com DDI (só dígitos), quando conhecido."
    },
    "lid": {
      "type": "string",
      "description": "LID do contato, quando conhecido (só no `whatsapp_web`)."
    },
    "name": {
      "type": "string",
      "description": "Como o contato quer ser chamado (ex.: `Dona Maria`), escrito por você, pela IA ou por um fluxo. Não vem do WhatsApp: os nomes do WhatsApp são `contact_name` e `push_name` da conversa."
    },
    "full_name": {
      "type": "string",
      "description": "Nome completo, para cadastro (nota, contrato), escrito por você, pela IA ou por um fluxo. Não vem do WhatsApp."
    },
    "email": {
      "type": "string",
      "description": "E-mail."
    },
    "document": {
      "type": "string",
      "description": "Documento (CPF/CNPJ ou outro)."
    },
    "status": {
      "type": "string",
      "description": "Etapa do funil, texto livre. A coluna do kanban é outra coisa: a tag com `kanban: true` em `tags`."
    },
    "tags": {
      "type": "array",
      "items": {
        "type": "string",
        "description": "Etiqueta do lead."
      },
      "description": "Etiquetas do lead (do CRM, não as do WhatsApp Business)."
    },
    "fields": {
      "type": "object",
      "additionalProperties": {
        "type": "string"
      },
      "description": "Campos personalizados (até 20), pela chave (`field01` a `field20`). O nome de cada um está em `GET /leads/fields`."
    },
    "notes": {
      "type": "string",
      "description": "Notas do CRM, só na Orkesio. Não são as notas do WhatsApp Business (essas são da conversa, em `GET /chats/{chat_id}`)."
    },
    "kanban_order": {
      "type": "integer",
      "description": "Posição do cartão na coluna do kanban (maior aparece primeiro)."
    },
    "identities": {
      "type": "array",
      "description": "As contas do contato em cada canal: uma por conversa ligada ao lead.",
      "items": {
        "type": "object",
        "additionalProperties": false,
        "required": [
          "channel",
          "id"
        ],
        "properties": {
          "channel": {
            "type": "string",
            "enum": [
              "whatsapp",
              "telegram",
              "messenger",
              "instagram"
            ],
            "description": "A rede (o WhatsApp Web e a API oficial são a mesma rede: `whatsapp`)."
          },
          "id": {
            "type": "string",
            "description": "O id do contato nesse canal, o mesmo de `chat.id`."
          },
          "username": {
            "type": "string",
            "description": "O nome de usuário nesse canal, quando há."
          }
        }
      }
    }
  },
  "required": [
    "id"
  ],
  "additionalProperties": false,
  "description": "Lead do CRM: o contato, com um lead por contato e por dono (hoje a inbox, então um por conversa direta). Grupo, canal e status não têm lead. Vem sempre em `message.received` e `message.sent` de conversa direta, e em cada conversa direta de `GET /chats`."
}

#/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/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."
      }
    }
  }
}

Guias relacionados

Visão geral · O que funciona em cada canal · O que muda da uazapi