Customers
Endpoints da WebApiAlcance para o cadastro de clientes (pessoa física e jurídica) da Alcance Contabilidade. Cobrem listagem, busca por múltiplos critérios (ID, CNPJ, razão social, nome fantasia, cidade, regime tributário), criação, atualização e desativação lógica.
Todos os endpoints exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs.
Base path
/api/v1/customersEscopos necessários
customers:read- listagem, busca e detalhamentocustomers:write- criação, atualização, desativação e exclusão
API Keys emitidas para o gateway MCP devem usar apenas os escopos estritamente necessários - preferencialmente customers:read.
Endpoints
POST /customers/
Cria um novo cliente (PF ou PJ). Os campos login_gov e senha_gov são write-only: aceitos na criação, mas nunca retornados em schemas de leitura.
Parâmetros
Este endpoint não recebe parâmetros de rota ou query - os dados vão no corpo da requisição (CustomerCreate). Campos obrigatórios: razao_social e nome_fantasia; recomendados: cpfecnpj, regime_tributario, cidade e estado.
Request
{
"razao_social": "ACME SERVICOS LTDA",
"nome_fantasia": "ACME",
"cpfecnpj": "12.345.678/0001-99",
"regime_tributario": "Simples Nacional",
"cidade": "Salvador",
"estado": "BA"
}Response 201 Created
{
"success": true,
"message": "Cliente criado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"nome_fantasia": "ACME",
"cpfecnpj": "12.345.678/0001-99",
"regime_tributario": "Simples Nacional",
"cidade": "Salvador",
"estado": "BA",
"ativo": true
}
}Escopo: customers:write
GET /customers/
Lista todos os clientes cadastrados. Lista vazia é estado válido, retornando data: [] com a mensagem "Nenhum cliente encontrado.". A resposta pode ser grande; o gateway MCP trunca em 20 resultados por padrão.
Parâmetros
Este endpoint não recebe parâmetros de rota ou query.
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Lista de clientes recuperada com sucesso",
"data": [
{ "id": 1, "razao_social": "ACME LTDA", "cpfecnpj": "11.111.111/0001-11", "ativo": true },
{ "id": 2, "razao_social": "BETA EIRELI", "cpfecnpj": "22.222.222/0001-22", "ativo": true }
]
}Escopo: customers:read
GET /customers/dctfweb
Variante da listagem otimizada para o módulo DCTFWeb - devolve apenas os campos relevantes para esse filtro. Lista vazia retorna data: [] com a mensagem "Nenhum cliente encontrado.".
Parâmetros
Este endpoint não recebe parâmetros de rota ou query.
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Lista de clientes recuperadas com sucesso!",
"data": [
{ "id": 1, "razao_social": "ACME LTDA", "cpfecnpj": "11.111.111/0001-11", "regime_tributario": "Lucro Presumido" }
]
}Escopo: customers:read
PUT /customers/{customer_id}
Atualiza um cliente existente. O body é um CustomerUpdate com campos parciais - somente o que vier preenchido é alterado. Quando o cliente não existe, retorna erro com a mensagem "Cliente não encontrado.".
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
customer_id | int | path | sim | ID interno do cliente |
Request (CustomerUpdate - todos os campos opcionais)
{
"razao_social": "ACME SERVICOS S.A.",
"regime_tributario": "Lucro Presumido"
}Response 200 OK
{
"success": true,
"message": "Cliente atualizado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS S.A.",
"nome_fantasia": "ACME",
"cpfecnpj": "12.345.678/0001-99",
"regime_tributario": "Lucro Presumido",
"ativo": true
}
}Escopo: customers:write
DELETE /customers/{customer_id}
Remove um cliente do sistema. Operação destrutiva - cascateia para activities, arquivos_processados, lembretes etc. Restrita a perfis administrador e diretoria; funcionários recebem 403 Forbidden.
O gateway MCP não expõe este endpoint. Para inativar um cliente, prefira PUT /customers/desativar/{customer_id}.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
customer_id | int | path | sim | ID interno do cliente |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Cliente deletado com sucesso",
"data": null
}Escopo: customers:write
GET /customers/city
Busca clientes por uma ou mais cidades, com exclusão opcional de regimes tributários e paginação. Sem resultados, retorna a mensagem "Nenhum cliente encontrado." com details: [].
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cidades | List[str] | query | sim | Repita o query param para múltiplas cidades. |
regimes_excluidos | List[str] | query | não | Regimes a excluir. Ex.: Simples Nacional. |
page | int >= 1 | query | não | Página. |
per_page | int 1..100 | query | não | Itens por página. |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/city?cidades=Salvador&cidades=Lauro%20de%20Freitas®imes_excluidos=MEI&page=1&per_page=50Response 200 OK
{
"success": true,
"message": "Clientes recuperados com sucesso",
"data": [
{ "id": 1, "razao_social": "ACME LTDA", "cidade": "Salvador", "estado": "BA", "ativo": true }
]
}Escopo: customers:read
GET /customers/with-services
Lista apenas os clientes para os quais a firma presta serviços (com ao menos um customer_service ativo), com filtros e paginação opcionais. O filtro servico combina os tipos por OR; Todos seleciona clientes com os quatro tipos ativos.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
ativo | bool | query | não | Filtra ativos/inativos; ausente traz todos. |
razao_social | str | query | não | Filtro por razão social. |
nome_fantasia | str | query | não | Filtro por nome fantasia. |
cpfecnpj | str | query | não | Filtro por CPF/CNPJ. |
cidades | List[str] | query | não | Repita o query param para múltiplas cidades. |
regime_tributario | str | query | não | Filtro por regime tributário. |
servico | List[TipoServico] | query | não | Contábil, Fiscal, Pessoal, Financeiro ou Todos (OR). |
page | int >= 1 | query | não | Página. |
per_page | int 1..100 | query | não | Itens por página. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Clientes atendidos recuperados com sucesso",
"data": {
"items": [
{ "id": 1, "razao_social": "ACME LTDA", "nome_fantasia": "ACME", "ativo": true }
],
"total": 1,
"total_pages": 1,
"current_page": 1,
"per_page": 50
}
}Escopo: customers:read
GET /customers/{customer_id}/credenciais-gov
Retorna as credenciais do Portal e-CAC (login_gov, senha_gov) de um cliente. Único endpoint de leitura autorizado a expor esses segredos: restrito aos perfis administrador e diretoria, apenas para usuário humano autenticado (API Key recebe 403 Forbidden) e com registro de auditoria.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
customer_id | int | path | sim | ID interno do cliente |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Credenciais recuperadas com sucesso",
"data": {
"id": 1234,
"login_gov": "12345678000199",
"senha_gov": "senha-do-portal"
}
}Escopo: customers:read
GET /customers/{customer_id}
Detalha um cliente pelo ID inteiro. Quando não encontrado, retorna a mensagem "Cliente não encontrado.".
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
customer_id | int | path | sim | ID interno do cliente |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"nome_fantasia": "ACME",
"cpfecnpj": "12.345.678/0001-99",
"cidade": "Salvador",
"estado": "BA",
"regime_tributario": "Simples Nacional",
"ativo": true
}
}Escopo: customers:read
GET /customers/cnpj/
Busca exata pelo CNPJ numérico (apenas dígitos). Note a barra final obrigatória antes da query string (ver Notas).
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cnpj | int | query | sim | CNPJ sem máscara (14 dígitos) |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/cnpj/?cnpj=12345678000199Response 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"cpfecnpj": "12.345.678/0001-99",
"ativo": true
}
}Escopo: customers:read
GET /customers/cnpj_parcial/
Busca por prefixo numérico do CNPJ (útil para localizar a raiz XX.XXX.XXX). Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cnpj | int | query | sim | Prefixo numérico do CNPJ (raiz) |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/cnpj_parcial/?cnpj=12345678Response 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "cpfecnpj": "12.345.678/0001-99", "ativo": true }
]
}Escopo: customers:read
GET /customers/razao_social/
Match exato da razão social. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
razao_social | str | query | sim | Razão social exata |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/razao_social/?razao_social=ACME%20SERVICOS%20LTDAResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"cpfecnpj": "12.345.678/0001-99",
"ativo": true
}
}Escopo: customers:read
GET /customers/razao_social_parcial/
Match por LIKE - retorna clientes cuja razão social contém a sequência informada. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
razao_social | str | query | sim | Trecho da razão social a buscar |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/razao_social_parcial/?razao_social=SERVICOSResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "cpfecnpj": "12.345.678/0001-99", "ativo": true }
]
}Escopo: customers:read
GET /customers/razao_social_parcial_format/
Match parcial com normalização - remove acentos e pontuação antes de comparar. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
razao_social | str | query | sim | Trecho da razão social a buscar |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/razao_social_parcial_format/?razao_social=servicosResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "cpfecnpj": "12.345.678/0001-99", "ativo": true }
]
}Escopo: customers:read
GET /customers/razao_social_fuzzy/
Fuzzy matching por similaridade textual - tolera erros de digitação. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
razao_social | str | query | sim | Termo aproximado da razão social |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/razao_social_fuzzy/?razao_social=acmi%20servicosResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "cpfecnpj": "12.345.678/0001-99", "ativo": true }
]
}Escopo: customers:read
GET /customers/nome_fantasia/
Match exato do nome fantasia. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
nome_fantasia | str | query | sim | Nome fantasia exato |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/nome_fantasia/?nome_fantasia=ACMEResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"nome_fantasia": "ACME",
"ativo": true
}
}Escopo: customers:read
GET /customers/nome_fantasia_parcial/
Match por LIKE - retorna clientes cujo nome fantasia contém a sequência informada. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
nome_fantasia | str | query | sim | Trecho do nome fantasia a buscar |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/nome_fantasia_parcial/?nome_fantasia=ACResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "nome_fantasia": "ACME", "ativo": true }
]
}Escopo: customers:read
GET /customers/nome_fantasia_parcial_format/
Match parcial do nome fantasia com normalização - remove acentos e pontuação antes de comparar. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
nome_fantasia | str | query | sim | Trecho do nome fantasia a buscar |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/nome_fantasia_parcial_format/?nome_fantasia=acmeResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "nome_fantasia": "ACME", "ativo": true }
]
}Escopo: customers:read
GET /customers/nome_fantasia_fuzzy/
Fuzzy matching do nome fantasia por similaridade textual - tolera erros de digitação. Exige a barra final antes da query string.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
nome_fantasia | str | query | sim | Termo aproximado do nome fantasia |
Request
Sem corpo de requisição. Exemplo de chamada:
GET /api/v1/customers/nome_fantasia_fuzzy/?nome_fantasia=acmiResponse 200 OK
{
"success": true,
"message": "Cliente encontrado com sucesso",
"data": [
{ "id": 1234, "razao_social": "ACME SERVICOS LTDA", "nome_fantasia": "ACME", "ativo": true }
]
}Escopo: customers:read
GET /customers/regime_tributario/
Agrupa todos os clientes por regime tributário. Retorna um objeto customers com uma lista por regime.
Parâmetros
Este endpoint não recebe parâmetros de rota ou query.
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Clientes encontrados com sucesso",
"data": {
"customers": {
"Simples Nacional": [{ "id": 1, "razao_social": "ACME LTDA" }],
"Lucro Presumido": [{ "id": 7, "razao_social": "BETA EIRELI" }],
"Lucro Real": []
}
}
}Escopo: customers:read
PUT /customers/desativar/{customer_id}
Inativa um cliente (ativo = false) sem apagar registros relacionados. É a forma recomendada para "desligar" um cliente. Quando não encontrado, retorna a mensagem "Cliente não encontrado.".
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
customer_id | int | path | sim | ID interno do cliente |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Cliente atualizado com sucesso",
"data": {
"id": 1234,
"razao_social": "ACME SERVICOS LTDA",
"ativo": false
}
}Escopo: customers:write
Schemas
Customer
Campos do model Customer retornado no data das respostas, agrupados por categoria.
| Campo | Tipo | Descrição |
|---|---|---|
id | int | Chave primária, identificador canônico em todas as tools MCP. |
razao_social | str | Razão social (PJ) ou nome completo (PF). |
nome_fantasia | str | Nome fantasia. |
cpfecnpj | str | CNPJ (PJ) ou CPF (PF), com máscara. |
cpf | str | CPF do responsável (quando PJ). |
numero_dominio | str | Código no sistema Domínio. |
inscricao_estadual | str | Inscrição estadual. |
inscricao_municipal | str | Inscrição municipal. |
telefone | str | Telefone fixo. |
celular | str | Celular. |
email | str | E-mail principal. |
endereco | str | Logradouro. |
numero | str | Número. |
complemento | str | Complemento. |
bairro | str | Bairro. |
cidade | str | Cidade. |
estado | str | UF (2 letras). |
cep | str | CEP. |
regime_tributario | str | Simples Nacional, Lucro Presumido, Lucro Real ou MEI. |
tipo_conta | str | Tipo de conta. |
ativo | bool | Situação do cliente; desativar = false. |
certificado | bool | Possui e-CNPJ digital. |
zap_contabil | bool | Integração ZapContábil habilitada. |
representante | str | Representante. |
numero_profissionais | str | Número de profissionais. |
email1_iss | str | E-mail 1 para ISS / nota fiscal. |
email2_iss | str | E-mail 2 para ISS / nota fiscal. |
email3_iss | str | E-mail 3 para ISS / nota fiscal. |
aliquota_iss | bool | Indicador de alíquota de ISS. |
login_gov | str | Sensível. Credencial do Portal e-CAC. Nunca exposto pelo gateway MCP. |
senha_gov | str | Sensível. Credencial do Portal e-CAC. Nunca exposto pelo gateway MCP. |
Campos sensíveis internos: login_gov e senha_gov armazenam credenciais do Portal e-CAC. Nunca são expostos pelo gateway MCP. Mantenha o escopo customers:read restrito à leitura de campos não-sensíveis quando a API Key for emitida para clientes IA.
Notas
Armadilha de roteamento FastAPI. A rota dinâmica GET /{customer_id} é declarada antes das rotas estáticas GET /cnpj/, GET /razao_social/, GET /nome_fantasia/. Para que o FastAPI case a rota estática (e não interprete cnpj como um customer_id inválido), a barra final é obrigatória na chamada: use /customers/cnpj/?cnpj=..., nunca /customers/cnpj?cnpj=....
- Toda resposta segue o envelope
{ success, message, data }(ou{ success: false, message, details }em erro). Códigos HTTP refletem semântica REST padrão. - Resultados grandes (
GET /customers/) devem ser paginados ou filtrados pelo cliente. O gateway MCP trunca em 20 itens com footer orientativo. - O campo
cpfecnpjchega da WebApi sem máscara; o MCP aplica a máscaraXX.XXX.***/0001-XXantes de devolver ao LLM.