# ZapyChat — API pública Base URL: `https://api.zapychat.com.br/api/v1` Autenticação: cabeçalho `Authorization: Bearer pk_...` (chave criada em Configurações › API Keys). Permissões da chave: `read` (rotas GET) e `write` (rotas que criam/alteram). Rotas marcadas como "aberta" não precisam de chave. Toda resposta de sucesso vem como `{ "data": , "meta": { "timestamp": "..." } }`; os exemplos abaixo mostram o conteúdo de `data`. Erros: `{ "statusCode", "message", "error", "timestamp", "path" }`. Códigos: 400 inválido, 401 chave inválida, 402 assinatura vencida, 403 sem permissão, 404 não encontrado, 409 conflito, 429 limite de chamadas. Listas: `page` (padrão 1) e `limit` (1–100, padrão 25); resposta `{ items, total, page, limit }`. Histórico de mensagens usa cursor `before`/`nextBefore`. Limites: 300 chamadas/min por chave (painel 120/min), 60 mensagens/min, texto até 4096 caracteres. ## Guia: Visão geral Integre o seu sistema ao ZapyChat com uma API REST simples: consulte conversas, contatos e avaliações, envie mensagens e receba eventos em tempo real. ### O que você pode fazer - Conversas: listar, ler o histórico, responder e encerrar. - Mensagens: enviar texto para qualquer telefone por um canal de WhatsApp. - Contatos e tags: criar, buscar, editar e organizar a base de clientes. - Tarefas: criar e concluir tarefas da equipe. - Avaliações: ler as notas do atendimento e dos atendentes. - Painel: puxar os indicadores do dashboard para os seus relatórios. - Webhooks: receber um aviso no seu servidor a cada evento importante. ### Como funciona Todas as chamadas são HTTPS com JSON. Você cria uma chave de API no painel, envia a chave no cabeçalho Authorization e recebe as respostas dentro de um objeto { data, meta }. Já tem uma chave? Vá direto ao Início rápido e faça a primeira chamada em um minuto. ## Guia: Início rápido Da chave de API à primeira resposta em três passos. ### 1. Crie uma chave de API No painel, abra Configurações › API Keys e crie uma chave. Marque a permissão de escrita só se for enviar mensagens ou alterar dados. Copie a chave (começa com pk_): ela aparece uma única vez. ### 2. Teste a chave ```bash curl "$BASE_URL/public/me" \ -H "Authorization: Bearer pk_sua_chave" ``` ### 3. Liste as conversas abertas ```bash curl "$BASE_URL/public/conversations?status=OPEN&limit=10" \ -H "Authorization: Bearer pk_sua_chave" ``` BASE_URL é o endereço da sua API terminando em /api/v1. Os exemplos da Referência já mostram o endereço certo. ## Guia: Conceitos Os nomes que aparecem em todas as rotas. | Termo | O que é | |---|---| | Empresa | A conta do cliente no ZapyChat. A chave de API pertence a uma empresa e só acessa os dados dela. | | Canal | Uma conexão de atendimento: um número de WhatsApp, uma conta de Instagram ou um e-mail. | | Contato | Uma pessoa que fala com a empresa. É identificado pelo telefone ou e-mail. | | Conversa | A troca de mensagens com um contato em um canal. Tem um status: PENDING, BOT, OPEN, WAITING ou CLOSED. | | Mensagem | Cada texto, imagem ou arquivo da conversa. direction diz se veio do cliente (INBOUND) ou da empresa (OUTBOUND). | | Tag | Etiqueta colorida para organizar contatos e conversas. | | Avaliação | A nota de 1 a 5 estrelas que o cliente dá ao atendimento e ao atendente. | ## Guia: Autenticação Toda chamada usa uma chave de API no cabeçalho Authorization. ```http Authorization: Bearer pk_sua_chave Content-Type: application/json ``` ### Permissões da chave | Permissão | Libera | |---|---| | read | Todas as rotas de consulta (GET). Toda chave tem. | | write | Rotas que criam ou alteram dados (POST, PATCH, DELETE). Só chaves criadas com esta permissão. | ### O que a chave enxerga A chave age como o usuário que a criou. Se esse usuário é um atendente com acesso restrito a certos canais ou só às próprias conversas, a API respeita as mesmas regras. Trate a chave como uma senha: não coloque em código de navegador nem em repositório público. Se vazar, revogue em Configurações › API Keys e crie outra. ## Guia: Respostas e erros O formato das respostas e o significado de cada código. ### Resposta de sucesso ```json { "data": { "id": "cmf3k9x1a0001", "status": "OPEN" }, "meta": { "timestamp": "2026-10-05T14:32:10.000Z" } } ``` ### Resposta de erro ```json { "statusCode": 404, "message": "Conversa não encontrada", "error": "NotFoundException", "timestamp": "2026-10-05T14:32:10.000Z", "path": "/api/v1/public/conversations/abc" } ``` Em erros de validação, message pode ser uma lista de textos. | Código | Significado | |---|---| | 200 / 201 | Deu certo. | | 400 | Algum campo está ausente ou inválido. A mensagem diz qual. | | 401 | Chave ausente, errada, vencida ou revogada. | | 402 | Assinatura da empresa vencida: só leitura até renovar. | | 403 | A chave não tem a permissão necessária (por exemplo, write). | | 404 | Não existe, ou a chave não tem acesso a esse item. | | 409 | Conflito: contato pediu para não receber mensagens, tag já existe, janela de 24 h fechada… | | 429 | Limite de chamadas excedido. Aguarde e tente de novo. | | 5xx | Falha do nosso lado. Tente novamente em alguns instantes. | ## Guia: Paginação Listas grandes vêm em páginas. As listas aceitam page (começa em 1) e limit (de 1 a 100, padrão 25) e respondem com os itens e o total. ```json { "items": [ ... ], "total": 134, "page": 2, "limit": 25 } ``` O histórico de mensagens usa um cursor: repita a chamada com before igual ao nextBefore recebido até ele vir null. Para manter outro sistema sincronizado, use o filtro updatedSince nas conversas e guarde a data da última sincronização. ## Guia: Limites e boas práticas Para a API continuar rápida para todo mundo. | Limite | Valor | |---|---| | Chamadas por chave | 300 por minuto | | Painel (dashboard) | 120 por minuto | | Mensagens enviadas por chave | 60 por minuto | | Tamanho do texto da mensagem | 4096 caracteres | | Período das consultas por data | até 1 ano | - Ao receber 429, espere alguns segundos e tente de novo, aumentando a espera a cada falha. - Prefira webhooks a ficar consultando a API de tempos em tempos. - Guarde os ids que a API devolve em vez de buscar de novo. ## Guia: Webhooks de saída O ZapyChat chama o seu servidor quando algo acontece, sem você precisar perguntar. Cadastre a URL em Configurações › Webhooks e escolha os eventos. Guarde o segredo mostrado na criação: é com ele que você confere que a chamada veio mesmo do ZapyChat. ### Eventos | Evento | Quando acontece | |---|---| | message.received | Chegou uma mensagem de um cliente. | | conversation.status_changed | O status de uma conversa mudou (aberta, encerrada…). | | conversation.assigned | Uma conversa foi atribuída a um atendente. | | tag.added | Uma tag foi aplicada a uma conversa ou contato. | | tag.removed | Uma tag foi removida de uma conversa ou contato. | ### Corpo da chamada ```json { "id": "evt_123", "event": "message.received", "organizationId": "cmf0org001", "createdAt": "2026-10-05T14:32:10.000Z", "data": { ... } } ``` ### Conferindo a assinatura Cada chamada traz os cabeçalhos X-ChatPRO-Event, X-ChatPRO-Timestamp e X-ChatPRO-Signature. A assinatura é sha256= seguido do HMAC-SHA256, com o seu segredo, do texto "{timestamp}.{corpo}". ```javascript import crypto from 'node:crypto'; function assinaturaValida(segredo, timestamp, corpoBruto, assinatura) { const esperada = 'sha256=' + crypto.createHmac('sha256', segredo).update(`${timestamp}.${corpoBruto}`).digest('hex'); return crypto.timingSafeEqual(Buffer.from(esperada), Buffer.from(assinatura)); } ``` Responda com um código 2xx em poucos segundos. Um endereço que falha muitas vezes seguidas é desativado automaticamente. ## Guia: Avaliações de atendimento Como o cliente avalia e como você lê as notas. Ao encerrar uma conversa, o cliente recebe um pedido de avaliação (se o envio automático estiver ligado em Configurações › Avaliações). Ele dá de 1 a 5 estrelas ao atendimento e ao atendente e pode comentar. | Estrelas | Significado | |---|---| | 1 | Ruim | | 2 | Regular | | 3 | Bom | | 4 | Muito bom | | 5 | Excelente | Use GET /public/ratings para a lista e GET /public/ratings/summary para médias e ranking. Para encerrar uma conversa e disparar a pesquisa pela API, use POST /public/conversations/{id}/close. ## Guia: Usando com assistentes de IA Dê a documentação inteira a um assistente para ele escrever a integração por você. A aba “Doc para IA” gera um texto único, em Markdown, com toda a referência. Copie e cole no seu assistente (ou baixe o arquivo) e peça, por exemplo: “crie uma função que lista as conversas abertas e responde às que estão sem resposta”. Nunca cole a sua chave de API real em conversas com IA. Use um valor de exemplo e coloque a chave em uma variável de ambiente. ## Referência: Identidade ### GET /public/me — Quem sou eu Identifica a chave de API: o usuário dono, a empresa e as permissões. Use para testar se a chave está funcionando. Permissão: read Exemplo de resposta (`data`): ```json { "user": { "id": "cmf1usr456", "name": "João Lima", "email": "joao@empresa.com" }, "organization": { "id": "cmf0org001", "name": "Minha Empresa", "slug": "minha-empresa", "userRole": "ADMIN" }, "scopes": [ "read", "write" ] } ``` ## Referência: Conversas ### GET /public/conversations — Listar conversas Lista as conversas que a chave pode ver, da mais recente para a mais antiga. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `status` | string | PENDING, BOT, OPEN, WAITING ou CLOSED. | | `channelId` | string | Só conversas deste canal. | | `contactId` | string | Só conversas deste contato. | | `assignedToId` | string | Só conversas deste atendente. | | `updatedSince` | string (ISO 8601) | Só conversas alteradas a partir desta data (bom para sincronizar). | | `page` | number | Página (começa em 1). Padrão: 1. | | `limit` | number | Itens por página, de 1 a 100. Padrão: 25. | Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf3k9x1a0001", "status": "OPEN", "channelId": "cmf0abc123", "channelName": "Vendas", "channelType": "WHATSAPP_MAGICAPI", "contactId": "cmf2xyz789", "contactName": "Maria Souza", "contactPhone": "5571999990000", "assignedToId": "cmf1usr456", "subject": null, "protocol": null, "isGroup": false, "lastMessageAt": "2026-10-05T14:32:10.000Z", "closedAt": null, "createdAt": "2026-10-05T14:10:00.000Z" } ], "total": 1, "page": 1, "limit": 25 } ``` - Chaves de atendente só enxergam as conversas que o atendente pode ver no painel. ### GET /public/conversations/{id} — Buscar uma conversa Devolve os dados de uma conversa. Permissão: read **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador da conversa. | Exemplo de resposta (`data`): ```json { "id": "cmf3k9x1a0001", "status": "OPEN", "channelId": "cmf0abc123", "channelName": "Vendas", "channelType": "WHATSAPP_MAGICAPI", "contactId": "cmf2xyz789", "contactName": "Maria Souza", "contactPhone": "5571999990000", "assignedToId": "cmf1usr456", "subject": null, "protocol": null, "isGroup": false, "lastMessageAt": "2026-10-05T14:32:10.000Z", "closedAt": null, "createdAt": "2026-10-05T14:10:00.000Z" } ``` ### GET /public/conversations/{id}/messages — Mensagens da conversa Histórico da conversa, da mensagem mais nova para a mais antiga. Para ir mais para trás, repita a chamada com `before` igual ao `nextBefore` recebido. Permissão: read **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador da conversa. | **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `limit` | number | De 1 a 100. Padrão: 30. | | `before` | string | Id de uma mensagem: devolve só as anteriores a ela. | Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf7msg001", "direction": "INBOUND", "type": "TEXT", "status": "DELIVERED", "text": "Oi, quero saber o preço", "mediaUrl": null, "createdAt": "2026-10-05T14:10:05.000Z" } ], "nextBefore": null } ``` - direction: INBOUND (cliente) ou OUTBOUND (empresa). nextBefore é null quando não há mais mensagens. ### POST /public/conversations/{id}/messages — Responder na conversa Envia uma mensagem de texto dentro de uma conversa que já existe, pelo mesmo canal dela. Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador da conversa. | **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `text` *(obrigatório)* | string | Texto da mensagem (até 4096 caracteres). | Exemplo de corpo: ```json { "text": "Olá! Já vou verificar para você." } ``` Exemplo de resposta (`data`): ```json { "id": "cmf7msg002", "status": "queued" } ``` - No WhatsApp oficial, fora da janela de 24 horas só é possível enviar templates. ### POST /public/conversations/{id}/close — Encerrar a conversa Encerra a conversa. Se o envio automático da pesquisa de avaliação estiver ligado, o cliente recebe o pedido de avaliação. Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador da conversa. | Exemplo de resposta (`data`): ```json { "id": "cmf3k9x1a0001", "status": "CLOSED", "channelId": "cmf0abc123", "channelName": "Vendas", "channelType": "WHATSAPP_MAGICAPI", "contactId": "cmf2xyz789", "contactName": "Maria Souza", "contactPhone": "5571999990000", "assignedToId": "cmf1usr456", "subject": null, "protocol": null, "isGroup": false, "lastMessageAt": "2026-10-05T14:32:10.000Z", "closedAt": "2026-10-05T15:30:00.000Z", "createdAt": "2026-10-05T14:10:00.000Z" } ``` ## Referência: Mensagens ### POST /public/messages — Enviar mensagem para um telefone Envia uma mensagem de texto para um número de telefone, por um canal de WhatsApp. O contato e a conversa são criados se ainda não existirem. Permissão: write **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `channelId` *(obrigatório)* | string | Canal de WhatsApp (veja GET /public/channels). | | `phone` *(obrigatório)* | string | Telefone com DDD. Aceita com ou sem +55 e símbolos. | | `text` *(obrigatório)* | string | Texto da mensagem (até 4096 caracteres). | | `name` | string | Nome do contato, usado se ele ainda não existir. | Exemplo de corpo: ```json { "channelId": "cmf0abc123", "phone": "(71) 99999-0000", "text": "Olá! Seu pedido saiu para entrega.", "name": "Maria Souza" } ``` Exemplo de resposta (`data`): ```json { "status": "queued", "conversationId": "cmf3k9x1a0001" } ``` - Limite de 60 mensagens por minuto por chave. - Contato que pediu para não receber mensagens: erro 409. Fora da janela de 24 h do WhatsApp oficial: erro 409. ## Referência: Contatos ### GET /public/contacts — Listar contatos Lista os contatos da empresa, do mais novo para o mais antigo. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `search` | string | Busca por nome, e-mail ou telefone. | | `tag` | string | Só contatos com esta tag (pelo nome). | | `page` | number | Página (começa em 1). Padrão: 1. | | `limit` | number | Itens por página, de 1 a 100. Padrão: 25. | Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com", "notes": null, "optedOut": false, "tags": [ { "id": "cmf4tag001", "name": "VIP", "color": "#6366f1" } ], "createdAt": "2026-09-20T10:00:00.000Z", "updatedAt": "2026-10-05T14:10:00.000Z" } ], "total": 1, "page": 1, "limit": 25 } ``` ### GET /public/contacts/{id} — Buscar um contato Devolve os dados de um contato, com as tags. Permissão: read **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador do contato. | Exemplo de resposta (`data`): ```json { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com", "notes": null, "optedOut": false, "tags": [ { "id": "cmf4tag001", "name": "VIP", "color": "#6366f1" } ], "createdAt": "2026-09-20T10:00:00.000Z", "updatedAt": "2026-10-05T14:10:00.000Z" } ``` ### POST /public/contacts — Criar ou atualizar contato Cria o contato, ou atualiza se já existir um com o mesmo telefone ou e-mail. Informe ao menos um dos dois. Permissão: write **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `phone` | string | Telefone com DDD. | | `email` | string | E-mail. | | `name` | string | Nome. | | `tags` | string[] | Tags a aplicar (criadas se não existirem; até 5). | Exemplo de corpo: ```json { "name": "Maria Souza", "phone": "71999990000", "email": "maria@exemplo.com", "tags": [ "VIP" ] } ``` Exemplo de resposta (`data`): ```json { "contact": { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com" }, "created": true } ``` ### PATCH /public/contacts/{id} — Editar contato Altera nome, e-mail ou observações. Só os campos enviados mudam. Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador do contato. | **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `name` | string | Novo nome. | | `email` | string | Novo e-mail (vazio remove). | | `notes` | string | Observações (vazio remove). | Exemplo de corpo: ```json { "notes": "Cliente prefere contato à tarde." } ``` Exemplo de resposta (`data`): ```json { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com", "notes": null, "optedOut": false, "tags": [ { "id": "cmf4tag001", "name": "VIP", "color": "#6366f1" } ], "createdAt": "2026-09-20T10:00:00.000Z", "updatedAt": "2026-10-05T14:10:00.000Z" } ``` ### POST /public/contacts/{id}/tags — Adicionar tag ao contato Aplica uma tag ao contato. A tag é criada se ainda não existir. Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador do contato. | **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `tag` *(obrigatório)* | string | Nome da tag (até 40 caracteres). | Exemplo de corpo: ```json { "tag": "Lead quente" } ``` Exemplo de resposta (`data`): ```json { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com", "notes": null, "optedOut": false, "tags": [ { "id": "cmf4tag001", "name": "VIP", "color": "#6366f1" } ], "createdAt": "2026-09-20T10:00:00.000Z", "updatedAt": "2026-10-05T14:10:00.000Z" } ``` ### DELETE /public/contacts/{id}/tags/{tag} — Remover tag do contato Tira a tag do contato (a tag continua existindo na empresa). Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador do contato. | | `tag` *(obrigatório)* | string | Nome da tag. | Exemplo de resposta (`data`): ```json { "id": "cmf2xyz789", "name": "Maria Souza", "phone": "5571999990000", "email": "maria@exemplo.com", "notes": null, "optedOut": false, "tags": [], "createdAt": "2026-09-20T10:00:00.000Z", "updatedAt": "2026-10-05T14:10:00.000Z" } ``` ## Referência: Canais ### GET /public/channels — Listar canais Canais (WhatsApp, Instagram, e-mail) que a chave pode usar. O `id` é o `channelId` usado ao enviar mensagens. Permissão: read Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf0abc123", "name": "Vendas", "type": "WHATSAPP_MAGICAPI", "isActive": true } ] } ``` ## Referência: Tags ### GET /public/tags — Listar tags Todas as tags da empresa. Permissão: read Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf4tag001", "name": "VIP", "color": "#6366f1" } ] } ``` ### POST /public/tags — Criar tag Cria uma tag. Se já existir uma com o mesmo nome, responde 409. Permissão: write **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `name` *(obrigatório)* | string | Nome (até 40 caracteres). | | `color` | string | Cor em hexadecimal, ex.: #22c55e. | Exemplo de corpo: ```json { "name": "Lead quente", "color": "#ef4444" } ``` Exemplo de resposta (`data`): ```json { "id": "cmf4tag002", "name": "Lead quente", "color": "#ef4444" } ``` ## Referência: Tarefas ### GET /public/tasks — Listar tarefas Tarefas atribuídas ao dono da chave ou criadas por ele. Administradores podem pedir todas com `scope=all`. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `status` | string | OPEN ou DONE. | | `contactId` | string | Só tarefas deste contato. | | `scope` | string | `all` para ver as de toda a empresa (só administradores). | Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf6tsk001", "title": "Ligar para o cliente", "description": null, "status": "OPEN", "dueAt": "2026-10-06T12:00:00.000Z", "completedAt": null, "assignedToId": "cmf1usr456", "contactId": "cmf2xyz789", "conversationId": null, "createdAt": "2026-10-05T14:40:00.000Z" } ] } ``` ### POST /public/tasks — Criar tarefa Cria uma tarefa atribuída ao dono da chave. Permissão: write **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `title` *(obrigatório)* | string | Título (até 200 caracteres). | | `description` | string | Detalhes. | | `dueAt` | string (ISO 8601) | Prazo. | | `contactId` | string | Contato relacionado. | Exemplo de corpo: ```json { "title": "Ligar para o cliente", "dueAt": "2026-10-06T12:00:00Z", "contactId": "cmf2xyz789" } ``` Exemplo de resposta (`data`): ```json { "id": "cmf6tsk001" } ``` ### PATCH /public/tasks/{id} — Concluir ou reabrir tarefa Muda o estado de uma tarefa. Permissão: write **Parâmetros de caminho** | Nome | Tipo | Descrição | |---|---|---| | `id` *(obrigatório)* | string | Identificador da tarefa. | **Corpo (JSON)** | Nome | Tipo | Descrição | |---|---|---| | `status` *(obrigatório)* | string | DONE (concluída) ou OPEN (reaberta). | Exemplo de corpo: ```json { "status": "DONE" } ``` Exemplo de resposta (`data`): ```json { "id": "cmf6tsk001", "status": "DONE", "completedAt": "2026-10-05T16:00:00.000Z" } ``` ## Referência: Avaliações ### GET /public/ratings — Listar avaliações Avaliações respondidas pelos clientes (nota do atendimento, nota do atendente e comentário), da mais recente para a mais antiga. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | | `agentId` | string | Só avaliações deste atendente. | | `minScore` | number | Nota mínima do atendimento (1 a 5). | | `maxScore` | number | Nota máxima do atendimento (1 a 5). | | `page` | number | Página (começa em 1). Padrão: 1. | | `limit` | number | Itens por página, de 1 a 100. Padrão: 25. | Exemplo de resposta (`data`): ```json { "items": [ { "id": "cmf5rat001", "score": 5, "agentScore": 4, "comment": "Atendimento rápido!", "source": "LINK", "respondedAt": "2026-10-05T15:00:00.000Z", "agentId": "cmf1usr456", "agentName": "João Lima", "conversationId": "cmf3k9x1a0001", "contactName": "Maria Souza" } ], "total": 1, "page": 1 } ``` - Notas de 1 a 5 estrelas: 1 = Ruim, 2 = Regular, 3 = Bom, 4 = Muito bom, 5 = Excelente. ### GET /public/ratings/summary — Resumo das avaliações Médias, distribuição das notas, taxa de resposta e ranking por atendente no período. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | | `agentId` | string | Só deste atendente. | Exemplo de resposta (`data`): ```json { "responses": 42, "sent": 80, "responseRate": 53, "avgScore": 4.5, "avgAgentScore": 4.6, "distribution": { "1": 1, "2": 2, "3": 4, "4": 12, "5": 23 }, "byAgent": [ { "agentId": "cmf1usr456", "agentName": "João Lima", "responses": 20, "avgScore": 4.7, "avgAgentScore": 4.8 } ] } ``` ## Referência: Painel ### GET /public/dashboard/overview — Visão geral Totais do período, comparação com o período anterior e situação atual (abertas, pendentes etc.). Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json { "activeConversations": 18, "totalConversations": 240, "totalMessages": 3120, "avgFirstResponseMinutes": 4.2, "slaCompliancePercent": 96, "resolutionRatePercent": 88 } ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/volume-by-day — Conversas por dia Quantidade de conversas criadas em cada dia. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "date": "2026-10-04", "count": 31 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/volume-by-channel — Conversas por canal Quantidade de conversas em cada canal. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "channelId": "cmf0abc123", "name": "Vendas", "count": 120 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/volume-by-status — Conversas por status Quantas conversas há agora em cada status (retrato do momento, sem período). Permissão: read Exemplo de resposta (`data`): ```json [ { "status": "OPEN", "count": 12 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/kpi-sparklines — Séries dos indicadores Série diária dos indicadores principais (ativas, tempo de resposta, SLA, resolução). Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json { "active": [], "firstResponse": [], "sla": [], "resolution": [] } ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/agent-performance — Desempenho dos atendentes Conversas atendidas e tempos por atendente. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "agentId": "cmf1usr456", "name": "João Lima", "conversations": 54 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/volume-flow — Criadas x encerradas Conversas criadas e encerradas por dia. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "date": "2026-10-04", "created": 31, "closed": 28 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/peak-hours — Horários de pico Mapa de calor de conversas por dia da semana e hora. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "day": 1, "hour": 10, "count": 14 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/messages-flow — Mensagens por dia Mensagens recebidas e enviadas por dia. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json [ { "date": "2026-10-04", "inbound": 220, "outbound": 260 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/bot-performance — Desempenho do robô Quanto o robô resolve sozinho e quanto passa para atendentes. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | Exemplo de resposta (`data`): ```json { "resolvedByBot": 40, "escalated": 12 } ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ### GET /public/dashboard/top-tags — Tags mais usadas Ranking das tags mais aplicadas no período. Permissão: read **Parâmetros de consulta (query)** | Nome | Tipo | Descrição | |---|---|---| | `from` | string (ISO 8601) | Início do período. Padrão: 30 dias atrás. | | `to` | string (ISO 8601) | Fim do período. Padrão: agora. O período pode ter no máximo 1 ano. | | `limit` | number | Quantas tags devolver. Padrão: 5. | Exemplo de resposta (`data`): ```json [ { "tag": "VIP", "count": 22 } ] ``` - O formato exato dos campos pode ganhar novos itens com o tempo; leia só o que precisa. ## Referência: Status ### GET /public/health — Saúde da API Mostra se a API e o banco de dados estão respondendo. Não precisa de chave. Responde 503 se o banco estiver fora. Permissão: aberta (sem chave) Exemplo de resposta (`data`): ```json { "status": "ok", "database": "ok", "latencyMs": 4, "time": "2026-10-05T14:00:00.000Z" } ```