# Api's de integração

# Meu Token (para proprietários)

Para saber seu **TOKEN** de acesso a API, dentro do sistema acesse **MENU -&gt; MEU PERFIL -&gt; MEUS DADOS**.

**![❗](https://fonts.gstatic.com/s/e/notoemoji/17.0/2757/32.png)Tokens só estarão disponíveis para usuários com perfil de PROPRIETÁRIO.**

[![image.png](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/scaled-1680-/s9Himage.png)](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/s9Himage.png)

**![❗](https://fonts.gstatic.com/s/e/notoemoji/17.0/2757/32.png)Se por acaso seu token foi exposto, basta clicar em Gerar novo token que o antigo token será automáticamente inativado.**

**⚠️ Atenção!**  
Use sempre HTTPS e mantenha o token de integração protegido. Não publique o token em código-fonte, repositórios, prints ou logs.

# Gerar Token para Meus Usuários

Se você tiver o perfil **PROPRIETÁRIO**, você poderá gerar Tokens para seus usuarios.   
Com o token eles irão conseguir utilzar as integrações disponíveis, SEMPRE limitados à sua hierarquia.

Para isso acesse **MENU -&gt; USUÁRIOS -&gt; CADASTRO DE USUÁRIOS**, filtre e selecione o usuário em questão.  
Clique em Editar, no final do formulário estará o token do usuário.

[![image.png](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-10/scaled-1680-/hdKimage.png)](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-10/hdKimage.png)

Cuidado ao compartilhar o token.  
Caso haja vazamento, basta acessar o cadatro do usuário e clicar em **GERAR NOVO TOKEN**.

# Produção

# Api de Carga da Produção

A API de Produção permite consultar os dados que participam de um Painel de Produção autorizado.

Use a API para:

- fazer uma carga inicial da base;
- buscar somente registros atualizados em intervalos posteriores;
- receber os dados em JSON ou CSV.

## Endereço base

```
https://api.xeotech.com.br/api/v1/producao/carga/SEU_TOKEN
```

O token é informado na URL. Não envie o token no corpo do payload.  
  
Quer saber como localizar seu TOKEN dentro do sistema? Clique [aqui.](https://ajuda.xeotech.com.br/books/apis-de-integracao/page/meu-token-para-proprietarios)

## Autorização

O token precisa ser um token de integração de usuário ativo. O usuário também precisa ter acesso à estrutura do painel informado e possuir as permissões:

- `PAINEL_PRODUCAO_VIEW`
- `PAINEL_PRODUCAO_EXPORTACAO`

A API respeita a hierarquia do usuário. A permissão `IGNORAR_HIERARQUIA` é aplicada pelo próprio Xeotech, de acordo com o usuário autorizado.

Painel, estrutura, vínculo ou permissão indisponível retornam `403`. Token inválido retorna `401`.

## Formatos

O campo `formato` aceita:

- `json` — recomendado para integrações e sincronização;
- `csv` — UTF-8 com BOM, separador `;`, cabeçalho e quebra de linha CRLF. Na carga, o cabeçalho é fixo e segue os 80 campos listados nesta página.

Se `formato` não for informado, o retorno será JSON.

---

## Chamada

A carga é usada para criar ou atualizar uma cópia dos dados do Xeotech. Baixe a sua base de produção e atualize de hora em hora para manter uma cópia da base de produção.

```
POST /api/v1/producao/carga/{token}
Content-Type: application/json
```

### Payload

```
{
  "painelId": 123,
  "dataHoraInicioCarga": "2026-09-30 09:00:00",
  "dataHoraFimCarga": "2026-09-30 10:00:00",
  "formato": "json"
}
```

<table id="bkmrk-campo-obrigat%C3%B3rio-de"><thead><tr class="header"><th>Campo</th><th style="text-align: right;">Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`painelId`</td><td style="text-align: right;">Sim</td><td>ID do Painel de Produção que será consultado.</td></tr><tr class="even"><td>`dataHoraInicioCarga`</td><td style="text-align: right;">Sim</td><td>Início do período, no formato `yyyy-MM-dd HH:mm:ss`.</td></tr><tr class="odd"><td>`dataHoraFimCarga`</td><td style="text-align: right;">Não</td><td>Fim do período. Se omitido, o Xeotech usa o horário de recebimento da requisição.</td></tr><tr class="even"><td>`formato`</td><td style="text-align: right;">Não</td><td>`json` ou `csv`. O padrão é `json`.</td></tr></tbody></table>

Para saber o ID do painel (painelId) acesse MENU -&gt; PRODUÇÃO -&gt; PAINEL DE PRODUÇÃO

[![image.png](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/scaled-1680-/oYeimage.png)](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/oYeimage.png)

As datas usam o fuso `America/Sao_Paulo`.

O filtro é aplicado assim:

```
pedido.data_hora_atualizacao >= dataHoraInicioCarga
pedido.data_hora_atualizacao < dataHoraFimCarga
```

O início é inclusivo e o fim é exclusivo. Para a próxima carga, é possível usar o fim da carga anterior como início da seguinte.

Durante o dia, entre 05:00 e 22:00, o período máximo é de 90 minutos. Entre 22:00 e 05:00 é possível solicitar períodos maiores, respeitando os limites de registros, tamanho do arquivo e tempo de processamento.

### cURL — JSON

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/producao/carga/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output carga-producao.json \
  --data '{
    "painelId": 123,
    "dataHoraInicioCarga": "2026-09-30 09:00:00",
    "dataHoraFimCarga": "2026-09-30 10:00:00",
    "formato": "json"
  }'
```

### cURL — CSV

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/producao/carga/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output carga-producao.csv \
  --data '{
    "painelId": 123,
    "dataHoraInicioCarga": "2026-09-30 09:00:00",
    "dataHoraFimCarga": "2026-09-30 10:00:00",
    "formato": "csv"
  }'
```

### Carga inicial e cargas seguintes

Para a primeira carga, use um período histórico adequado, preferencialmente durante a janela noturna. Depois, faça cargas menores, por exemplo, de hora em hora, sempre usando a data de atualização como controle.

A API não informa exclusões. Se um pedido ou item deixar de participar do painel, ele não aparecerá necessariamente em uma carga incremental. Faça uma reconciliação completa periódica e use uma sobreposição de alguns minutos entre cargas para reduzir o risco de atualizações tardias.

## Retornos da API

No formato JSON, a carga retorna `meta`, `dados` e `totalRegistros`. Cada elemento de `dados` representa uma linha da carga e contém os 80 campos documentados abaixo. O relatório de exportação possui um contrato próprio, descrito na página dessa operação.

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-meta"><thead><tr><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr><td>`meta`</td><td>Versão, painel, operação, fuso, horário de recebimento (`recebidoEm`) e período utilizado.</td></tr><tr><td>`dados`</td><td>Lista de registros. Retorna `[]` quando não houver resultados.</td></tr><tr><td>`totalRegistros`</td><td>Quantidade de linhas retornadas, não a soma do campo `quantidade`.</td></tr></tbody></table>

Datas são retornadas como `yyyy-MM-dd`; data e hora, como `yyyy-MM-ddTHH:mm:ss`, podendo conter frações de segundo. Os exemplos abaixo são fictícios. Considere o fuso `America/Sao_Paulo`; os valores não incluem um deslocamento UTC.

### Retorno da carga

O exemplo abaixo apresenta uma linha completa da carga, com os 80 campos retornados pela API, incluindo campos sem valor. Os valores são fictícios. A tabela seguinte lista os mesmos campos na ordem do cabeçalho CSV.

```
{
  "meta": {
    "versao": "v1",
    "painelId": 123,
    "operacao": "carga",
    "fusoHorario": "America/Sao_Paulo",
    "recebidoEm": "2026-10-05T16:44:05",
    "dataHoraInicioCarga": "2026-10-01T13:00:00",
    "dataHoraFimCarga": "2026-10-01T14:00:00",
    "intervalo": "inicioInclusivoFimExclusivo"
  },
  "dados": [
    {
      "id": "123:1001:2001:10:20",
      "pedidoId": 1001,
      "linhaId": 10,
      "colunaId": 20,
      "nomeLinha": "VOZ - Renovação",
      "nomeColuna": "Ativo/Instalado",
      "quantidade": 5,
      "valor": 199.95,
      "valorUnitario": 39.99,
      "valorDesconto": 0,
      "valorBaseAtual": 0,
      "valorAgregado": 0,
      "numeroPedido": "1001",
      "numeroPedidoOrigem": null,
      "numeroPedidoVinculado": null,
      "tipoNegociacao": "NOVO",
      "clienteId": 3001,
      "nomeCliente": "Empresa Exemplo Ltda.",
      "cpfCnpj": "12345678000190",
      "cidade": "BALNEARIO CAMBORIU",
      "estado": "SC",
      "ddd": "47",
      "estruturaUsuarioId": 4001,
      "nomeUsuario": "Consultor Exemplo",
      "nomeUsuarioAdm": null,
      "equipeId": null,
      "nomeEquipe": null,
      "nomeEtapa": "ATIVO (NEOCRM)",
      "nomeEtapaItem": "CONCLUIDO",
      "dataCadastro": "2026-09-28",
      "dataHoraAtualizacao": "2026-10-01T13:50:13",
      "dataPortabilidade": null,
      "nomeOrigem": "NEOCRM",
      "item": null,
      "itemId": 2001,
      "pedidoItemSolicitacaoId": 4,
      "produtoId": 5001,
      "produtoCategoriaId": 1,
      "nomeProduto": "Plano de voz - Exemplo",
      "nomeCategoria": "VOZ",
      "numeroTelefoneItem": "",
      "dataReferencia": "2026-10-01",
      "nomeConsultorOperadora": null,
      "notasFiscais": null,
      "revisao": null,
      "loginOperadora": null,
      "atividades": null,
      "tags": "",
      "percentualDesconto": null,
      "percentualTroca": null,
      "cep": "88330000",
      "clusterOrigem": null,
      "solicitacaoId": 4,
      "nomeSolicitacao": "RENOVAÇÃO",
      "somaQuantidade": true,
      "dataInstalacao": null,
      "periodo": null,
      "rpon": "",
      "instancia": "",
      "cepInstalacao": null,
      "logradouroInstalacao": null,
      "numeroInstalacao": null,
      "bairroInstalacao": null,
      "complInstalacao": null,
      "cidadeInstalacao": null,
      "estadoInstalacao": null,
      "numeroProvisorio": "",
      "codigoPortabilidade": null,
      "cotacao": null,
      "aparelhoCartaoCredito": null,
      "categoriaAtividade": null,
      "subCategoriaAtividade": null,
      "numeroSimulacao": null,
      "operadoraCedente": "",
      "nomeCedente": "",
      "telefoneCedente": "",
      "emailCedente": "",
      "cpfCnpjCedente": "",
      "claroConvergenciaResposta": null,
      "claroTabelaRenovacao": null
    }
  ],
  "totalRegistros": 1
}
```

Campos da carga, na ordem do cabeçalho CSV:

<table id="bkmrk-posi%C3%A7%C3%B5es-campos-1%E2%80%938-"><thead><tr><th>Posições</th><th>Campos</th></tr></thead><tbody><tr><td>1–8</td><td>`id`, `pedidoId`, `linhaId`, `colunaId`, `nomeLinha`, `nomeColuna`, `quantidade`, `valor`</td></tr><tr><td>9–16</td><td>`valorUnitario`, `valorDesconto`, `valorBaseAtual`, `valorAgregado`, `numeroPedido`, `numeroPedidoOrigem`, `numeroPedidoVinculado`, `tipoNegociacao`</td></tr><tr><td>17–24</td><td>`clienteId`, `nomeCliente`, `cpfCnpj`, `cidade`, `estado`, `ddd`, `estruturaUsuarioId`, `nomeUsuario`</td></tr><tr><td>25–32</td><td>`nomeUsuarioAdm`, `equipeId`, `nomeEquipe`, `nomeEtapa`, `nomeEtapaItem`, `dataCadastro`, `dataHoraAtualizacao`, `dataPortabilidade`</td></tr><tr><td>33–40</td><td>`nomeOrigem`, `item`, `itemId`, `pedidoItemSolicitacaoId`, `produtoId`, `produtoCategoriaId`, `nomeProduto`, `nomeCategoria`</td></tr><tr><td>41–48</td><td>`numeroTelefoneItem`, `dataReferencia`, `nomeConsultorOperadora`, `notasFiscais`, `revisao`, `loginOperadora`, `atividades`, `tags`</td></tr><tr><td>49–56</td><td>`percentualDesconto`, `percentualTroca`, `cep`, `clusterOrigem`, `solicitacaoId`, `nomeSolicitacao`, `somaQuantidade`, `dataInstalacao`</td></tr><tr><td>57–64</td><td>`periodo`, `rpon`, `instancia`, `cepInstalacao`, `logradouroInstalacao`, `numeroInstalacao`, `bairroInstalacao`, `complInstalacao`</td></tr><tr><td>65–72</td><td>`cidadeInstalacao`, `estadoInstalacao`, `numeroProvisorio`, `codigoPortabilidade`, `cotacao`, `aparelhoCartaoCredito`, `categoriaAtividade`, `subCategoriaAtividade`</td></tr><tr><td>73–80</td><td>`numeroSimulacao`, `operadoraCedente`, `nomeCedente`, `telefoneCedente`, `emailCedente`, `cpfCnpjCedente`, `claroConvergenciaResposta`, `claroTabelaRenovacao`</td></tr></tbody></table>

Campos sem informação podem retornar `null` ou texto vazio `""`, conforme o cadastro. Valores numéricos e booleanos preservam seus tipos no JSON. Se não houver linhas, a API retorna `dados: []` e `totalRegistros: 0`.

Campos sem informação podem retornar `null`. A carga não acrescenta os complementos calculados do relatório, como `formularios`, `tagsAtividade` e `variacaoRenovacao`.

Na carga, o identificador da linha segue o formato:

```
painelId:pedidoId:itemId:linhaId:colunaId
```

Use o campo `id` para fazer `upsert` na sua cópia local. Essa orientação se aplica exclusivamente à carga: o relatório de exportação não retorna esse identificador.

## Limites de proteção

Os limites abaixo somam as chamadas de **carga** e **exportação**.

<table id="bkmrk-regra-limite-padr%C3%A3o-"><thead><tr class="header"><th>Regra</th><th style="text-align: right;">Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Exportações simultâneas globais</td><td style="text-align: right;">2</td></tr><tr class="even"><td>Exportações simultâneas por estrutura</td><td style="text-align: right;">1</td></tr><tr class="odd"><td>Intervalo mínimo após uma execução</td><td style="text-align: right;">120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td style="text-align: right;">3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td style="text-align: right;">20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td style="text-align: right;">600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td style="text-align: right;">8</td></tr><tr class="even"><td>Registros por resposta</td><td style="text-align: right;">1.000.000</td></tr><tr class="odd"><td>Tamanho máximo do arquivo</td><td style="text-align: right;">1 GiB</td></tr><tr class="even"><td>Tamanho máximo do payload</td><td style="text-align: right;">16 KiB</td></tr><tr class="odd"><td>Tempo máximo solicitado para a consulta</td><td style="text-align: right;">600 segundos</td></tr><tr class="even"><td>Tempo máximo de geração da resposta</td><td style="text-align: right;">900 segundos</td></tr></tbody></table>

As tentativas recusadas também entram no controle de tentativas. Quando um limite temporário for atingido, a resposta será `429` e terá o header `Retry-After` com a quantidade aproximada de segundos para nova tentativa.

Os limites são aplicados por estrutura, mesmo que o cliente altere o período, o painel ou o formato entre chamadas. Enquanto uma exportação estiver em andamento, uma segunda chamada para a mesma estrutura será recusada.

## Respostas de erro

<table id="bkmrk-http-c%C3%B3digo-comum-si"><thead><tr class="header"><th style="text-align: right;">HTTP</th><th>Código comum</th><th>Situação</th></tr></thead><tbody><tr class="odd"><td style="text-align: right;">`400`</td><td>`PAYLOAD_INVALIDO`</td><td>Campo ausente, data inválida ou período incorreto.</td></tr><tr class="even"><td style="text-align: right;">`401`</td><td>`TOKEN_INVALIDO`</td><td>Token inválido.</td></tr><tr class="odd"><td style="text-align: right;">`403`</td><td>`ACESSO_NEGADO`</td><td>Sem acesso ao painel ou às permissões necessárias.</td></tr><tr class="even"><td style="text-align: right;">`413`</td><td>`PAYLOAD_GRANDE`</td><td>Payload maior que 16 KiB.</td></tr><tr class="odd"><td style="text-align: right;">`422`</td><td>`LIMITE_REGISTROS` ou `LIMITE_ARQUIVO`</td><td>Resultado acima dos limites permitidos.</td></tr><tr class="even"><td style="text-align: right;">`429`</td><td>`LIMITE_API`</td><td>Guard ocupado, cooldown ou excesso de tentativas.</td></tr><tr class="odd"><td style="text-align: right;">`504`</td><td>`TEMPO_EXCEDIDO`</td><td>Consulta ou geração excedeu o tempo permitido.</td></tr></tbody></table>

Exemplo de erro:

```
{
  "codigo": "LIMITE_API",
  "mensagem": "Aguarde entre exportações da API.",
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000"
}
```

Guarde o `requestId` ao registrar uma falha. Ele ajuda o suporte a localizar a execução nos logs.

## Boas práticas de integração

- Use JSON quando precisar preservar tipos, datas, nulos e valores numéricos.
- Use CSV quando a carga for consumida por ferramentas de análise ou planilhas.
- Salve o arquivo em uma área temporária e só confirme a carga depois de validar o HTTP 200, o `Content-Length` e o `X-Total-Registros`.
- Na carga, faça `upsert` usando o ID estável da linha. A exportação é um relatório sem esse ID.
- Na carga, mantenha o último intervalo confirmado e use pequenas sobreposições entre chamadas.
- Faça uma reconciliação completa periódica para tratar exclusões e mudanças que não atualizaram o pedido.
- Respeite o `Retry-After` e não repita imediatamente uma resposta `429`.
- Nunca registre o token completo em logs.

# Api do Relatório de exportação

Esse endpoint retorna os campos e cálculos do relatório da tela do Painel de Produção em JSON ou CSV, respeitando o usuário, o painel e a hierarquia autorizada. **O retorno é diferente da carga:** não inclui os IDs internos e seleciona os campos conforme o tipo da estrutura. Formulários e tags são agrupados em campos próprios na API, em vez de colunas individuais do Excel.

## Endereço base

```
https://api.xeotech.com.br/api/v1/producao/exportacao/SEU_TOKEN
```

O token é informado na URL. Não envie o token no corpo do payload.  
  
Quer saber como localizar seu TOKEN dentro do sistema? Clique [aqui.](https://ajuda.xeotech.com.br/books/apis-de-integracao/page/meu-token-para-proprietarios)

## Autorização

O token precisa ser um token de integração de usuário ativo. O usuário também precisa ter acesso à estrutura do painel informado e possuir as permissões:

- `PAINEL_PRODUCAO_VIEW`
- `PAINEL_PRODUCAO_EXPORTACAO`

A API respeita a hierarquia do usuário. A permissão `IGNORAR_HIERARQUIA` é aplicada pelo próprio Xeotech, de acordo com o usuário autorizado.

Painel, estrutura, vínculo ou permissão indisponível retornam `403`. Token inválido retorna `401`.

## Formatos

O campo `formato` aceita:

- `json` — recomendado para integrações e sincronização;
- `csv` — UTF-8 com BOM, separador `;`, cabeçalho e quebra de linha CRLF. Na carga, o cabeçalho é fixo; na exportação, depende do tipo da estrutura.

Se `formato` não for informado, o retorno será JSON.

---

## Chamada  


A api de exportação reflete exatamente a exportação do painel de produção.

```
POST /api/v1/producao/exportacao/{token}
Content-Type: application/json
```

Na exportação, envie `dataInicio` e `dataFim`. Não envie `dataHoraInicioCarga` nem `dataHoraFimCarga`.

### Payload

```
{
  "painelId": 123,
  "dataInicio": "2026-09-01",
  "dataFim": "2026-09-30",
  "formato": "csv"
}
```

<table id="bkmrk-campo-obrigat%C3%B3rio-de-1"><thead><tr class="header"><th>Campo</th><th style="text-align: right;">Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`painelId`</td><td style="text-align: right;">Sim</td><td>ID do Painel de Produção.</td></tr><tr class="even"><td>`dataInicio`</td><td style="text-align: right;">Sim</td><td>Data inicial no formato `yyyy-MM-dd`.</td></tr><tr class="odd"><td>`dataFim`</td><td style="text-align: right;">Sim</td><td>Data final no formato `yyyy-MM-dd`.</td></tr><tr class="even"><td>`formato`</td><td style="text-align: right;">Não</td><td>`json` ou `csv`. O padrão é `json`.</td></tr></tbody></table>

O período máximo é de três meses, contando as duas datas. Por exemplo, `01/01` a `31/03` é válido; `01/01` a `01/04` ultrapassa o limite.  
  
Para saber o ID do painel (painelId) acesse MENU -&gt; PRODUÇÃO -&gt; PAINEL DE PRODUÇÃO[![image.png](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/scaled-1680-/h8Oimage.png)](https://ajuda.xeotech.com.br/uploads/images/gallery/2026-09/h8Oimage.png)

### cURL — CSV

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/producao/exportacao/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output exportacao-producao.csv \
  --data '{
    "painelId": 123,
    "dataInicio": "2026-09-01",
    "dataFim": "2026-09-30",
    "formato": "csv"
  }'
```

### cURL — JSON

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/producao/exportacao/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output exportacao-producao.json \
  --data '{
    "painelId": 123,
    "dataInicio": "2026-09-01",
    "dataFim": "2026-09-30",
    "formato": "json"
  }'
```

---

## Retornos da API

A api retorna um objeto JSON com `meta`, `dados` e `totalRegistros`. Cada elemento de `dados` representa uma linha do resultado. Os campos da linha dependem da operação.

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-meta"><thead><tr><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr><td>`meta`</td><td>Versão, painel, operação, fuso, horário de recebimento (`recebidoEm`) e período utilizado.</td></tr><tr><td>`dados`</td><td>Lista de registros. Retorna `[]` quando não houver resultados.</td></tr><tr><td>`totalRegistros`</td><td>Quantidade de linhas retornadas, não a soma do campo `quantidade`.</td></tr></tbody></table>

Datas são retornadas como `yyyy-MM-dd`; data e hora, como `yyyy-MM-ddTHH:mm:ss`, podendo conter frações de segundo. Os exemplos abaixo são fictícios. Considere o fuso `America/Sao_Paulo`; os valores não incluem um deslocamento UTC.

### Retorno do relatório de exportação

A exportação retorna os campos do relatório aplicáveis à estrutura. Campos que não se aplicam são **omitidos** do JSON e do cabeçalho CSV; campos aplicáveis sem informação podem retornar `null` ou texto vazio.

<table id="bkmrk-condi%C3%A7%C3%A3o-campos-reto"><thead><tr><th>Condição</th><th>Campos retornados</th></tr></thead><tbody><tr><td>Todas as estruturas</td><td>`nomeLinha`, `nomeColuna`, `numeroPedido`, `nomeCliente`, `cpfCnpj`, `tipoPessoa`, `cidade`, `estado`, `nomeUsuario`, `usuarioTags`, `nomeUsuarioAdm`, `nomeEquipe`, `nomeEtapa`, `categoriaAtividade`, `subCategoriaAtividade`, `dataCadastro`, `dataHoraAtualizacao`, `solicitacao`, `nomeEtapaItem`, `nomeProduto`, `valor`, `quantidade`, `valorDesconto`, `dataReferencia`, `formularios`, `tagsAtividade`</td></tr><tr><td>Estruturas de telefonia</td><td>`numeroVinculado`, `loginOperadora`, `ddd`, `nomeConsultorOperadora`, `possuiAudio`, `tipoNegociacao`, `notasFiscais`, `revisao`, `atividades`, `item`, `numeroTelefoneItem`, `dataPortabilidade`, `operadoraCedente`, `nomeCedente`, `cpfCnpjCedente`, `telefoneCedente`, `emailCedente`, `nomeOrigem`, `dataInstalacao`, `periodo`, `cepInstalacao`, `logradouroInstalacao`, `numeroInstalacao`, `bairroInstalacao`, `complInstalacao`, `cidadeInstalacao`, `estadoInstalacao`</td></tr><tr><td>Vivo</td><td>`cotacao`, `numeroPedidoOrigem`, `codigoPortabilidade`, `numeroProvisorio`, `rpon`, `instancia`</td></tr><tr><td>Claro</td><td>`percentualDesconto`, `variacaoRenovacao`, `faixaRenovacao`, `valorBaseAtual`, `valorAgregado`, `percentualTroca`, `clusterOrigem`, `aparelhoCartaoCredito`, `claroConvergenciaResposta`, `claroTabelaRenovacao`</td></tr></tbody></table>

Os grupos são cumulativos: uma estrutura Vivo de telefonia recebe os campos comuns, os de telefonia e os de Vivo; uma estrutura Claro de telefonia recebe os comuns, os de telefonia e os de Claro. TIM e demais estruturas recebem os campos comuns e, quando classificadas como telefonia no Xeotech, os campos de telefonia. A classificação é definida pelo sistema.

Ordem das colunas: siga a lista abaixo, desconsiderando os campos que não se aplicarem. No JSON, leia os campos pelo nome; no CSV, utilize o cabeçalho do arquivo recebido.

```
nomeLinha;nomeColuna;numeroPedido;numeroVinculado;cotacao;numeroPedidoOrigem;codigoPortabilidade;loginOperadora;nomeCliente;cpfCnpj;tipoPessoa;cidade;estado;ddd;nomeUsuario;usuarioTags;nomeUsuarioAdm;nomeConsultorOperadora;nomeEquipe;nomeEtapa;categoriaAtividade;subCategoriaAtividade;dataCadastro;dataHoraAtualizacao;solicitacao;possuiAudio;tipoNegociacao;notasFiscais;revisao;atividades;item;numeroTelefoneItem;numeroProvisorio;nomeEtapaItem;dataPortabilidade;operadoraCedente;nomeCedente;cpfCnpjCedente;telefoneCedente;emailCedente;nomeProduto;valor;quantidade;valorDesconto;dataReferencia;nomeOrigem;dataInstalacao;periodo;cepInstalacao;logradouroInstalacao;numeroInstalacao;bairroInstalacao;complInstalacao;cidadeInstalacao;estadoInstalacao;rpon;instancia;percentualDesconto;variacaoRenovacao;faixaRenovacao;valorBaseAtual;valorAgregado;percentualTroca;clusterOrigem;aparelhoCartaoCredito;claroConvergenciaResposta;claroTabelaRenovacao;formularios;tagsAtividade
```

### Campos calculados e formatos especiais da exportação

<table id="bkmrk-campo-regra-numerovi"><thead><tr><th>Campo</th><th>Regra</th></tr></thead><tbody><tr><td>`numeroVinculado`</td><td>Primeiro valor preenchido entre número do pedido vinculado, cotação e número da simulação. Retorna texto vazio quando nenhum estiver preenchido.</td></tr><tr><td>`tipoPessoa`</td><td>`PJ` quando CPF/CNPJ tiver 14 caracteres; `PF` nos demais casos preenchidos. Retorna `null` quando CPF/CNPJ for nulo.</td></tr><tr><td>`ddd`</td><td>DDD informado; quando ausente ou igual a zero, tenta localizar pelo estado e cidade. Sem resultado, retorna texto vazio.</td></tr><tr><td>`quantidade`</td><td>Quantidade considerada na produção. Retorna zero quando o item não deve somar quantidade.</td></tr><tr><td>`solicitacao`</td><td>Nome da solicitação do item, em vez do ID.</td></tr><tr><td>`possuiAudio`</td><td>Texto `SIM` ou `NAO`, sem acento. Não é um booleano.</td></tr><tr><td>`valor / valorDesconto`</td><td>Valores numéricos. Na ausência de valor, retornam zero.</td></tr><tr><td>`variacaoRenovacao / faixaRenovacao`</td><td>Cálculo e faixa de renovação conforme as regras da estrutura Claro. Variação sem resultado retorna zero; a faixa é obtida pelo cálculo do Xeotech.</td></tr><tr><td>`percentualDesconto / valorBaseAtual / valorAgregado / percentualTroca`</td><td>Valores numéricos específicos da Claro; quando nulos na origem, retornam zero.</td></tr><tr><td>`aparelhoCartaoCredito`</td><td>Texto `SIM`, `NÃO` ou texto vazio quando não informado. Específico da Claro.</td></tr><tr><td>`claroConvergenciaResposta / claroTabelaRenovacao`</td><td>Valores registrados na estrutura Claro, ou texto vazio quando não informados.</td></tr><tr><td>`usuarioTags`</td><td>Tags do usuário, em texto.</td></tr><tr><td>`formularios`</td><td>Objeto cujas chaves são os nomes dos campos dos formulários e cujos valores são as respostas. Sem respostas: `{}`.</td></tr><tr><td>`tagsAtividade`</td><td>Lista de textos obtida das tags da atividade. Sem tags: `[]`.</td></tr></tbody></table>

A exportação utiliza `numeroVinculado`, `ddd`, `quantidade` e `solicitacao`. Não retorna os nomes antigos `numeroVinculadoExibicao`, `dddExibicao`, `quantidadeProducao` e `solicitacaoExibicao`.

### Exemplo completo de uma linha de exportação

Exemplo para uma estrutura sem campos de telefonia, Vivo ou Claro. Os campos condicionais são acrescentados nas estruturas correspondentes.

```
{
  "meta": {
    "versao": "v1",
    "painelId": 123,
    "operacao": "exportacao",
    "fusoHorario": "America/Sao_Paulo",
    "recebidoEm": "2026-09-30T10:00:00",
    "dataInicio": "2026-09-01",
    "dataFim": "2026-09-30"
  },
  "dados": [
    {
      "nomeLinha": "Serviços",
      "nomeColuna": "Vendas",
      "numeroPedido": "PED-1001",
      "nomeCliente": "Empresa Exemplo",
      "cpfCnpj": null,
      "tipoPessoa": null,
      "cidade": "São Paulo",
      "estado": "SP",
      "nomeUsuario": "Usuário Exemplo",
      "usuarioTags": "#COMERCIAL",
      "nomeUsuarioAdm": null,
      "nomeEquipe": "Equipe Comercial",
      "nomeEtapa": "Concluído",
      "categoriaAtividade": "Venda",
      "subCategoriaAtividade": null,
      "dataCadastro": "2026-09-10",
      "dataHoraAtualizacao": "2026-09-30T09:30:00",
      "solicitacao": null,
      "nomeEtapaItem": "Concluído",
      "nomeProduto": "Serviço Exemplo",
      "valor": 149.9,
      "quantidade": 1,
      "valorDesconto": 0.0,
      "dataReferencia": "2026-09-30",
      "formularios": {
        "Observação": "Instalação agendada",
        "Data combinada": "2026-10-01",
        "Aceite": "SIM",
        "Valor informado": "150,50"
      },
      "tagsAtividade": [
        "VENDA",
        "PRIORIDADE"
      ]
    }
  ],
  "totalRegistros": 1
}
```

### Formulários e tags

Na API, as respostas de formulário ficam dentro de `formularios`. Texto permanece texto; datas usam formato ISO; respostas decimais são textos com vírgula, como `"150,50"`; respostas booleanas são textos `"SIM"` ou `"NÃO"`. Os nomes dos campos dependem dos formulários do pedido.

`tagsAtividade` é uma lista separada das tags do usuário (`usuarioTags`). No CSV, tanto o objeto `formularios` quanto a lista `tagsAtividade` são serializados como JSON dentro de uma única célula cada. Eles não viram várias colunas, como no Excel do painel.

### Retorno CSV

O CSV contém o cabeçalho e as linhas, sem o envelope `meta`/`dados`/`totalRegistros`. A carga possui cabeçalho fixo; o relatório possui cabeçalho conforme a estrutura.

Exemplo correspondente à linha JSON acima:

```
nomeLinha;nomeColuna;numeroPedido;nomeCliente;cpfCnpj;tipoPessoa;cidade;estado;nomeUsuario;usuarioTags;nomeUsuarioAdm;nomeEquipe;nomeEtapa;categoriaAtividade;subCategoriaAtividade;dataCadastro;dataHoraAtualizacao;solicitacao;nomeEtapaItem;nomeProduto;valor;quantidade;valorDesconto;dataReferencia;formularios;tagsAtividade
"Serviços";"Vendas";"PED-1001";"Empresa Exemplo";;;"São Paulo";"SP";"Usuário Exemplo";"#COMERCIAL";;"Equipe Comercial";"Concluído";"Venda";;"2026-09-10";"2026-09-30T09:30:00";;"Concluído";"Serviço Exemplo";"149.9";"1";"0.0";"2026-09-30";"{""Observação"":""Instalação agendada"",""Data combinada"":""2026-10-01"",""Aceite"":""SIM"",""Valor informado"":""150,50""}";"[""VENDA"",""PRIORIDADE""]"

```

Use um leitor CSV com separador `;`, codificação UTF-8 e suporte a aspas escapadas. Depois de ler a célula de formulário ou tags, interprete seu conteúdo como JSON. Valores nulos viram células vazias. Textos que possam ser interpretados como fórmulas recebem um apóstrofo inicial de proteção.

---

## Limites de proteção

Os limites abaixo somam as chamadas de **carga** e **exportação**.

<table id="bkmrk-regra-limite-padr%C3%A3o-"><thead><tr class="header"><th>Regra</th><th style="text-align: right;">Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Exportações simultâneas globais</td><td style="text-align: right;">2</td></tr><tr class="even"><td>Exportações simultâneas por estrutura</td><td style="text-align: right;">1</td></tr><tr class="odd"><td>Intervalo mínimo após uma execução</td><td style="text-align: right;">120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td style="text-align: right;">3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td style="text-align: right;">20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td style="text-align: right;">600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td style="text-align: right;">8</td></tr><tr class="even"><td>Registros por resposta</td><td style="text-align: right;">1.000.000</td></tr><tr class="odd"><td>Tamanho máximo do arquivo</td><td style="text-align: right;">1 GiB</td></tr><tr class="even"><td>Tamanho máximo do payload</td><td style="text-align: right;">16 KiB</td></tr><tr class="odd"><td>Tempo máximo solicitado para a consulta</td><td style="text-align: right;">600 segundos</td></tr><tr class="even"><td>Tempo máximo de geração da resposta</td><td style="text-align: right;">900 segundos</td></tr></tbody></table>

As tentativas recusadas também entram no controle de tentativas. Quando um limite temporário for atingido, a resposta será `429` e terá o header `Retry-After` com a quantidade aproximada de segundos para nova tentativa.

Os limites são aplicados por estrutura, mesmo que o cliente altere o período, o painel ou o formato entre chamadas. Enquanto uma exportação estiver em andamento, uma segunda chamada para a mesma estrutura será recusada.

## Respostas de erro

<table id="bkmrk-http-c%C3%B3digo-comum-si"><thead><tr class="header"><th style="text-align: right;">HTTP</th><th>Código comum</th><th>Situação</th></tr></thead><tbody><tr class="odd"><td style="text-align: right;">`400`</td><td>`PAYLOAD_INVALIDO`</td><td>Campo ausente, data inválida ou período incorreto.</td></tr><tr class="even"><td style="text-align: right;">`401`</td><td>`TOKEN_INVALIDO`</td><td>Token inválido.</td></tr><tr class="odd"><td style="text-align: right;">`403`</td><td>`ACESSO_NEGADO`</td><td>Sem acesso ao painel ou às permissões necessárias.</td></tr><tr class="even"><td style="text-align: right;">`413`</td><td>`PAYLOAD_GRANDE`</td><td>Payload maior que 16 KiB.</td></tr><tr class="odd"><td style="text-align: right;">`422`</td><td>`LIMITE_REGISTROS` ou `LIMITE_ARQUIVO`</td><td>Resultado acima dos limites permitidos.</td></tr><tr class="even"><td style="text-align: right;">`429`</td><td>`LIMITE_API`</td><td>Guard ocupado, cooldown ou excesso de tentativas.</td></tr><tr class="odd"><td style="text-align: right;">`504`</td><td>`TEMPO_EXCEDIDO`</td><td>Consulta ou geração excedeu o tempo permitido.</td></tr></tbody></table>

Exemplo de erro:

```
{
  "codigo": "LIMITE_API",
  "mensagem": "Aguarde entre exportações da API.",
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000"
}
```

Guarde o `requestId` ao registrar uma falha. Ele ajuda o suporte a localizar a execução nos logs.

## Boas práticas de integração

- Use JSON quando precisar preservar tipos, datas, nulos e valores numéricos.
- Use CSV quando a carga for consumida por ferramentas de análise ou planilhas.
- Salve o arquivo em uma área temporária e só confirme a carga depois de validar o HTTP 200, o `Content-Length` e o `X-Total-Registros`.
- Na carga, faça `upsert` usando o ID estável da linha. A exportação é um relatório sem esse ID.
- Na carga, mantenha o último intervalo confirmado e use pequenas sobreposições entre chamadas.
- Faça uma reconciliação completa periódica para tratar exclusões e mudanças que não atualizaram o pedido.
- Respeite o `Retry-After` e não repita imediatamente uma resposta `429`.
- Nunca registre o token completo em logs.

# Pedidos (Atividades)

# Api de Movimentação de Pedidos

A API de Movimentação de Pedidos permite consultar o histórico de movimentações dos pedidos de uma estrutura autorizada.

Use a API para:

- buscar movimentações de pedidos em um período;
- filtrar por tipo de pedido: `COMERCIAL` ou `POS_VENDA`;
- consultar todos os pedidos da estrutura ou somente uma lista de pedidos;
- receber os dados em JSON ou CSV.

## Endereço

```
POST https://api.xeotech.com.br/api/v1/pedidos/movimentacao/{token}
```

O token é informado na URL. Não envie o token dentro do payload.

Para localizar seu token no Xeotech, acesse a página [Meu token](https://ajuda.xeotech.com.br/books/apis-de-integracao/page/meu-token-para-proprietarios).

## Autorização

O token precisa pertencer a um usuário ativo. O usuário também precisa possuir um vínculo ativo com uma estrutura ativa.

A estrutura usada na consulta é obtida pelo vínculo do usuário autenticado. O cliente não informa `estruturaId` no payload.

A consulta sempre aplica a estrutura do usuário:

```
eu.estrutura_id = estruturaIdDoUsuario
```

Mesmo que sejam enviados IDs de pedidos de outra estrutura, eles não serão retornados.

## Payload

```
{
  "dataHoraInicio": "2026-09-30 09:00:00",
  "dataHoraFim": "2026-09-30 10:00:00",
  "pedidoTipo": "COMERCIAL",
  "pedidoIds": [1001, 1002],
  "formato": "json"
}
```

<table id="bkmrk-campos-payload-movimentacao"><thead><tr class="header"><th>Campo</th><th style="text-align: right;">Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`dataHoraInicio`</td><td style="text-align: right;">Sim</td><td>Início do período no formato `yyyy-MM-dd HH:mm:ss`.</td></tr><tr class="even"><td>`dataHoraFim`</td><td style="text-align: right;">Sim</td><td>Fim do período no formato `yyyy-MM-dd HH:mm:ss`. Deve ser posterior ao início.</td></tr><tr class="odd"><td>`pedidoTipo`</td><td style="text-align: right;">Sim</td><td>Aceita `COMERCIAL` ou `POS_VENDA`.</td></tr><tr class="even"><td>`pedidoIds`</td><td style="text-align: right;">Não</td><td>Lista de IDs de pedidos. Quando omitida ou vazia, consulta todos os pedidos da estrutura. Limite de 10.000 IDs.</td></tr><tr class="odd"><td>`formato`</td><td style="text-align: right;">Não</td><td>Aceita `json` ou `csv`. O padrão é `json`.</td></tr></tbody></table>

### Regras dos filtros

<table id="bkmrk-combinacoes-filtros-pedidos"><thead><tr class="header"><th>Payload</th><th>Resultado</th></tr></thead><tbody><tr class="odd"><td>Período + `pedidoTipo`</td><td>Todas as movimentações do período para o tipo informado, dentro da estrutura do usuário.</td></tr><tr class="even"><td>Período + `pedidoTipo` + `pedidoIds`</td><td>Somente as movimentações do período dos pedidos informados e pertencentes à estrutura do usuário.</td></tr></tbody></table>

O início do período é inclusivo e o fim é exclusivo:

```
pedido.data_hora_atualizacao >= dataHoraInicio
pedido.data_hora_atualizacao < dataHoraFim
```

As datas usam o fuso `America/Sao_Paulo`.

## Exemplos cURL

### JSON — todos os pedidos do período

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/pedidos/movimentacao/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output movimentacoes-pedidos.json \
  --data '{
    "dataHoraInicio": "2026-09-30 09:00:00",
    "dataHoraFim": "2026-09-30 10:00:00",
    "pedidoTipo": "COMERCIAL",
    "formato": "json"
  }'
```

### JSON — somente pedidos selecionados

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/pedidos/movimentacao/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output movimentacoes-pedidos.json \
  --data '{
    "dataHoraInicio": "2026-09-30 09:00:00",
    "dataHoraFim": "2026-09-30 10:00:00",
    "pedidoTipo": "POS_VENDA",
    "pedidoIds": [1001, 1002, 1003],
    "formato": "json"
  }'
```

### CSV

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/pedidos/movimentacao/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --output movimentacoes-pedidos.csv \
  --data '{
    "dataHoraInicio": "2026-09-30 09:00:00",
    "dataHoraFim": "2026-09-30 10:00:00",
    "pedidoTipo": "COMERCIAL",
    "pedidoIds": [1001, 1002],
    "formato": "csv"
  }'
```

## Retorno JSON

```
{
  "meta": {
    "versao": "v1",
    "operacao": "movimentacao",
    "fusoHorario": "America/Sao_Paulo",
    "recebidoEm": "2026-09-30T10:00:00",
    "dataHoraInicio": "2026-09-30T09:00:00",
    "dataHoraFim": "2026-09-30T10:00:00",
    "pedidoTipo": "COMERCIAL",
    "pedidoIdsInformados": [1001, 1002]
  },
  "dados": [
    {
      "id": "123456789",
      "pedidoId": 1001,
      "euEntrouId": 20,
      "euSaiuId": 21,
      "etapaId": 8,
      "cpfCnpjCliente": "12345678000199",
      "nomeCliente": "Empresa Exemplo Ltda.",
      "numeroAtividade": "PED-1001",
      "nomeEtapa": "Em análise",
      "usuarioEntrou": "Usuário Entrada",
      "usuarioSaiu": "Usuário Saída",
      "dataHoraEntrou": "2026-09-30T09:10:00",
      "dataHoraSaiu": "2026-09-30T09:45:00",
      "tempo": "00:35:00",
      "slaHoras": 24,
      "tagsAtividade": "#PRIORIDADE,#CLIENTE",
      "movimentacao": "Avanço de etapa",
      "nomeConsultor": "Consultor Exemplo",
      "total": 149.90,
      "compromissoMensal": 99.90,
      "pedidoTipo": "COMERCIAL",
      "controlaBko": true
    }
  ],
  "totalRegistros": 1
}
```

O objeto `dados` utiliza os 22 campos do `PedidoStatusDTO`. Campos sem valor podem retornar `null`.

<table id="bkmrk-campos-retorno-movimentacao"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`id`</td><td>Identificador gerado para a linha retornada.</td></tr><tr class="even"><td>`pedidoId`</td><td>ID do pedido.</td></tr><tr class="odd"><td>`euEntrouId` / `euSaiuId`</td><td>IDs dos vínculos de estrutura dos usuários que entraram e saíram.</td></tr><tr class="even"><td>`etapaId` / `nomeEtapa`</td><td>Etapa relacionada à movimentação.</td></tr><tr class="odd"><td>`cpfCnpjCliente` / `nomeCliente`</td><td>Identificação do cliente.</td></tr><tr class="even"><td>`numeroAtividade`</td><td>Número da atividade/pedido.</td></tr><tr class="odd"><td>`usuarioEntrou` / `usuarioSaiu`</td><td>Usuários associados à entrada e à saída.</td></tr><tr class="even"><td>`dataHoraEntrou` / `dataHoraSaiu`</td><td>Datas e horas da movimentação.</td></tr><tr class="odd"><td>`tempo` / `slaHoras`</td><td>Tempo calculado e SLA da etapa.</td></tr><tr class="even"><td>`tagsAtividade` / `movimentacao`</td><td>Tags e descrição da movimentação.</td></tr><tr class="odd"><td>`nomeConsultor`</td><td>Consultor associado ao pedido.</td></tr><tr class="even"><td>`total` / `compromissoMensal`</td><td>Valores financeiros do pedido.</td></tr><tr class="odd"><td>`pedidoTipo` / `controlaBko`</td><td>Tipo de pedido e indicador de controle BKO.</td></tr></tbody></table>

O campo `id` retornado pela consulta não deve ser usado como chave permanente de `upsert`. Para uma cópia local, use uma chave composta com os campos de negócio necessários, como `pedidoId`, `etapaId`, `dataHoraEntrou`, `dataHoraSaiu` e `movimentacao`.

## Retorno CSV

O CSV usa UTF-8 com BOM, separador `;`, cabeçalho e quebra de linha CRLF.

```
id;pedidoId;euEntrouId;euSaiuId;etapaId;cpfCnpjCliente;nomeCliente;numeroAtividade;nomeEtapa;usuarioEntrou;usuarioSaiu;dataHoraEntrou;dataHoraSaiu;tempo;slaHoras;tagsAtividade;movimentacao;nomeConsultor;total;compromissoMensal;pedidoTipo;controlaBko
```

Datas e horas seguem o formato ISO no JSON e são gravadas como texto no CSV. Valores nulos geram células vazias.

## Limites e guard

A API de movimentação utiliza os mesmos limites da API de produção, com guard próprio para os pedidos:

<table id="bkmrk-limites-movimentacao-pedidos"><thead><tr class="header"><th>Regra</th><th style="text-align: right;">Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Execuções simultâneas globais</td><td style="text-align: right;">2</td></tr><tr class="even"><td>Execuções simultâneas por estrutura</td><td style="text-align: right;">1</td></tr><tr class="odd"><td>Intervalo mínimo após uma execução</td><td style="text-align: right;">120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td style="text-align: right;">3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td style="text-align: right;">20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td style="text-align: right;">600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td style="text-align: right;">8</td></tr><tr class="even"><td>Registros por resposta</td><td style="text-align: right;">1.000.000</td></tr><tr class="odd"><td>Tamanho máximo do payload</td><td style="text-align: right;">16 KiB</td></tr><tr class="even"><td>IDs no campo `pedidoIds`</td><td style="text-align: right;">10.000</td></tr></tbody></table>

As tentativas recusadas também entram no controle. Quando um limite for atingido, a resposta será `429` com o header `Retry-After`.

## Respostas de erro

<table id="bkmrk-erros-movimentacao-pedidos"><thead><tr class="header"><th style="text-align: right;">HTTP</th><th>Código</th><th>Situação</th></tr></thead><tbody><tr class="odd"><td style="text-align: right;">`400`</td><td>`PAYLOAD_INVALIDO`</td><td>Campo ausente, data inválida, lista inválida ou tipo de pedido incorreto.</td></tr><tr class="even"><td style="text-align: right;">`401`</td><td>`TOKEN_INVALIDO`</td><td>Token inexistente ou inválido.</td></tr><tr class="odd"><td style="text-align: right;">`403`</td><td>`ACESSO_NEGADO`</td><td>Usuário ou estrutura inativos.</td></tr><tr class="even"><td style="text-align: right;">`413`</td><td>`PAYLOAD_GRANDE`</td><td>Payload acima de 16 KiB.</td></tr><tr class="odd"><td style="text-align: right;">`422`</td><td>`LIMITE_REGISTROS`</td><td>Resultado acima de 1.000.000 de movimentações.</td></tr><tr class="even"><td style="text-align: right;">`429`</td><td>`LIMITE_API`</td><td>Guard ocupado, cooldown ou excesso de tentativas.</td></tr></tbody></table>

Exemplo:

```
{
  "codigo": "LIMITE_API",
  "mensagem": "Aguarde entre exportações da API.",
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000"
}
```

## Boas práticas

- Use intervalos consecutivos sem sobreposição quando a consulta for controlada pelo período.
- Use JSON quando a integração precisar preservar tipos e datas.
- Use CSV para planilhas e ferramentas de análise.
- Respeite o header `Retry-After` em respostas `429`.
- Não registre o token completo em logs.
- Não use o campo `id` da resposta como identificador permanente.

# Api Consulta Pedido

A API de Consulta de Pedido permite buscar os dados completos de um pedido pertencente à estrutura autorizada pelo token.

Use esta API para consultar:

- dados comerciais e financeiros do pedido;
- cliente associado, sem credenciais sensíveis;
- etapa atual, origem e consultor;
- itens do pedido e dados públicos do produto.

## Endereço

```
GET https://api.xeotech.com.br/api/v1/pedidos/{pedidoId}/{token}
```

O `pedidoId` é o identificador interno do pedido. O token é informado na URL e não deve ser enviado em cabeçalho ou payload.

Para localizar seu token no Xeotech, acesse a página [Meu token](https://ajuda.xeotech.com.br/books/apis-de-integracao/page/meu-token-para-proprietarios).

## Autorização e segurança

O token precisa pertencer a um usuário ativo. O usuário também precisa possuir um vínculo ativo com uma estrutura ativa.

A API obtém a estrutura diretamente do usuário autenticado. O cliente não envia `estruturaId`.

```
pedido.id = pedidoId
AND estrutura_usuario.estrutura_id = estruturaIdDoUsuario
```

Se o pedido não existir ou pertencer a outra estrutura, a API retorna `404`. Essa resposta evita revelar a existência de pedidos de outras estruturas.

## Payload

O GET não possui payload. Todos os dados necessários estão na URL:

<table id="bkmrk-parametros-consulta-pedido"><thead><tr class="header"><th>Parâmetro</th><th>Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`pedidoId`</td><td>Sim</td><td>ID interno numérico do pedido.</td></tr><tr class="even"><td>`token`</td><td>Sim</td><td>Novo token de integração do usuário, informado na URL.</td></tr></tbody></table>

## Exemplo cURL

```
curl --fail-with-body --location \
  --request GET \
  'https://api.xeotech.com.br/api/v1/pedidos/123456/SEU_TOKEN' \
  --header 'Accept: application/json' \
  --output pedido-123456.json
```

## Retorno JSON

O retorno utiliza o formato `PedidoApiDTO`. A entidade JPA não é serializada diretamente.

```
{
  "id": 123456,
  "numero": "49565585",
  "pedidoTipo": "COMERCIAL",
  "tipoNegociacao": "NOVO",
  "dataCadastro": "2026-09-30",
  "dataHoraAtualizacao": "2026-09-30T14:32:10",
  "dataHoraUltimaMov": "2026-09-30T14:31:55",
  "total": 149.90,
  "compromissoMensal": 99.90,
  "nomeConsultorOperadora": "Consultor Exemplo",
  "numeroPedidoOrigem": null,
  "numeroPedidoVinculado": null,
  "numeroSimulacao": "SIM-10001",
  "complementos": null,
  "notasFiscais": null,
  "loginOperadora": null,
  "percentualTroca": null,
  "tags": "#PRIORIDADE",
  "clusterOrigem": null,
  "cotacao": null,
  "codigoPortabilidade": null,
  "observacaoProposta": null,
  "dataRetornoFuturo": null,
  "percentualDesconto": null,
  "observacao": null,
  "aparelhoCartaoCredito": false,
  "cliente": {
    "id": 9876,
    "cpfCnpj": "12345678000199",
    "nome": "Empresa Exemplo Ltda.",
    "cep": "89800000",
    "logradouro": "Rua Principal",
    "numero": "100",
    "complemento": null,
    "bairro": "Centro",
    "cidade": "Balneário Camboriú",
    "estado": "SC",
    "tags": null
  },
  "etapa": {
    "id": 44501,
    "nome": "ENVIADO BKO",
    "ativo": true,
    "sincronizavel": true,
    "editavel": false,
    "pedidoTipo": "COMERCIAL",
    "slaHoras": 0
  },
  "usuarioProprietario": {
    "id": 321,
    "nome": "Consultor Exemplo",
    "login": "consultor",
    "tags": "#PRIORIDADE,#VIP",
    "equipe": {
      "id": 12,
      "nome": "Equipe Comercial"
    },
    "ativo": true
  },
  "itens": [
    {  
      "id": 629534248,
      "numero": "47991370111",
      "quantidade": 1,
      "valorUnitario": 99.99,
      "dataReferencia": "2026-09-30",
      "dataPortabilidade": "2026-09-30",
      "dataInstalacao": "2026-09-30",
      "cepInstalacao": "88330484",
      "logradouroInstalacao": "R 1822",
      "numeroInstalacao": "400",
      "bairroInstalacao": "Centro",
      "complInstalacao": "sl 1901",
      "cidadeInstalacao": "Balneario Camboriu",
      "estadoInstalacao": "SC",
      "operadoraCedente": "TIM",
      "nomeCedente": "Sebastião Barbosa",
      "cpfCnpjCedente": "45935282917",
      "telefoneCedente": "47991917979",
      "emailCedente": "xeotechoficial@gmail.com",
      "produto": {
        "id": 18272,
        "nome": "iPHONE 18",
        "descricao": "iPHONE 18",
        "valor": 12319.00,
        "categoria": "APARELHO"
      }
    }      
  ]
}
```

## Campos do pedido

<table id="bkmrk-campos-pedido-consulta-tabela"><thead><tr class="header"><th>Grupo</th><th>Campos</th></tr></thead><tbody><tr class="odd"><td>Identificação</td><td>`id`, `numero`, `pedidoTipo`, `tipoNegociacao`, `numeroPedidoOrigem`, `numeroPedidoVinculado`, `numeroSimulacao`</td></tr><tr class="even"><td>Datas</td><td>`dataCadastro`, `dataHoraAtualizacao`, `dataHoraOperadora`, `dataHoraUltimaMov`, `dataRetornoFuturo`</td></tr><tr class="odd"><td>Valores</td><td>`total`, `compromissoMensal`, `valorFaturaOrigem`, `percentualTroca`, `percentualDesconto`</td></tr><tr class="even"><td>Operação</td><td>`nomeConsultorOperadora`, `loginOperadora`, `atividades`, `clusterOrigem`, `cotacao`, `codigoPortabilidade`, `leadSistema`</td></tr><tr class="odd"><td>Observações</td><td>`complementos`, `notasFiscais`, `observacao`, `observacaoProposta`, `tags`, `aparelhoCartaoCredito`, `revisao`</td></tr></tbody></table>

## Cliente, etapa e consultor

O objeto `cliente` retorna identificação e endereço comercial. Campos de senha, login de conta online e demais credenciais não fazem parte do retorno.

O objeto `etapa` informa somente `id`, `nome`, `ativo`, `sincronizavel`, `editavel`, `pedidoTipo` e `slaHoras`. O objeto `origem` informa a origem do pedido. O objeto `usuarioProprietario` informa o usuário proprietário, suas tags, equipe e o indicador `ativo` do vínculo com a estrutura.

## Itens e produtos

O campo `itens` retorna uma lista dos itens associados ao pedido. Os campos podem variar conforme o tipo de item, mas somente campos públicos e controlados são exportados, como:

- `id`, `numero`, `descricao`, `quantidade`;
- `valor`, `valorUnitario`, `codigo`, `nome`;
- `modelo`, `plano`, `tipo`;
- `dataReferencia`, `dataInstalacao` e dados do endereço de instalação;
- `dataPortabilidade`, `operadoraCedente`, `nomeCedente`, `cpfCnpjCedente`, `telefoneCedente` e `emailCedente`;
- objeto `produto` com `id`, `codigo`, `nome`, `descricao`, `modelo`, `tipo`, `valor`, `somaCompromissoMensal` e `categoria`.

## Limites e guard

O GET utiliza o mesmo guard da API de pedidos. Embora a consulta retorne somente um pedido, a autenticação e o controle de concorrência continuam protegidos.

<table id="bkmrk-limites-consulta-pedido"><thead><tr class="header"><th>Regra</th><th style="text-align: right;">Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Execuções simultâneas globais</td><td style="text-align: right;">2</td></tr><tr class="even"><td>Execuções simultâneas por estrutura</td><td style="text-align: right;">1</td></tr><tr class="odd"><td>Intervalo mínimo após uma execução</td><td style="text-align: right;">120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td style="text-align: right;">3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td style="text-align: right;">20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td style="text-align: right;">600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td style="text-align: right;">8</td></tr></tbody></table>

As tentativas recusadas também entram no controle. Quando um limite for atingido, a resposta será `429` com o header `Retry-After`.

## Respostas de erro

<table id="bkmrk-erros-consulta-pedido"><thead><tr class="header"><th style="text-align: right;">HTTP</th><th>Código</th><th>Situação</th></tr></thead><tbody><tr class="odd"><td style="text-align: right;">`401`</td><td>`TOKEN_INVALIDO`</td><td>Token inexistente, vazio ou inválido.</td></tr><tr class="even"><td style="text-align: right;">`403`</td><td>`ACESSO_NEGADO`</td><td>Usuário ou estrutura inativos.</td></tr><tr class="odd"><td style="text-align: right;">`404`</td><td>`PEDIDO_NAO_ENCONTRADO`</td><td>Pedido inexistente ou que não pertence à estrutura do token.</td></tr><tr class="even"><td style="text-align: right;">`429`</td><td>`LIMITE_API`</td><td>Guard ocupado, cooldown ou excesso de tentativas.</td></tr></tbody></table>

Exemplo de erro:

```
{
  "codigo": "PEDIDO_NAO_ENCONTRADO",
  "mensagem": "Pedido não encontrado para esta estrutura.",
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000"
}
```

## Boas práticas

- Não registre o token completo em logs, código ou repositórios.
- Trate `404` como pedido inexistente ou não autorizado para a estrutura.
- Use o `id` do pedido como identificador da consulta local.
- Respeite o header `Retry-After` nas respostas `429`.
- Considere que campos sem valor podem retornar `null`.

# Api Movimentação de Etapa de Atividade

A API de movimentação de etapa permite mover uma ou várias atividades para outra etapa do funil, respeitando as mesmas regras de segurança, permissões, hierarquia e histórico utilizadas no Xeotech.

Essa operação não altera diretamente o pedido sem controle. Ela executa o processo de movimentação, registra o histórico e valida as regras da atividade.

## Endereço

```
POST https://api.xeotech.com.br/api/v1/pedidos/alterar-etapa/{token}
```

O token é informado na URL. Não envie o token no payload.

## Autorização e estrutura

O token precisa pertencer a um usuário ativo, com vínculo ativo em uma estrutura ativa. A estrutura é obtida automaticamente pelo vínculo do usuário; não é possível informar `estruturaId` no payload.

A etapa de destino é localizada pelo Xeotech usando:

- estrutura do usuário do token;
- tipo do pedido informado;
- nome exato da etapa;
- origem padrão do pedido, atualmente `5`;
- etapa ativa.

## Payload

```
{
  "numerosAtividades": ["49565585", "49565586"],
  "pedidoTipo": "COMERCIAL",
  "nomeEtapa": "ATIVO"
}
```

<table id="bkmrk-campos-payload-alterar-etapa"><thead><tr class="header"><th>Campo</th><th style="text-align: right;">Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`numerosAtividades`</td><td style="text-align: right;">Sim</td><td>Lista com 1 a 50 números de atividades. Envie os números como texto, mesmo quando forem numéricos. Não pode haver repetição.</td></tr><tr class="even"><td>`pedidoTipo`</td><td style="text-align: right;">Sim</td><td>Aceita `COMERCIAL` ou `POS_VENDA`.</td></tr><tr class="odd"><td>`nomeEtapa`</td><td style="text-align: right;">Sim</td><td>Nome exato da etapa ativa cadastrada para o tipo de pedido e estrutura do token.</td></tr></tbody></table>

O payload aceita somente esses três campos. Campos desconhecidos, números vazios, duplicados ou acima de 50 atividades são rejeitados.

## Header obrigatório

```
Idempotency-Key: alteracao-etapa-20261001-0001
```

A chave deve conter de 16 a 64 caracteres usando letras, números, hífen ou sublinhado.

Use a mesma chave somente para repetir exatamente a mesma operação. A chave é controlada por usuário, atividade e payload. Não reutilize uma chave para outra etapa ou outro pedido.

## Regras de processamento

- Cada atividade é processada em uma transação independente.
- Uma falha em uma atividade não impede o processamento das demais.
- A atividade precisa pertencer à estrutura do token e ser acessível pela hierarquia do usuário.
- Se a etapa atual não estiver no Kanban do solicitante, é necessária a permissão `MOVER_SEM_ESTAR_NO_KANBAN`.
- Se a etapa de destino não estiver no Kanban do solicitante, é necessária a permissão `MOVER_ATIVIDADE_FORA_KANBAN`.
- Para sair de uma etapa não editável, é sempre necessária a permissão `ATIVIDADE_MOVER_NAO_EDITAVEIS`, mesmo que a etapa esteja no Kanban.
- Para entrar em uma etapa não editável fora do Kanban, também é necessária a permissão `MOVER_ATIVIDADE_PARA_NAO_EDITAVEIS`. Quando o destino está no Kanban, essa permissão específica é dispensada.
- Se a atividade já estiver na etapa informada, o resultado será `SEM_ALTERACAO`.
- A movimentação registra o status e o histórico da atividade.
- Se a etapa de destino atualizar a data de referência, os itens do pedido terão a data atualizada conforme a regra do sistema.
- Se houver formulário ativo vinculado à etapa atual, a API recusa a operação. Nesse caso, a movimentação deve ser feita pela tela do Xeotech.
- Negociações vinculadas podem ser movimentadas quando atendem às regras de sincronização, hierarquia, permissões e formulário. As mesmas validações de Kanban são aplicadas usando o tipo da negociação vinculada; se ela for recusada, a alteração do pedido principal também é revertida.

## Permissões

<table id="bkmrk-permissoes-alterar-etapa-tabela"><thead><tr class="header"><th>Permissão</th><th>Quando é necessária</th></tr></thead><tbody><tr class="odd"><td>`PAINEL_ATIVIDADE_ETAPA_CHANGE`</td><td>Obrigatória em todas as chamadas, inclusive para uma única atividade. A permissão `KANBAN_ETAPA_CHANGE` sozinha não autoriza esta API.</td></tr><tr class="even"><td>`ATIVIDADE_ALTERACAO_EM_LOTE`</td><td>Obrigatória quando o payload contém mais de uma atividade.</td></tr><tr class="odd"><td>`ATIVIDADE_MOVER_NAO_EDITAVEIS`</td><td>Necessária para sair de uma etapa não editável.</td></tr><tr class="even"><td>`MOVER_ATIVIDADE_PARA_NAO_EDITAVEIS`</td><td>Necessária para entrar em uma etapa não editável que não esteja no Kanban do solicitante.</td></tr><tr class="even"><td>`MOVER_SEM_ESTAR_NO_KANBAN`</td><td>Necessária quando a etapa atual da atividade não está no Kanban do solicitante.</td></tr><tr class="odd"><td>`MOVER_ATIVIDADE_FORA_KANBAN`</td><td>Necessária quando a etapa de destino não está no Kanban do solicitante.</td></tr><tr class="odd"><td>`IGNORAR_HIERARQUIA`</td><td>Permite ignorar a validação de hierarquia, conforme as regras do usuário.</td></tr></tbody></table>

As permissões de Kanban e de etapas não editáveis são cumulativas. Por exemplo, mover uma atividade de uma etapa não editável fora do Kanban para outro destino não editável fora do Kanban exige as quatro permissões específicas, além das permissões gerais da operação.

## Exemplo cURL

```
curl --fail-with-body --location \
  --request POST \
  'https://api.xeotech.com.br/api/v1/pedidos/alterar-etapa/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Idempotency-Key: alteracao-etapa-20261001-0001' \
  --data '{
    "numerosAtividades": ["49565585", "49565586"],
    "pedidoTipo": "COMERCIAL",
    "nomeEtapa": "ATIVO"
  }'
```

## Retorno

A resposta informa o resultado individual de cada atividade. O HTTP `200` indica que o lote foi processado; verifique os campos `sucessos`, `falhas` e `resultados`.

```
{
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000",
  "total": 2,
  "sucessos": 1,
  "falhas": 1,
  "resultados": [
    {
      "numeroAtividade": "49565585",
      "pedidoId": 49565585,
      "sucesso": true,
      "codigo": "ETAPA_ALTERADA",
      "mensagem": "Etapa alterada com sucesso."
    },
    {
      "numeroAtividade": "49565586",
      "pedidoId": null,
      "sucesso": false,
      "codigo": "FORMULARIO_VINCULADO",
      "mensagem": "Esta atividade possui formulário vinculado à etapa atual. Realize a movimentação pela tela do sistema."
    }
  ]
}
```

<table id="bkmrk-campos-retorno-alterar-etapa"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`requestId`</td><td>Identificador da requisição para rastreamento no suporte.</td></tr><tr class="even"><td>`total`</td><td>Total de atividades recebidas.</td></tr><tr class="odd"><td>`sucessos`</td><td>Quantidade de atividades alteradas ou processadas sem erro.</td></tr><tr class="even"><td>`falhas`</td><td>Quantidade de atividades recusadas ou com erro.</td></tr><tr class="odd"><td>`numeroAtividade`</td><td>Número enviado no payload.</td></tr><tr class="even"><td>`pedidoId`</td><td>ID interno do pedido, quando localizado.</td></tr><tr class="odd"><td>`sucesso`</td><td>Indica se a atividade foi processada com sucesso.</td></tr><tr class="even"><td>`codigo`</td><td>Código estável do resultado, como `ETAPA_ALTERADA`, `SEM_ALTERACAO` ou `FORMULARIO_VINCULADO`.</td></tr><tr class="odd"><td>`mensagem`</td><td>Descrição do resultado.</td></tr></tbody></table>

## Limites e guard

A alteração de etapa reutiliza o `pedidoApiGuard` da API de pedidos. Os limites são aplicados antes da autenticação e durante o processamento.

<table id="bkmrk-limites-alterar-etapa"><thead><tr class="header"><th>Regra</th><th style="text-align: right;">Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Execuções simultâneas globais</td><td style="text-align: right;">2</td></tr><tr class="even"><td>Execuções simultâneas por estrutura</td><td style="text-align: right;">1</td></tr><tr class="odd"><td>Intervalo mínimo após execução</td><td style="text-align: right;">120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td style="text-align: right;">3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td style="text-align: right;">20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td style="text-align: right;">600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td style="text-align: right;">8</td></tr><tr class="even"><td>Tamanho máximo do payload</td><td style="text-align: right;">16 KiB</td></tr><tr class="odd"><td>Atividades por requisição</td><td style="text-align: right;">50</td></tr></tbody></table>

Quando um limite for atingido, a API retorna `429` e informa o tempo de espera no header `Retry-After`. O guard em memória é controlado por instância da aplicação; a idempotência é garantida pelo banco de dados.

## Principais erros

<table id="bkmrk-erros-alterar-etapa-tabela"><thead><tr class="header"><th style="text-align: right;">HTTP</th><th>Código</th><th>Situação</th></tr></thead><tbody><tr class="odd"><td style="text-align: right;">`400`</td><td>`PAYLOAD_INVALIDO` ou `CHAVE_INVALIDA`</td><td>Payload inválido ou ausência de uma chave de idempotência válida.</td></tr><tr class="even"><td style="text-align: right;">`401`</td><td>`TOKEN_INVALIDO`</td><td>Token inexistente ou inválido.</td></tr><tr class="odd"><td style="text-align: right;">`403`</td><td>`ACESSO_NEGADO` ou `SEM_PERMISSAO`</td><td>Usuário, vínculo, estrutura ou permissão indisponível.</td></tr><tr class="even"><td style="text-align: right;">`404`</td><td>`PEDIDO_NAO_ENCONTRADO`</td><td>Atividade não encontrada na estrutura e no tipo informados.</td></tr><tr class="odd"><td style="text-align: right;">`409`</td><td>`IDEMPOTENCIA_CONFLITO` ou `NUMERO_AMBIGUO`</td><td>Chave reutilizada com outro payload ou número não exclusivo.</td></tr><tr class="even"><td style="text-align: right;">`413`</td><td>`PAYLOAD_GRANDE`</td><td>Payload acima de 16 KiB.</td></tr><tr class="odd"><td style="text-align: right;">`422`</td><td>`ETAPA_INVALIDA` ou `FORMULARIO_VINCULADO`</td><td>Etapa inexistente, ambígua, inativa ou bloqueada por formulário.</td></tr><tr class="even"><td style="text-align: right;">`429`</td><td>`LIMITE_API`</td><td>Guard ocupado, cooldown ou excesso de tentativas.</td></tr></tbody></table>

Falhas específicas de uma atividade são retornadas dentro de `resultados`, com HTTP `200` para o lote. Isso inclui `ETAPA_ATUAL_FORA_KANBAN`, `ETAPA_DESTINO_FORA_KANBAN`, `SEM_PERMISSAO`, `FORMULARIO_VINCULADO` e demais recusas da atividade. Os números HTTP da tabela representam as categorias de erro; não substituem a análise de cada resultado.

## Boas práticas

- Envie números de atividade como texto para preservar compatibilidade com números antigos.
- Use uma chave de idempotência única para cada operação nova.
- Em caso de timeout, repita a requisição com a mesma chave e o mesmo payload.
- Analise o resultado de cada atividade, mesmo quando o HTTP for `200`.
- Respeite o header `Retry-After` nas respostas `429`.
- Não registre o token completo nos logs.

# Consulta Cliente

A API de Consulta de Clientes permite consultar uma lista de CNPJs e receber os dados básicos dos clientes, pessoas, responsáveis, contatos, vencimentos e o indicador de enriquecimento.

## Endereço

```
POST https://api.xeotech.com.br/api/v1/clientes/consulta/{token}
```

O token é informado na URL. Para localizar seu token, consulte a página [Meu token](https://ajuda.xeotech.com.br/books/apis-de-integracao/page/meu-token-para-proprietarios).

## Autorização e acesso

O token precisa possuir um vínculo ativo com uma estrutura ativa. A estrutura é obtida pelo usuário do token: não envie `estruturaId` no payload.

Usuários com perfil `PROPRIETARIO` ou permissão `CLIENTE_CARTEIRA_VER_TUDO` podem consultar os clientes da estrutura. Os demais precisam estar cadastrados como responsáveis diretos pelo cliente. A consulta aos dados extras segue essa regra; estar na hierarquia de um responsável não substitui o vínculo direto.

CNPJs inexistentes ou sem autorização aparecem na mesma lista `cnpjsNaoEncontradosOuNaoAutorizados`. A API não revela cadastros de outras estruturas.

## Payload

```
{
  "cnpjs": [
    "55275604000132",
    "12.345.678/0001-90"
  ]
}
```

<table id="bkmrk-campo-obrigat%C3%B3rio-de"><thead><tr class="header"><th>Campo</th><th>Obrigatório</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`cnpjs`</td><td>Sim</td><td>Lista de 1 a 50 CNPJs distintos, enviados como texto. Aceita 14 dígitos ou a máscara `00.000.000/0000-00`.</td></tr></tbody></table>

Somente o campo `cnpjs` é aceito. Não envie `formato`: o retorno é exclusivamente JSON. CNPJs repetidos são rejeitados, inclusive quando um é enviado com máscara e outro sem máscara.

A máscara é removida antes da consulta. O cadastro é localizado pelo CNPJ armazenado sem máscara. Os dígitos verificadores não são validados nessa consulta. Números JSON, CPFs, listas vazias e campos adicionais são rejeitados.

## Exemplo cURL

```
curl --fail-with-body --request POST \
  'https://api.xeotech.com.br/api/v1/clientes/consulta/SEU_TOKEN' \
  --header 'Content-Type: application/json' \
  --header 'Accept: application/json' \
  --output clientes.json \
  --data '{"cnpjs":["55275604000132","12.345.678/0001-90"]}'
```

## Retorno JSON

Exemplo ilustrativo. Os IDs, nomes e dados abaixo são fictícios; os campos correspondem ao contrato da API.

```
{
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000",
  "totalRegistros": 1,
  "dados": [
    {
      "id": 1001,
      "cpfCnpj": "55275604000132",
      "nome": "Empresa Exemplo Ltda.",
      "cep": "88330000",
      "logradouro": "Rua Exemplo",
      "numero": "100",
      "complemento": null,
      "bairro": "Centro",
      "cidade": "Balneário Camboriú",
      "estado": "SC",
      "inscricaoEstadual": null,
      "tags": "#CLIENTE",
      "observacao": null,
      "dataHoraAtualizacao": "2026-10-05T08:00:00",
      "classificacao": "Cliente",
      "enriquecido": true,
      "pessoas": [
        {
          "id": 101,
          "nome": "Pessoa Exemplo",
          "cpf": null,
          "rg": null,
          "email": "pessoa@example.com",
          "celular": "47999990000",
          "telefone2": null,
          "nascimento": null,
          "papel": "Contato comercial"
        }
      ],
      "responsaveis": [
        {
          "id": 201,
          "usuarioId": 301,
          "nome": "Consultor Exemplo",
          "login": "consultor@example.com",
          "estruturaUsuarioId": 401,
          "ativo": true,
          "equipeId": 501,
          "equipeNome": "Equipe Comercial"
        }
      ],
      "contatos": [
        {
          "id": 601,
          "tipo": null,
          "valor": "47999990000",
          "verificado": null
        }
      ],
      "vencimentos": [
        {
          "id": 701,
          "identificador": "NUMERO-CONTRATO",
          "dia": 10,
          "apartir": "2026-01-01",
          "ate": "2026-12-31"
        }
      ]
    }
  ],
  "cnpjsNaoEncontradosOuNaoAutorizados": [
    "12345678000190"
  ]
}
```

Campos sem valor podem retornar `null`. As listas sem registros retornam `[]`. Os valores de `tipo` e `verificado`, quando preenchidos, são os nomes dos indicadores cadastrados no Xeotech.

<table id="bkmrk-campo-da-resposta-de"><thead><tr class="header"><th>Campo da resposta</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`requestId`</td><td>Identificador da requisição para suporte; também enviado no header `X-Request-Id`.</td></tr><tr class="even"><td>`totalRegistros`</td><td>Quantidade de clientes disponíveis retornados.</td></tr><tr class="odd"><td>`dados`</td><td>Lista de clientes, na ordem dos CNPJs solicitados, omitindo os indisponíveis.</td></tr><tr class="even"><td>`cnpjsNaoEncontradosOuNaoAutorizados`</td><td>CNPJs normalizados que não foram localizados ou autorizados.</td></tr></tbody></table>

## Dados básicos do cliente

<table id="bkmrk-grupo-campos-e-descr"><thead><tr class="header"><th>Grupo</th><th>Campos e descrição</th></tr></thead><tbody><tr class="odd"><td>Identificação</td><td>`id`, `cpfCnpj` e `nome`.</td></tr><tr class="even"><td>Endereço</td><td>`cep`, `logradouro`, `numero`, `complemento`, `bairro`, `cidade` e `estado`.</td></tr><tr class="odd"><td>Cadastro</td><td>`inscricaoEstadual`, `tags`, `observacao`, `cadastroWhatsapp` e `dataHoraAtualizacao`.</td></tr><tr class="even"><td>Classificação</td><td>`classificacao`: nome da classificação, ou `null`.</td></tr><tr class="odd"><td>Enriquecimento</td><td>`enriquecido`: indicador booleano de enriquecimento existente na estrutura autorizada.</td></tr></tbody></table>

## Pessoas

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-id-i"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`id`</td><td>Identificador da pessoa.</td></tr><tr class="even"><td>`nome`</td><td>Nome cadastrado.</td></tr><tr class="odd"><td>`cpf / rg`</td><td>Documentos cadastrados, quando disponíveis.</td></tr><tr class="even"><td>`email / celular / telefone2`</td><td>Dados de contato.</td></tr><tr class="odd"><td>`nascimento`</td><td>Data de nascimento, no formato yyyy-MM-dd.</td></tr><tr class="even"><td>`papel`</td><td>Papel da pessoa no cliente.</td></tr></tbody></table>

## Responsáveis

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-id-i-1"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`id`</td><td>Identificador do registro de responsabilidade.</td></tr><tr class="even"><td>`funcao`</td><td>Função cadastrada.</td></tr><tr class="odd"><td>`usuarioId / nome / login`</td><td>Identificação do usuário responsável.</td></tr><tr class="even"><td>`estruturaUsuarioId`</td><td>Identificador do vínculo do usuário com a estrutura.</td></tr><tr class="odd"><td>`ativo`</td><td>Situação do vínculo com a estrutura.</td></tr><tr class="even"><td>`equipeId / equipeNome`</td><td>Equipe vinculada ao responsável, ou null.</td></tr></tbody></table>

## Contatos

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-id-i-2"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`id`</td><td>Identificador do contato.</td></tr><tr class="even"><td>`tipo`</td><td>Tipo do contato, conforme cadastro.</td></tr><tr class="odd"><td>`valor`</td><td>Telefone, e-mail ou outro valor cadastrado.</td></tr><tr class="even"><td>`verificado`</td><td>Indicador de verificação cadastrado.</td></tr><tr class="odd"><td>`nivelRelevancia`</td><td>Nível de relevância do contato.</td></tr><tr class="even"><td>`temWhats`</td><td>Indica WhatsApp cadastrado; pode retornar null.</td></tr><tr class="odd"><td>`dataWhats`</td><td>Data da informação de WhatsApp.</td></tr></tbody></table>

## Vencimentos

<table id="bkmrk-campo-descri%C3%A7%C3%A3o-id-i-3"><thead><tr class="header"><th>Campo</th><th>Descrição</th></tr></thead><tbody><tr class="odd"><td>`id`</td><td>Identificador do vencimento.</td></tr><tr class="even"><td>`nome`</td><td>Descrição cadastrada.</td></tr><tr class="odd"><td>`dia`</td><td>Dia informado para o vencimento.</td></tr><tr class="even"><td>`apartir`</td><td>Data inicial de vigência, no formato yyyy-MM-dd. O nome do campo é exatamente apartir.</td></tr><tr class="odd"><td>`ate`</td><td>Data final de vigência, ou null.</td></tr></tbody></table>

## Indicador enriquecido

`enriquecido: true` significa que existe um registro de enriquecimento para esse CNPJ na estrutura do token. `false` significa que não foi localizado esse registro. O indicador não garante que todos os contatos estejam preenchidos ou atualizados.

Essa consulta apenas informa o enriquecimento existente. Ela não executa enriquecimento e não consome créditos para enriquecer o cliente.

## Limites e guard

A consulta compartilha o guard da API de pedidos. Chamadas de consulta de clientes e das APIs de pedidos disputam os mesmos limites de execução; trocar o token não elimina os limites por estrutura.

<table id="bkmrk-regra-limite-padr%C3%A3o-"><thead><tr class="header"><th>Regra</th><th>Limite padrão</th></tr></thead><tbody><tr class="odd"><td>Execuções simultâneas no guard compartilhado</td><td>2</td></tr><tr class="even"><td>Execuções simultâneas por estrutura</td><td>1</td></tr><tr class="odd"><td>Intervalo após o término de uma execução</td><td>120 segundos</td></tr><tr class="even"><td>Execuções por estrutura</td><td>3 a cada 10 minutos</td></tr><tr class="odd"><td>Tentativas por token</td><td>20 a cada 60 segundos</td></tr><tr class="even"><td>Tentativas globais</td><td>600 a cada 60 segundos</td></tr><tr class="odd"><td>Autenticações simultâneas</td><td>8</td></tr><tr class="even"><td>CNPJs por requisição</td><td>50</td></tr><tr class="odd"><td>Payload</td><td>16 KiB</td></tr><tr class="even"><td>Itens de cada coleção no lote completo</td><td>5.000 por coleção: pessoas, responsáveis, contatos ou vencimentos</td></tr><tr class="odd"><td>Timeout configurado de processamento no banco</td><td>30 segundos; limite de consulta configurado de 10 segundos</td></tr></tbody></table>

Concorrência global e intervalo entre execuções seguem a configuração vigente do servidor. Quando um limite é atingido, a API retorna `429` com o header `Retry-After`, indicando quantos segundos aguardar. O controle é aplicado por instância da aplicação.

Se uma coleção ultrapassar 5.000 itens somando todos os clientes do lote, a API rejeita a resposta inteira com `LIMITE_ITENS`. Reduza a quantidade de CNPJs e consulte novamente. A resposta não é truncada silenciosamente.

## Respostas de erro

<table id="bkmrk-http-c%C3%B3digo-como-tra"><thead><tr class="header"><th>HTTP</th><th>Código</th><th>Como tratar</th></tr></thead><tbody><tr class="odd"><td>400</td><td>`PAYLOAD_INVALIDO` / `JSON_INVALIDO`</td><td>Corrija o JSON, os CNPJs ou a quantidade de itens.</td></tr><tr class="even"><td>401</td><td>`TOKEN_INVALIDO`</td><td>Verifique o token.</td></tr><tr class="odd"><td>403</td><td>`ACESSO_NEGADO`</td><td>Verifique o vínculo e a estrutura autorizada.</td></tr><tr class="even"><td>413</td><td>`PAYLOAD_GRANDE`</td><td>Reduza o payload para até 16 KiB.</td></tr><tr class="odd"><td>422</td><td>`LIMITE_ITENS`</td><td>Divida a lista de CNPJs em lotes menores.</td></tr><tr class="even"><td>422</td><td>`CADASTRO_AMBIGUO`</td><td>Há cadastros duplicados para CNPJs solicitados; contate o suporte.</td></tr><tr class="odd"><td>429</td><td>`LIMITE_API`</td><td>Aguarde o tempo informado em Retry-After.</td></tr><tr class="even"><td>504</td><td>`TEMPO_EXCEDIDO`</td><td>Reduza o lote e respeite o intervalo antes de repetir.</td></tr><tr class="odd"><td>500</td><td>`ERRO_INTERNO`</td><td>Informe o requestId ao suporte.</td></tr></tbody></table>

```
{
  "codigo": "LIMITE_ITENS",
  "mensagem": "Uma coleção excedeu 5.000 itens. Reduza a lista de CNPJs.",
  "requestId": "d8e4c3c2-0000-0000-0000-000000000000"
}
```

Quando nenhum CNPJ está disponível, a resposta é HTTP `200`, com `dados: []`, `totalRegistros: 0` e a lista dos CNPJs indisponíveis. Não é retornado HTTP 404 para cada cliente.

## Boas práticas

- Agrupe consultas em lotes de até 50 CNPJs e evite uma chamada por cliente.
- Armazene os dados necessários na integração para evitar consultas repetidas.
- Respeite o Retry-After e os limites compartilhados com pedidos.
- Trate listas vazias e campos null.
- Não registre o token completo nos logs.
- O retorno inclui documentos e contatos de pessoas; restrinja o acesso a esses dados na sua integração.

Senhas e credenciais de gestor ou conta online não fazem parte da resposta.