SN Analytics: Comércio

Endpoints da WebApiAlcance para o faturamento de comércio do Simples Nacional, consumidos pelo produto Simples Analytics. O domínio tem dois níveis: o consolidado (total de faturamento por empresa e competência, calculado no servidor) e os registros individuais de NF-e que compõem cada consolidado. Toda escrita em registros recalcula automaticamente o consolidado da competência afetada - um consolidado que fica sem registros é apagado. Os endpoints cobrem a listagem de consolidados, a listagem paginada de registros, a criação individual e em lote (com deduplicação de NF-e), a atualização de valores em lote, a atualização individual e a exclusão de um registro.

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/sn-comercio

Escopos necessários

  • sn_comercio:read - listagem de consolidados e de registros
  • sn_comercio:write - criação individual e em lote, atualização de valores em lote, atualização individual e exclusão de registros

O escopo é derivado do prefixo público da rota: /sn-comercio vira o recurso sn_comercio (hífen → underscore), e o método HTTP define a ação (read para GET, write para POST/PUT/DELETE).

Ordem das rotas

As rotas literais POST /sn-comercio/registros/batch e PUT /sn-comercio/registros/batch-valores são declaradas antes da rota dinâmica PUT|DELETE /sn-comercio/registros/{registro_id} para que o FastAPI faça o match na ordem correta (batch/batch-valores não são interpretados como um registro_id).

Endpoints

GET /sn-comercio/consolidados

Lista os consolidados de comércio (total de faturamento por empresa e competência). Aceita filtro opcional por empresa_id. Lista vazia é um estado válido.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
empresa_idintquerynãoFiltra os consolidados de uma empresa.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Consolidados recuperados com sucesso",
  "data": [
    {
      "id": 501,
      "empresa_id": 10,
      "competencia": "03/2026",
      "total_faturamento": 45000.0,
      "created_at": "2026-04-01T09:00:00",
      "updated_at": "2026-04-05T11:20:00"
    }
  ]
}

Escopo: sn_comercio:read

GET /sn-comercio/registros

Lista os registros individuais de NF-e, com paginação. Aceita filtros opcionais por empresa e por intervalo de data/hora da nota.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
empresa_idintquerynãoFiltra os registros de uma empresa.
data_iniciodatetimequerynãoFiltro inicial de data_hora_nfe (ISO 8601).
data_fimdatetimequerynãoFiltro final de data_hora_nfe (ISO 8601).
limitintquerynãoItens por página. 1..10000. Default 1000.
offsetintquerynãoOffset de paginação. >= 0. Default 0.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Registros recuperados com sucesso",
  "data": {
    "items": [
      {
        "id": 9001,
        "empresa_id": 10,
        "consolidado_id": 501,
        "data_hora_nfe": "2026-03-15T14:20:00",
        "competencia": "03/2026",
        "valor_produtos": 12000.0,
        "numero_nfe": "1001",
        "created_at": "2026-03-16T08:00:00",
        "updated_at": "2026-03-16T08:00:00"
      }
    ],
    "total": 1
  }
}

O campo total reflete o total de registros que casam com o filtro, ignorando limit/offset.

Escopo: sn_comercio:read

POST /sn-comercio/registros

Cria um registro de comércio. Resolve (ou cria) o consolidado da (empresa_id, competencia) e recalcula o total automaticamente, em uma única transação.

Parâmetros

Este endpoint não recebe parâmetros de rota ou query. O corpo é um SnComercioRegistroCreate.

Request

{
  "empresa_id": 10,
  "data_hora_nfe": "2026-03-15T14:20:00",
  "competencia": "03/2026",
  "valor_produtos": 12000.0,
  "numero_nfe": "1001"
}

Response 201 Created

{
  "status": "success",
  "message": "Registro criado com sucesso",
  "data": {
    "id": 9001,
    "empresa_id": 10,
    "consolidado_id": 501,
    "data_hora_nfe": "2026-03-15T14:20:00",
    "competencia": "03/2026",
    "valor_produtos": 12000.0,
    "numero_nfe": "1001",
    "created_at": "2026-03-16T08:00:00",
    "updated_at": "2026-03-16T08:00:00"
  }
}

Erros de negócio respondem {"message": "<texto>"} com o código HTTP mapeado a partir da mensagem: 404 Not Found (não encontrado, ex.: empresa inexistente), 409 Conflict (já existe/duplicado) ou 422 Unprocessable Entity (demais casos).

Escopo: sn_comercio:write

POST /sn-comercio/registros/batch

