Importações
Endpoints da WebApiAlcance para o fluxo de importação de arquivos - envio de extratos e planilhas (ofx, pdf, csv, contas, regras_conversor), leitura e conferência do parse, geração dos lançamentos contábeis e gestão do ciclo de vida de cada importação (listagem, detalhe, download do original, substituição, duplicação e exclusão).
O parse e a geração de lançamentos são síncronos - não há task Celery neste domínio: preview, confirmar, analisar-regras e confirmar-regras rodam o parser na própria requisição e devolvem o resultado no envelope.
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/importacoesEscopos necessários
importacoes:read- listagem, detalhe, download do arquivo e lançamentos geradosimportacoes:write- upload, preview, confirmar, análise/confirmação de regras, substituir, duplicar e excluir
O escopo é derivado da rota: o prefixo /importacoes vira o recurso importacoes, e o método HTTP define a ação (read para GET, write para POST/DELETE).
Endpoints
POST /importacoes/upload
Faz o upload do arquivo e cria o registro de importação com status pending. Requisição multipart/form-data (não JSON). Calcula o hash SHA-256 do arquivo e bloqueia reimport (409 Conflict) se já existir uma importação bem-sucedida com o mesmo arquivo + cliente.
Parâmetros
Este endpoint não recebe parâmetros de rota ou query - os campos vão no formulário multipart/form-data:
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
id_cliente | int | form | sim | ID do cliente (customer.id). |
tipo | str (enum) | form | sim | Um de ofx | pdf | csv | contas | regras_conversor. |
arquivo | file | form | sim | Arquivo binário a importar. |
id_estrutura | int | form | não | Layout usado (omitir para OFX; opcional p/ regras_conversor). |
id_plano_contas | int | form | não | Plano alvo (contas/regras_conversor). NULL para OFX/PDF/CSV. |
id_banco | int | form | não | Banco selecionado (feature Padrão de Regras por Banco). Para OFX, a resposta também traz codigo_ofx_detectado / id_banco_sugerido. |
Request
Requisição multipart/form-data - os campos vão no formulário (ver tabela acima), não em JSON. Não envie um corpo JSON.
Response 201 Created
{
"success": true,
"message": "Upload registrado com sucesso",
"data": {
"id": 812,
"id_usuario_created": 7,
"id_cliente": 154,
"id_estrutura": null,
"id_plano_contas": null,
"id_banco": null,
"tipo": "ofx",
"nome_arquivo_original": "extrato-junho.ofx",
"tamanho_bytes": 48213,
"hash_arquivo": "9f2c...",
"status": "pending",
"qtd_lancamentos_criados": 0,
"qtd_linhas_erro": 0,
"codigo_ofx_detectado": "341",
"id_banco_sugerido": 12
}
}Arquivo acima de IMPORTACAO_MAX_UPLOAD_BYTES retorna 413 Request Entity Too Large; hash duplicado retorna 409 Conflict, cujo detail traz { message, importacao_existente }, onde importacao_existente segue o HashDuplicadoInfo. Escopo: importacoes:write
GET /importacoes/
Lista as importações do escritório, com filtros opcionais. Lista vazia é estado válido - retorna 200 OK com data: [].
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
id_cliente | int | query | não | Filtra por cliente. |
tipo | str (enum) | query | não | ofx | pdf | csv | contas | regras_conversor. |
status | str (enum) | query | não | pending | processing | success | partial | error. |
data_inicio | date | query | não | Data inicial de data_hora_criacao (YYYY-MM-DD). |
data_fim | date | query | não | Data final de data_hora_criacao (YYYY-MM-DD). |
limit | int | query | não | Padrão 50, entre 1 e 500. |
offset | int | query | não | Padrão 0, maior ou igual a 0. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Importacoes recuperadas com sucesso",
"data": [
{
"id": 812,
"id_usuario_created": 7,
"id_cliente": 154,
"tipo": "ofx",
"nome_arquivo_original": "extrato-junho.ofx",
"tamanho_bytes": 48213,
"status": "success",
"qtd_lancamentos_criados": 128,
"qtd_atualizados": 0,
"qtd_ignorados": 3,
"qtd_linhas_erro": 0,
"data_hora_criacao": "2026-07-03T14:20:00",
"data_hora_conclusao": "2026-07-03T14:22:10"
}
]
}O data é um array de ImportacaoListItem (ou []). Escopo: importacoes:read
GET /importacoes/{importacao_id}
Detalha uma importação pelo ID inteiro. 404 Not Found quando não existe ou não pertence ao usuário.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID interno da importação. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Importacao encontrada",
"data": {
"id": 812,
"id_usuario_created": 7,
"id_cliente": 154,
"id_estrutura": null,
"id_plano_contas": null,
"id_banco": 12,
"tipo": "ofx",
"nome_arquivo_original": "extrato-junho.ofx",
"tamanho_bytes": 48213,
"hash_arquivo": "9f2c...",
"status": "success",
"qtd_lancamentos_criados": 128,
"qtd_linhas_erro": 0,
"data_hora_criacao": "2026-07-03T14:20:00",
"data_hora_conclusao": "2026-07-03T14:22:10"
}
}O data segue o schema ImportacaoRead. Escopo: importacoes:read
GET /importacoes/{importacao_id}/arquivo
Faz o download do arquivo original do upload. A resposta não é o envelope JSON - é um FileResponse binário (application/octet-stream) com o nome_arquivo_original como nome de download.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
Request
Sem corpo de requisição.
Response 200 OK
Stream binário do arquivo (application/octet-stream), sem envelope JSON. Retorna 404 Not Found se a importação não existir/pertencer ao usuário ou se o arquivo não estiver mais no disco.
Escopo: importacoes:read
GET /importacoes/{importacao_id}/lancamentos
Lista os lançamentos contábeis gerados a partir desta importação (id_importacao == importacao_id), ordenados por data_registro e id. A lista fica populada após um POST /confirmar bem-sucedido. Visão compartilhada do escritório - lista todos os lançamentos da importação, sem filtro por dono.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Lancamentos recuperados com sucesso",
"data": [
{
"id": 90211,
"id_importacao": 812,
"data_registro": "2026-06-01",
"descricao": "PAGAMENTO FORNECEDOR XYZ",
"valor": 1520.5,
"tipo": "D",
"regras_aplicadas": []
}
]
}O data é um array de LancamentoContabilRead (com regras_aplicadas resolvidas) ou []. 404 Not Found quando a importação não existe/pertence ao usuário. Escopo: importacoes:read
POST /importacoes/{importacao_id}/preview
Roda o parser e devolve as transações detectadas + erros por linha sem persistir nada. Serve para o frontend mostrar "isto é o que vai ser criado" antes do POST /confirmar.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "128 lancamentos detectados",
"data": {
"importacao_id": 812,
"tipo": "ofx",
"total_linhas_lidas": 131,
"qtd_lancamentos_detectados": 128,
"qtd_erros": 0,
"qtd_ignorados": 3,
"ignorados": [],
"lancamentos": [
{
"linha_arquivo": 1,
"data": "2026-06-01",
"descricao": "PAGAMENTO FORNECEDOR XYZ",
"valor": 1520.5,
"tipo": "D"
}
],
"erros": [],
"id_banco": 12,
"codigo_ofx_detectado": "341",
"id_banco_sugerido": 12
}
}O data segue o schema ImportacaoPreviewResponse. Escopo: importacoes:write
POST /importacoes/{importacao_id}/confirmar
Roda o parser e persiste os lançamentos em transação atômica. Em sucesso parcial (algumas linhas falham), o status final é partial.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
id_banco | int | query | não | Banco a aplicar (feature Padrão de Regras por Banco). Quando informado, substitui/persiste o banco da importação e seus padrões ATIVOS têm precedência sobre as regras de cliente/estrutura. Omitir mantém o banco vinculado no upload. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Importacao concluida: 128 lancamentos criados (status=success)",
"data": {
"importacao_id": 812,
"qtd_criados": 128,
"qtd_erros": 0,
"qtd_ignorados": 3,
"status_final": "success",
"data_hora_conclusao": "2026-07-03T14:22:10"
}
}O data segue o schema ConfirmarResponse. Escopo: importacoes:write
POST /importacoes/{importacao_id}/analisar-regras
Para importações do tipo regras_conversor: lê a planilha e devolve colunas detectadas, amostra (até 5 linhas), total de linhas, duplicados, contas faltantes (código de exportação sem Conta no cliente) e os planos do cliente. Não persiste.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
O corpo segue o schema AnalisarRegrasRequest: mapeamento (obrigatório) e campo_destino (opcional).
Request
{
"mapeamento": { "comparacao": 0, "exportacao": 1 },
"campo_destino": "conta_debito"
}Response 200 OK
{
"success": true,
"message": "240 linhas analisadas",
"data": {
"colunas": [
{ "indice": 0, "header": "Historico" },
{ "indice": 1, "header": "Codigo" }
],
"amostra": [{ "comparacao": "TARIFA", "exportacao": "3010" }],
"total_linhas": 240,
"mapeamento_sugerido": { "comparacao": 0, "exportacao": 1 },
"duplicados": [],
"contas_faltantes": [],
"planos_cliente": [{ "id": 5, "codigo_dominio": "01", "nome": "Plano Padrao" }]
}
}O data segue o schema AnalisarRegrasResponse. Escopo: importacoes:write
POST /importacoes/{importacao_id}/confirmar-regras
Processa todas as linhas da planilha, criando/atualizando RegraLancamento. O plano de contas de cada regra é derivado da conta resolvida pelo codigo_dominio (coluna de exportação). Resoluções de duplicados e de contas faltantes vêm no corpo.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
O corpo segue o schema ConfirmarRegrasRequest: mapeamento e campo_destino obrigatórios; demais campos com defaults.
Request
{
"mapeamento": { "comparacao": 0, "exportacao": 1 },
"campo_comparacao": "historico",
"modo_comparacao": "contem",
"campo_destino": "conta_debito",
"resolucao_duplicados": "ignorar",
"resolucao_contas_faltantes": "ignorar"
}Response 200 OK
{
"success": true,
"message": "230 criadas, 8 atualizadas, 2 ignoradas (status=success)",
"data": {
"importacao_id": 815,
"qtd_criadas": 230,
"qtd_atualizadas": 8,
"qtd_ignoradas": 2,
"qtd_erros": 0,
"status_final": "success",
"erros": [],
"data_hora_conclusao": "2026-07-03T15:05:40"
}
}O data segue o schema ConfirmarRegrasResponse. Escopo: importacoes:write
POST /importacoes/{importacao_id}/substituir
Substitui uma importação em status terminal: apaga os lançamentos antigos e roda o parser de novo no mesmo arquivo. Aceita success, partial e error. Recusa pending e processing (409 Conflict). Útil para reaplicar uma estrutura corrigida ou reavaliar após nova regra.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
Request
Sem corpo de requisição.
Response 200 OK
{
"success": true,
"message": "Importacao substituida: 128 lancamentos criados (status=success)",
"data": {
"importacao_id": 812,
"qtd_criados": 128,
"qtd_erros": 0,
"qtd_ignorados": 3,
"status_final": "success",
"data_hora_conclusao": "2026-07-03T16:10:00"
}
}O data segue o schema ConfirmarResponse. Escopo: importacoes:write
POST /importacoes/{importacao_id}/duplicar
Duplica uma importação: copia o arquivo no disco com novo UUID e cria um novo registro pending apontando para a original via id_importacao_original. Recusa processing (409 Conflict). Bypassa o dedup por hash internamente - duplicar é justamente reusar o mesmo arquivo. O fluxo segue com /preview e /confirmar no novo id retornado.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação original. |
Request
Sem corpo de requisição.
Response 201 Created
{
"success": true,
"message": "Importacao duplicada com sucesso (nova id=813)",
"data": {
"id": 813,
"id_usuario_created": 7,
"id_cliente": 154,
"id_importacao_original": 812,
"tipo": "ofx",
"nome_arquivo_original": "extrato-junho.ofx",
"tamanho_bytes": 48213,
"status": "pending",
"qtd_lancamentos_criados": 0,
"qtd_linhas_erro": 0,
"data_hora_criacao": "2026-07-03T17:00:00"
}
}O data segue o schema ImportacaoRead da nova importação. Escopo: importacoes:write
DELETE /importacoes/{importacao_id}
Hard delete cascade: apaga o registro de importação, todos os lançamentos vinculados e o arquivo do disco. Importações filhas (criadas via /duplicar desta) ficam órfãs (id_importacao_original = NULL via ON DELETE SET NULL) - não são deletadas em cascade.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
importacao_id | int | path | sim | ID da importação. |
excluir_regras | bool | query | não | Apenas para regras_conversor. true: apaga em cascade as RegraLancamento geradas por este import. false (default): as regras são desvinculadas (id_importacao → NULL) e permanecem. |
Request
Sem corpo de requisição.
Response 204 No Content
Sem body. Retorna 404 Not Found se a importação não existir ou não pertencer ao usuário. Imports contas apagam apenas registro + arquivo (não apagam contas).
Escopo: importacoes:write
Schemas
ImportacaoRead
Registro completo de uma importação (retorno de upload, detalhe e duplicar).
| Campo | Tipo | Notas |
|---|---|---|
id | int | Identificador da importação. |
id_usuario_created | int | Usuário que criou o upload. |
usuario_nome | str? | Nome do usuário criador. |
id_cliente | int | Cliente-alvo. |
id_estrutura | int? | Layout usado (NULL para OFX). |
id_plano_contas | int? | Plano alvo (contas/regras_conversor). |
id_importacao_original | int? | Import de origem quando esta foi duplicada. |
id_banco | int? | Banco selecionado/sugerido. |
tipo | str (enum) | ofx | pdf | csv | contas | regras_conversor. |
nome_arquivo_original | str | Nome original do arquivo enviado. |
path_arquivo | str | Caminho interno no disco. |
tamanho_bytes | int | Tamanho do arquivo. |
hash_arquivo | str? | SHA-256 usado no dedup. |
status | str (enum) | pending | processing | success | partial | error. |
qtd_lancamentos_criados | int | Lançamentos gerados. |
qtd_atualizados | int | Default 0. |
qtd_ignorados | int | Default 0. |
qtd_linhas_erro | int | Linhas que falharam no parse. |
erros | list? | Detalhes dos erros por linha. |
data_hora_criacao | datetime | Criação do registro. |
data_hora_conclusao | datetime? | Preenchida ao concluir o parse. |
codigo_ofx_detectado | str? | BANKID lido do OFX (não persistido). |
id_banco_sugerido | int? | Banco do catálogo cujo codigo_ofx casa (não persistido). |
ImportacaoListItem
Versão enxuta para listagens - omite path_arquivo (segurança) e erros. Traz os mesmos campos de identificação, tipo, status, contadores (qtd_lancamentos_criados, qtd_atualizados, qtd_ignorados, qtd_linhas_erro) e datas (data_hora_criacao, data_hora_conclusao).
ImportacaoPreviewResponse
Resultado do POST /preview - o que seria criado, sem persistir.
| Campo | Tipo | Notas |
|---|---|---|
importacao_id | int | Importação analisada. |
tipo | str (enum) | Tipo do arquivo. |
total_linhas_lidas | int | Linhas lidas do arquivo. |
qtd_lancamentos_detectados | int | Transações válidas detectadas. |
qtd_erros | int | Linhas com erro. |
qtd_ignorados | int | Linhas descartadas por regra de ignorar. Default 0. |
ignorados | LancamentoIgnorado[] | Linhas que serão descartadas (com regra_id/regra_nome). |
lancamentos | LancamentoDetectado[] | Transações detectadas. |
erros | ErroParse[] | { linha_arquivo, mensagem }. |
id_banco | int? | Banco já vinculado à importação. |
codigo_ofx_detectado | str? | BANKID lido agora (OFX). |
id_banco_sugerido | int? | Banco do catálogo que casa. |
Cada LancamentoDetectado traz linha_arquivo, data, descricao, valor (sempre positivo), tipo (D=débito/saída, C=crédito/entrada), documento? e historico_complementar?.
ConfirmarResponse
Resultado do POST /confirmar (e de /substituir).
| Campo | Tipo | Notas |
|---|---|---|
importacao_id | int | Importação processada. |
qtd_criados | int | Lançamentos persistidos. |
qtd_erros | int | Linhas que falharam. |
qtd_ignorados | int | Linhas ignoradas. Default 0. |
status_final | str (enum) | success | partial | error (entre outros). |
data_hora_conclusao | datetime? | Momento da conclusão. |
HashDuplicadoInfo
Corpo do detail no 409 Conflict do upload quando o hash já existe.
| Campo | Tipo | Notas |
|---|---|---|
importacao_id_existente | int | Importação original com o mesmo arquivo. |
status_existente | str (enum) | Status da importação original. |
data_hora_criacao | datetime | Quando a original foi criada. |
AnalisarRegrasRequest
Body do POST /analisar-regras.
| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
mapeamento | MapeamentoColunas | sim | { comparacao: int, exportacao: int } (índices 0-based). |
campo_destino | str (enum) | não | conta_debito | conta_credito | historico. Quando informado, os duplicados consideram conteúdo e lado da conta; quando null (1ª análise), nenhum duplicado é reportado. |
AnalisarRegrasResponse
| Campo | Tipo | Notas |
|---|---|---|
colunas | ColunaDetectada[] | { indice, header } das colunas da planilha. |
amostra | AmostraLinha[] | Até 5 linhas { comparacao, exportacao }. |
total_linhas | int | Total de linhas na planilha. |
mapeamento_sugerido | MapeamentoColunas | Mapeamento inferido. |
duplicados | DuplicadoInfo[] | { comparacao, id_regra_existente }. |
contas_faltantes | str[] | Códigos de exportação sem Conta no cliente. |
planos_cliente | PlanoClienteInfo[] | { id, codigo_dominio, nome }. |
ConfirmarRegrasRequest
Body do POST /confirmar-regras.
| Campo | Tipo | Obrigatório | Notas |
|---|---|---|---|
mapeamento | MapeamentoColunas | sim | Índices das colunas comparação/exportação. |
campo_destino | str (enum) | sim | conta_debito | conta_credito | historico. |
campo_comparacao | str (enum) | não | Campo comparado pela condição. Default historico. |
modo_comparacao | str (enum) | não | Operador da condição. Default contem. |
id_estrutura | int? | não | Estrutura opcional para vincular as regras geradas. |
resolucao_duplicados | str (enum) | não | substituir | criar | ignorar. Default ignorar. |
resolucao_contas_faltantes | str (enum) | não | criar | ignorar. Default ignorar. |
id_plano_contas_novas | int? | não | Plano onde criar contas novas quando resolucao_contas_faltantes=criar e o cliente tem mais de um plano. |
ConfirmarRegrasResponse
| Campo | Tipo | Notas |
|---|---|---|
importacao_id | int | Importação processada. |
qtd_criadas | int | Regras criadas. |
qtd_atualizadas | int | Regras atualizadas. |
qtd_ignoradas | int | Regras ignoradas. |
qtd_erros | int | Linhas com erro. |
status_final | str (enum) | Status final da importação. |
erros | ErroLinhaRegra[] | { linha, mensagem }. |
data_hora_conclusao | datetime? | Momento da conclusão. |
Notas
- Toda resposta segue o envelope
{ success, message, data }(ou{ success: false, message, details }em erro). A exceção éGET /importacoes/{importacao_id}/arquivo, que devolve o binário do arquivo (FileResponse), eDELETE /importacoes/{importacao_id}, que retorna204 No Contentsem body. - O
POST /importacoes/uploadémultipart/form-data- não envie JSON. O único fluxo de criação de importação é este upload. - Não há task Celery neste domínio:
preview,confirmar,analisar-regras,confirmar-regrasesubstituirrodam o parser de forma síncrona na própria requisição. - Mapeamento de erros de negócio para HTTP: "não encontrado" →
404, "acesso negado" →403, conflitos de duplicidade/estado (duplicad,ja existe,ja foi processada,apenas importacoes) →409, demaisValueError→400. - Os tipos
contaseregras_conversoralimentam fluxos específicos:contasimporta plano/contas eregras_conversoralimentaanalisar-regras/confirmar-regras, que geram Regras de Lançamento.