# Integração com a credencial da agência: guia para agentes de código Este arquivo é para o agente de código (Claude Code, Cursor ou outro) que vai integrar um sistema à API v3 do Monde usando a credencial que a própria agência de viagens gerou. Siga os passos em ordem. Não pule a verificação do passo 7. Este guia **não** é o da conexão automática. Se o projeto é de um parceiro homologado que vai pôr o botão "Conectar com o Monde" para várias agências, o guia certo é `https://web.monde.com.br/automatic-connection-guide.md`. Se o usuário recebeu de uma agência um valor de credencial pronto, este é o guia certo. - `MONDE_API_CREDENTIAL`: variável de ambiente com a credencial. O valor nunca aparece neste arquivo, no código nem no chat. Host de todos os endpoints: `https://web.monde.com.br/api/v3`. ## 1. O que será implementado Um sistema da agência, ou de alguém que trabalha para ela, que lê ou grava dados no Monde dessa agência: um site que cadastra o cliente, um formulário que abre uma tarefa para o vendedor, um BI que lê as vendas. Não há fluxo de autorização: a credencial já vem pronta e vai, igual, no cabeçalho de toda requisição. ## 2. Antes de começar: passos que só o humano faz Pare e confirme com o usuário estes itens. Não continue sem eles. 1. **Licença.** A empresa da agência precisa da licença da API Monde. Sem ela, toda chamada responde `403`. Quem contrata é a agência, com o time comercial do Monde. 2. **Credencial.** Um usuário **administrador** da agência cria a credencial no Monde, em **Integrações > Adicionar > API Monde**. Na mesma tela, ele marca o que a credencial pode fazer em cada empresa (por exemplo, **Vendas > Ler todas as vendas** ou **Pessoas > Inserir e editar**). A credencial só faz o que foi marcado ali. 3. **Valor da credencial.** Ao salvar, o Monde mostra o valor uma única vez. Peça ao usuário para gravá-lo em `MONDE_API_CREDENTIAL` no ambiente do backend (arquivo `.env` fora do controle de versão, ou o gerenciador de segredos do projeto). **Não peça o valor no chat.** Se o usuário colar o valor no chat, não o escreva em nenhum arquivo. Peça a ele para gravá-lo na variável de ambiente e para gerar uma credencial nova no Monde, em **Gerar nova credencial**, porque a que passou pelo chat deve ser tratada como vazada. 4. **O que a integração vai fazer.** Pergunte quais dados o sistema vai ler e quais vai gravar, e em qual empresa da agência. Compare com as permissões que o administrador marcou. Se faltar permissão, peça ao administrador para marcá-la antes de você codar. ## 3. Regras invioláveis - A credencial fica **só no backend**. Ela nunca vai para o navegador, para app de celular, para log, para mensagem de erro ou para o controle de versão. - Não decodifique, não monte e não altere a credencial. Ela é opaca: use o valor exatamente como o Monde entregou. - **Não existe ambiente de testes.** A credencial grava na base real da agência. Não faça `POST`, `PATCH` nem `DELETE` para testar: cada um cria ou altera um registro de verdade. Teste com `GET`. - Use só endpoint que a documentação marca como disponível. O que aparece como **Em desenvolvimento** ainda não existe; o que aparece como **Beta** funciona, mas pode mudar. - Antes de usar um endpoint, leia o contrato dele na especificação (passo 4). Não deduza campos pelo nome nem por outra API. ## 4. Onde está o contrato da API - **Especificação OpenAPI em YAML**, para ler como máquina: `https://web.monde.com.br/api/v3/documentation/file`. Em inglês: `https://web.monde.com.br/api/v3/documentation/file?locale=en`. Leia a especificação, não a página HTML: ela traz todos os endpoints, campos, exemplos e erros. - **Página da documentação**, para o humano: `https://web.monde.com.br/api/v3/documentation`. A seção **Changelog** da especificação diz o que mudou e quando. Leia antes de reaproveitar código antigo de integração. ## 5. Identifique a stack antes de codar Leia o projeto antes de escrever código e responda: 1. Qual é a linguagem e o framework do backend? 2. Como o projeto lê variáveis de ambiente? 3. Qual cliente HTTP o backend já usa? 4. Onde o projeto guarda o que precisa lembrar entre execuções (por exemplo, o `id` de um registro já criado no Monde)? Use o que o projeto já tem. Não adicione SDK nem biblioteca só para esta integração: são requisições HTTP com JSON. ## 6. Como chamar a API Toda requisição leva estes cabeçalhos, inclusive `GET`: ``` Authorization: Bearer $MONDE_API_CREDENTIAL Content-Type: application/json ``` Sem o `Content-Type: application/json`, a API responde `415`. A única exceção é o envio de anexo, que a especificação marca como `multipart/form-data`. **Identificadores.** - Registro que já existe no Monde é referenciado pelo `id` dele, um UUID que a própria API devolve (por exemplo, `category_id` ou `assignee_id`). Busque o `id` num `GET` antes de gravar. Não invente nem converta. - A empresa da agência é informada pelo CNPJ, no campo `company_identifier`, quando o endpoint pede. - O `external_id` é o identificador que **o seu sistema** dá ao registro e que o Monde guarda junto dele. É único por credencial: a mesma credencial não dá o mesmo `external_id` a dois registros. Uma credencial nova (criada em **Adicionar**, não em **Gerar nova credencial**) não enxerga os `external_id` gravados pela anterior. - Ao inserir um registro (por exemplo, uma pessoa), envie o `external_id` do seu sistema. Se ele já identifica alguém, a API recusa com `422`, e é isso que impede a duplicação quando a mesma pessoa é enviada de novo dias depois. - Quando o endpoint aceita criar uma pessoa junto do registro principal (por exemplo, o pagante de uma venda), o mesmo `external_id` aponta para a pessoa que já existe, sem duplicar o cadastro. **Gravação: `Idempotency-Key`.** Os endpoints de gravação que a especificação marca com o cabeçalho `Idempotency-Key` (criar venda, inserir pessoa, criar tarefa, por exemplo) exigem um UUID v4 nele. - Uma chave por operação: gere a chave quando decidir gravar e **guarde a chave junto com o corpo antes de enviar**, no mesmo lugar onde o projeto guarda o que lembra entre execuções. Assim, se o processo cair no meio, a nova tentativa reenvia a mesma chave. - Ao repetir a **mesma** operação depois de um timeout, de uma falha de rede ou de um `429`, envie a **mesma** chave e o **mesmo** corpo. A API não grava de novo: devolve `200` com o corpo da primeira resposta e o cabeçalho `X-Idempotent-Replay: true`. A primeira gravação costuma responder `201`, então trate `200` e `201` como sucesso. - Mudou o corpo, mudou a operação: gere uma chave nova. Vale também para o corpo corrigido depois de um `422` de validação. - A chave vale por 1 dia. Passado isso, é o `external_id` que segura a duplicação. - `409` numa requisição com chave: em geral, a primeira requisição com essa chave ainda está em processamento. Espere e repita com a mesma chave, poucas vezes e com intervalo crescente. Se o `409` persistir, pare: o estado do registro impede a gravação (por exemplo, alterar uma tarefa excluída), e repetir não resolve. Em requisição sem chave, o `409` também é desse tipo (por exemplo, excluir um registro que tem vínculos): leia a especificação do endpoint e não repita. - `422` com a mesma chave e outro corpo: a chave já foi usada para outra operação. Isso não acontece se você seguir a regra de uma chave por corpo. **Listas: paginação por cursor.** 1. Faça a primeira requisição sem `cursor`. O parâmetro `size` vai de 1 a 50 (padrão 20). 2. Enquanto `pagination.has_next_page` for `true`, repita a requisição com `cursor` igual ao `pagination.next_cursor` da resposta anterior e com os **mesmos** filtros. 3. Quando `has_next_page` for `false`, a varredura terminou. O cursor é opaco: guarde e devolva como veio. A resposta não traz o total de registros. **Limite de requisições.** A API conta as requisições por IP de origem; o limite está na seção **Limites de requisição** da especificação. Ao receber `429`, espere e repita com intervalo crescente (backoff exponencial). Na gravação, repita com a mesma `Idempotency-Key`. Não dispare requisições em paralelo para varrer uma lista: siga o cursor, uma página por vez. **Endereço configurável.** Leia o endereço base da API de uma variável de ambiente (por exemplo, `MONDE_API_BASE_URL`, com `https://web.monde.com.br/api/v3` como padrão), sem fixá-lo no código. **Formato das respostas.** - Lista: `{ "data": [...], "pagination": { ... } }`. - Registro único: o objeto, sem envelope. - Erro: `{ "errors": ["mensagem"] }`. A mensagem é para log e para o humano. Decida pelo status HTTP, não pelo texto. ## 7. Verificação: quando a integração está pronta Escolha um `GET` de um recurso que o administrador liberou para leitura e chame com a credencial. Por exemplo, se ele liberou **Vendas > Ler todas as vendas**: ```bash curl "https://web.monde.com.br/api/v3/sales?size=1" \ -H "Authorization: Bearer $MONDE_API_CREDENTIAL" \ -H "Content-Type: application/json" ``` | Resposta | Significado | |---|---| | `200` | A credencial autentica e tem a permissão. **A conexão está pronta.** | | `401` com `{"errors":["Credenciais de acesso não são válidas."]}` | Credencial errada, desativada ou substituída por uma nova. Peça ao usuário para conferir `MONDE_API_CREDENTIAL`. | | `403` com `{"errors":["Você não tem permissão para executar essa ação."]}` | A credencial autentica, mas não tem essa permissão em nenhuma empresa. Peça ao administrador para marcá-la. | | `403` com `{"errors":["Você não possui licença de API. ..."]}` | A credencial tem a permissão, mas a empresa não tem a licença da API. A agência precisa contratar. | A integração só está pronta depois que o `GET` de cada recurso que ela vai **ler** responde `200`. Para o que ela vai **gravar**, confira o corpo contra a especificação e combine com o usuário a primeira gravação real: ela vai aparecer no Monde da agência. ## 8. Quando a credencial deixa de valer A credencial não expira. Ela para de funcionar, com `401`, quando a agência: - desativa ou exclui a credencial; - clica em **Gerar nova credencial**, que invalida a anterior na hora. Ao receber `401`, pare as chamadas, registre o erro no log sem a credencial e avise o usuário. Não repita a chamada em loop: a credencial não volta a valer sozinha. ## 9. Erros comuns | Onde | Resposta | Causa | O que fazer | |---|---|---|---| | Qualquer chamada | `401` | Credencial errada, desativada ou substituída | Conferir `MONDE_API_CREDENTIAL` e falar com o administrador da agência | | Qualquer chamada | `403` "Você não tem permissão..." | Falta a permissão do recurso na credencial | Pedir ao administrador para marcá-la em **Integrações** | | Qualquer chamada | `403` "Você não possui licença de API..." | A empresa não tem a licença da API | A agência contrata com o comercial do Monde | | Gravação | `403` "Sua licença de API não dá acesso a esta ação." | A licença da empresa é somente leitura | A consulta segue liberada. Para gravar, a agência ajusta a licença com o comercial | | Qualquer chamada | `415` | Falta `Content-Type: application/json` | Enviar o cabeçalho em toda chamada, inclusive `GET` (no envio de anexo, `multipart/form-data`) | | Gravação | `400` | Falta o `Idempotency-Key`, ou ele não é UUID; ou o JSON está malformado | Enviar um UUID v4 e conferir o corpo | | Gravação com chave | `409` | A requisição com essa chave ainda está em processamento, ou o registro não aceita a gravação (por exemplo, tarefa excluída) | Esperar e repetir com a mesma chave, poucas vezes; se persistir, parar e ler a mensagem | | Exclusão | `409` | O registro tem vínculos que impedem a exclusão | Não repetir. Ler a mensagem e tratar o vínculo | | Gravação | `422` | Corpo fora do contrato, `external_id` que já identifica outro registro, ou chave reaproveitada com outro corpo | Ler a mensagem e corrigir o corpo contra a especificação. Corpo novo, chave nova | | Consulta | `400` | Filtro em formato errado, ou cursor que a API não devolveu | Conferir o filtro na especificação; usar o `next_cursor` como veio | | Consulta | `404` | O `id` não existe ou não está ao alcance da credencial | Buscar o `id` de novo pela listagem | | Qualquer chamada | `429` | Limite de requisições excedido | Esperar e repetir com intervalo crescente | | Qualquer chamada | `500` | Erro no Monde | Repetir uma vez mais tarde; se persistir, falar com o suporte (`suporte@monde.com.br`) |