Cria registros em lote (até 5000 itens), com deduplicação de NF-e: um item é considerado duplicata de um registro já gravado quando numero_nfe, competencia e empresa_id coincidem (numero_nfe nulo/vazio nunca é duplicata). Recalcula todos os consolidados afetados em uma única transação.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
em_duplicidadestringquerynãoDecisão para o lote inteiro quando há duplicatas: substituir (atualiza os existentes), duplicar (grava mesmo assim) ou ignorar (descarta os duplicados e grava o restante). Omitido = a API detecta e devolve 409 sem gravar nada.

O corpo é uma lista de SnComercioRegistroCreate, com no máximo 5000 itens.

Request

[
  {
    "empresa_id": 10,
    "data_hora_nfe": "2026-03-15T14:20:00",
    "competencia": "03/2026",
    "valor_produtos": 12000.0,
    "numero_nfe": "1001"
  }
]

Response 201 Created

{
  "status": "success",
  "message": "Registros criados com sucesso",
  "data": [
    {
      "id": 9001,
      "empresa_id": 10,
      "consolidado_id": 501,
      "data_hora_nfe": "2026-03-15T14:20:00",
      "competencia": "03/2026",
      "valor_produtos": 12000.0,
      "numero_nfe": "1001",
      "created_at": "2026-03-16T08:00:00",
      "updated_at": "2026-03-16T08:00:00"
    }
  ]
}

Response 409 Conflict (duplicatas encontradas e em_duplicidade não informado - nada é gravado)

{
  "status": "pendente_decisao",
  "message": "1 registro(s) do lote já existem para a mesma empresa, competência e número de NF-e.",
  "data": {
    "total_duplicatas": 1,
    "decisoes_disponiveis": ["substituir", "duplicar", "ignorar"],
    "duplicatas": [
      {
        "id": 9001,
        "empresa_id": 10,
        "competencia": "03/2026",
        "numero_nfe": "1001",
        "valor_atual": 12000.0,
        "valor_novo": 13500.0,
        "data_hora_nfe_atual": "2026-03-15T14:20:00",
        "data_hora_nfe_novo": "2026-03-16T09:00:00"
      }
    ]
  }
}

Reenvie o mesmo lote acrescentando ?em_duplicidade=substituir|duplicar|ignorar para resolver. Erros de validação de negócio (fora do fluxo de duplicidade) respondem {"message": "<texto>"} com 404, 409 ou 422, conforme a mensagem.

Escopo: sn_comercio:write

PUT /sn-comercio/registros/batch-valores

Atualiza valor e/ou número de NF-e de registros que já existem, identificados por id. Não faz deduplicação (só atualiza linhas existentes, nunca insere) e recalcula os consolidados afetados.

Parâmetros

Este endpoint não recebe parâmetros de rota ou query. O corpo é uma lista de SnComercioRegistroBatchValores, com no máximo 5000 itens.

Request

[{ "id": 9001, "valor_produtos": 13500.0, "numero_nfe": "1001" }]

Response 200 OK

{
  "status": "success",
  "message": "Valores atualizados com sucesso",
  "data": [
    {
      "id": 9001,
      "empresa_id": 10,
      "consolidado_id": 501,
      "data_hora_nfe": "2026-03-15T14:20:00",
      "competencia": "03/2026",
      "valor_produtos": 13500.0,
      "numero_nfe": "1001",
      "created_at": "2026-03-16T08:00:00",
      "updated_at": "2026-03-17T10:00:00"
    }
  ]
}

Se algum id do lote não existir, a chamada inteira é desfeita (rollback) e a API responde {"message": "Registro <id> não encontrado."} com 404 Not Found.

Escopo: sn_comercio:write

PUT /sn-comercio/registros/{registro_id}

Atualiza um registro individualmente (update parcial). Se empresa_id e/ou competencia mudarem, o registro é revinculado ao consolidado correto e ambos os consolidados (antigo e novo) são recalculados.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
registro_idintpathsimID do registro de NF-e.

O corpo é um SnComercioRegistroUpdate.

Request

{ "valor_produtos": 14000.0 }

Response 200 OK

{
  "status": "success",
  "message": "Registro atualizado com sucesso",
  "data": {
    "id": 9001,
    "empresa_id": 10,
    "consolidado_id": 501,
    "data_hora_nfe": "2026-03-15T14:20:00",
    "competencia": "03/2026",
    "valor_produtos": 14000.0,
    "numero_nfe": "1001",
    "created_at": "2026-03-16T08:00:00",
    "updated_at": "2026-03-17T15:30:00"
  }
}

Quando registro_id não existe, responde {"message": "Registro não encontrado."} com 404 Not Found.

Escopo: sn_comercio:write

DELETE /sn-comercio/registros/{registro_id}

Exclui um registro de NF-e e recalcula (ou apaga, se ficar vazio) o consolidado correspondente.

Parâmetros

ParâmetroTipoLocalObrigatórioDescrição
registro_idintpathsimID do registro de NF-e.

Request

Sem corpo de requisição.

Response 200 OK

{
  "status": "success",
  "message": "Registro removido com sucesso",
  "data": null
}

Quando registro_id não existe, responde {"message": "Registro não encontrado."} com 404 Not Found.

Escopo: sn_comercio:write

Schemas

SnComercioRegistroCreate

Corpo do POST /sn-comercio/registros e item do POST /sn-comercio/registros/batch.

CampoTipoObrigatórioObservações
empresa_idintsimID da empresa (equivale ao customer.id).
data_hora_nfedatetimesimData/hora de emissão da NF-e.
competenciastringsimFormato MM/AAAA.
valor_produtosDecimalnão>= 0, até 15 dígitos com 2 casas decimais. Default 0.
numero_nfestringnãoMáx. 50 caracteres. Chave da deduplicação no batch; null nunca é duplicata.

SnComercioRegistroUpdate

Corpo do PUT /sn-comercio/registros/{registro_id}. Update parcial - todos os campos são opcionais, mas não aceitam null explícito (exceto numero_nfe, a única coluna anulável).

CampoTipoObrigatórioObservações
empresa_idintnãoAlterar revincula o registro ao consolidado da nova empresa.
data_hora_nfedatetimenão-
competenciastringnãoFormato MM/AAAA. Alterar revincula o registro ao consolidado da nova competência.
valor_produtosDecimalnão>= 0, até 15 dígitos com 2 casas decimais.
numero_nfestringnãoMáx. 50 caracteres. Aceita null explícito para limpar o campo.

SnComercioRegistroBatchValores

Item do PUT /sn-comercio/registros/batch-valores.

CampoTipoObrigatórioObservações
idintsimID do registro já gravado.
valor_produtosDecimalsim>= 0, até 15 dígitos com 2 casas decimais.
numero_nfestringnãoMáx. 50 caracteres.

SnComercioDuplicataDetectada

Item de data.duplicatas na resposta 409 do POST /sn-comercio/registros/batch.

CampoTipoObservações
idintID do registro já gravado (candidato à substituição).
empresa_idint-
competenciastring-
numero_nfestring-
valor_atualfloatvalor_produtos já gravado.
valor_novofloatvalor_produtos que está chegando no lote.
data_hora_nfe_atualdatetime-
data_hora_nfe_novodatetime-

SnComercioRegistroRead

Retorno de leitura de um registro. empresa_id, created_at e updated_at do JSON mapeiam as colunas id_cliente, data_hora_criacao e data_hora_atualizacao.

CampoTipoObservações
idint-
empresa_idintColuna id_cliente no banco.
consolidado_idintID do consolidado ao qual o registro pertence.
data_hora_nfedatetime-
competenciastring-
valor_produtosfloat-
numero_nfestringPode ser null.
created_atdatetimeColuna data_hora_criacao.
updated_atdatetimeColuna data_hora_atualizacao.

SnComercioConsolidadoRead

Retorno de leitura de um consolidado (somente leitura - os totais são calculados no servidor).

CampoTipoObservações
idint-
empresa_idintColuna id_cliente no banco.
competenciastringFormato MM/AAAA.
total_faturamentofloatSoma de valor_produtos dos registros da competência.
created_atdatetimeColuna data_hora_criacao.
updated_atdatetimeColuna data_hora_atualizacao.

Notas

  • Sucesso segue o envelope { status: "success", message, data }. Erros levantados como HTTPException (404/409/422/500) respondem { message } com o código HTTP correspondente. O POST /sn-comercio/registros/batch tem um terceiro estado, { status: "pendente_decisao", message, data } com 409, específico para a deduplicação de NF-e.
  • GET /sn-comercio/consolidados e GET /sn-comercio/registros sempre retornam 200 OK; lista vazia é estado normal antes da primeira importação.
  • Ordem de rotas (FastAPI): POST /sn-comercio/registros/batch e PUT /sn-comercio/registros/batch-valores são declaradas antes de PUT|DELETE /sn-comercio/registros/{registro_id}.
  • Toda escrita em registros (criar, batch, batch-valores, atualizar, excluir) recalcula o(s) consolidado(s) da(s) competência(s) afetada(s) na mesma transação; um consolidado sem registros é apagado automaticamente.
  • Duplicata de NF-e = mesmo numero_nfe na mesma competencia da mesma empresa_id. Registro com numero_nfe nulo/vazio nunca é duplicata. A decisão de em_duplicidade vale para o lote inteiro, não item a item.
  • POST /sn-comercio/registros/batch e PUT /sn-comercio/registros/batch-valores aceitam no máximo 5000 itens por chamada.