Smart: Impostos Retidos
Endpoints da WebApiAlcance para os impostos retidos na fonte exportados do produto Smart. O domínio reúne quatro relatórios de origem (ir_pcc_inss, terceiros_pj, iss, servicos_tomados) numa única tabela, discriminados pelo campo tipo_relatorio - eles são quatro recortes do mesmo fato (um pagamento a fornecedor com tributo retido), então toda soma/apuração deve filtrar por tipo_relatorio, sob risco de contar a mesma retenção mais de uma vez. Diferente do restante da família Smart, este domínio tem chave natural (10 colunas) e uma rota de importação em lote idempotente, além do CRUD unitário padrão.
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/smart-impostos-retidosEscopos necessários
smart_impostos_retidos:read- listagem e busca por IDsmart_impostos_retidos:write- importação em lote, criação avulsa, atualização e exclusão
O escopo é derivado do prefixo público da rota: /smart-impostos-retidos vira o recurso smart_impostos_retidos (hífen → underscore), e o método HTTP define a ação (read para GET, write para POST/PUT/DELETE). Os quatro relatórios de origem compartilham o mesmo prefixo e, portanto, os mesmos 2 escopos - eles não são domínios separados.
Ordem das rotas
A rota literal POST /smart-impostos-retidos/importar é declarada antes das rotas com parâmetro de path para que nenhuma delas a capture. Ela não cria um escopo próprio: continua exigindo smart_impostos_retidos:write.
Endpoints
POST /smart-impostos-retidos/importar
Importa uma planilha inteira em uma única requisição, de forma idempotente: reimportar o mesmo lote não cria linhas novas (upsert pela chave natural). Em conflito, atualiza apenas as colunas não-chave - id e data_hora_criacao são preservados. Erros de validação de negócio recusam o lote inteiro (nunca sucesso parcial).
Parâmetros
Este endpoint não recebe parâmetros de rota ou query. O corpo é um ImportacaoLoteRequest.
Request
{
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"itens": [
{
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5000.0,
"valor_emissao": 5000.0,
"ipg_irrf": 75.0,
"ipg_inss": 550.0,
"indic": "IRRF",
"ipg_dt_pgto": "2026-04-10T00:00:00",
"mcc_irrf": 75.0,
"mcc_inss": 550.0
}
]
}Response 200 OK
{
"status": "success",
"message": "Importação concluída",
"data": {
"total": 1,
"criados": 1,
"atualizados": 0,
"duplicados_no_lote": 0,
"avisos": []
}
}Erros de validação (ex.: colunas mcc_* divergentes das ipg_* correspondentes, itens com a mesma chave natural e payloads diferentes, falha de persistência) respondem {"message": "<texto>"} com 422 Unprocessable Entity e nada é gravado.
Escopo: smart_impostos_retidos:write
GET /smart-impostos-retidos/
Lista os impostos retidos, com filtro opcional por CNPJ e por tipo_relatorio, e paginação.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
cnpj | string | query | não | Filtra por CNPJ do cliente. |
tipo_relatorio | string | query | não | Filtra pelo pivot de origem: ir_pcc_inss, terceiros_pj, iss ou servicos_tomados. Recomendado em toda soma/apuração. |
limit | int | query | não | Itens por página. 1..500. Default 100. |
offset | int | query | não | Offset de paginação. >= 0. Default 0. |
Request
Sem corpo de requisição.
Response 200 OK
{
"status": "success",
"message": "Impostos retidos recuperados com sucesso",
"data": [
{
"id": 4102,
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"cfg_emp": "01 - HOSPITAL EXEMPLO",
"gcc_descr": "FORNECEDORES DIVERSOS",
"cde_nome": "FORNECEDOR EXEMPLO LTDA",
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5000.0,
"valor_emissao": 5000.0,
"valor_pagamento": 5000.0,
"valor_bruto": null,
"ipg_irrf": 75.0,
"ipg_inss": 550.0,
"ipg_iss": 0.0,
"ipg_imp_pis": 32.5,
"ipg_imp_cofins": 150.0,
"ipg_imp_cssl": 50.0,
"indic": "IRRF",
"indic_1": "SERV",
"indic_2": "Titulos",
"fis_jur": "J",
"cfo": "6.202",
"conta_contabil": "2.1.3.01.001",
"banco": "BANCO EXEMPLO",
"ipg_dt_pgto": "2026-04-10T00:00:00",
"data_hora_criacao": "2026-04-11T08:00:00"
}
]
}Se nenhum registro casar com o filtro, data volta [] com 200 OK e message: "Nenhum imposto retido encontrado.".
Escopo: smart_impostos_retidos:read
GET /smart-impostos-retidos/{registro_id}
Busca um imposto retido pelo ID.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
registro_id | int | path | sim | ID do imposto retido. |
Request
Sem corpo de requisição.
Response 200 OK
{
"status": "success",
"message": "Imposto retido recuperado com sucesso",
"data": {
"id": 4102,
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"cfg_emp": "01 - HOSPITAL EXEMPLO",
"gcc_descr": "FORNECEDORES DIVERSOS",
"cde_nome": "FORNECEDOR EXEMPLO LTDA",
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5000.0,
"valor_emissao": 5000.0,
"valor_pagamento": 5000.0,
"valor_bruto": null,
"ipg_irrf": 75.0,
"ipg_inss": 550.0,
"ipg_iss": 0.0,
"ipg_imp_pis": 32.5,
"ipg_imp_cofins": 150.0,
"ipg_imp_cssl": 50.0,
"indic": "IRRF",
"indic_1": "SERV",
"indic_2": "Titulos",
"fis_jur": "J",
"cfo": "6.202",
"conta_contabil": "2.1.3.01.001",
"banco": "BANCO EXEMPLO",
"ipg_dt_pgto": "2026-04-10T00:00:00",
"data_hora_criacao": "2026-04-11T08:00:00"
}
}Quando o ID não existe, responde {"message": "Imposto retido não encontrado."} com 404 Not Found.
Escopo: smart_impostos_retidos:read
POST /smart-impostos-retidos/
Cria um registro avulso (correção pontual - a carga em massa é POST /smart-impostos-retidos/importar).
Parâmetros
Este endpoint não recebe parâmetros de rota ou query. O corpo é um SmartImpostosRetidosCreate.
Request
{
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5000.0,
"valor_emissao": 5000.0,
"ipg_irrf": 75.0,
"ipg_inss": 550.0,
"indic": "IRRF",
"ipg_dt_pgto": "2026-04-10T00:00:00"
}Response 201 Created
{
"status": "success",
"message": "Imposto retido criado com sucesso",
"data": {
"id": 4102,
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5000.0,
"valor_emissao": 5000.0,
"valor_pagamento": null,
"valor_bruto": null,
"ipg_irrf": 75.0,
"ipg_inss": 550.0,
"ipg_iss": null,
"ipg_imp_pis": null,
"ipg_imp_cofins": null,
"ipg_imp_cssl": null,
"indic": "IRRF",
"indic_1": null,
"indic_2": null,
"fis_jur": null,
"cfo": null,
"conta_contabil": null,
"banco": null,
"ipg_dt_pgto": "2026-04-10T00:00:00",
"data_hora_criacao": "2026-04-11T08:00:00"
}
}Como a tabela tem chave natural, um POST repetido com os mesmos 10 campos-chave responde {"message": "<texto>"} com 409 Conflict.
Escopo: smart_impostos_retidos:write
PUT /smart-impostos-retidos/{registro_id}
Atualiza um imposto retido (update parcial). Não aceita nenhum dos 10 campos da chave natural (ver SmartImpostosRetidosUpdate) - mover um registro de tenant/pivot por HTTP não é permitido.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
registro_id | int | path | sim | ID do imposto retido. |
O corpo é um SmartImpostosRetidosUpdate.
Request
{ "ipg_valor": 5200.0, "ipg_irrf": 78.0 }Response 200 OK
{
"status": "success",
"message": "Imposto retido atualizado com sucesso",
"data": {
"id": 4102,
"tipo_relatorio": "ir_pcc_inss",
"cnpj": "12345678000199",
"emp_cgc": "98765432000188",
"cpg_credor": "FORNECEDOR EXEMPLO LTDA",
"cpg_serie": "1",
"cpg_num": 7788,
"cpg_doc": "7788",
"cpg_dt_doc_emiss": "2026-04-01T00:00:00",
"ipg_parc": 1,
"total_parc": 1,
"ipg_valor": 5200.0,
"valor_emissao": 5000.0,
"valor_pagamento": null,
"valor_bruto": null,
"ipg_irrf": 78.0,
"ipg_inss": 550.0,
"ipg_iss": null,
"ipg_imp_pis": null,
"ipg_imp_cofins": null,
"ipg_imp_cssl": null,
"indic": "IRRF",
"indic_1": null,
"indic_2": null,
"fis_jur": null,
"cfo": null,
"conta_contabil": null,
"banco": null,
"ipg_dt_pgto": "2026-04-10T00:00:00",
"data_hora_criacao": "2026-04-11T08:00:00"
}
}Quando o ID não existe, responde {"message": "Imposto retido não encontrado."} com 404 Not Found.
Escopo: smart_impostos_retidos:write
DELETE /smart-impostos-retidos/{registro_id}
Remove um imposto retido.
Parâmetros
| Parâmetro | Tipo | Local | Obrigatório | Descrição |
|---|---|---|---|---|
registro_id | int | path | sim | ID do imposto retido. |
Request
Sem corpo de requisição.
Response 200 OK
{
"status": "success",
"message": "Imposto retido removido com sucesso",
"data": null
}Quando o ID não existe, responde {"message": "Imposto retido não encontrado."} com 404 Not Found.
Escopo: smart_impostos_retidos:write
Schemas
Vocabulário tipo_relatorio
| Valor | Origem |
|---|---|
ir_pcc_inss | 1 linha por parcela x grupo de tributo (indic). |
terceiros_pj | 1 linha por parcela. |
iss | 1 linha por parcela. |
servicos_tomados | 1 linha por documento (sem série/número/parcela). |
SmartImpostosRetidosCreate
Corpo do POST /smart-impostos-retidos/. model_config usa extra="forbid": qualquer campo fora desta lista responde 422.
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
tipo_relatorio | string | sim | Um dos 4 valores do vocabulário acima. |
ipg_dt_pgto | datetime | sim | Data do pagamento. Parte da chave natural. |
cnpj | string | não | Máx. 30. CNPJ do cliente (quem paga); normalizado pela API. |
cfg_emp | string | não | Máx. 300. Identificação da empresa na origem. |
gcc_descr | string | não | Máx. 300. Descrição do grupo/conta contábil de origem. |
cde_nome | string | não | Máx. 300. Nome de referência do credor na origem. |
emp_cgc | string | não | Máx. 30. CNPJ do credor/fornecedor (quem recebe); gravado como veio, sem normalização. |
cpg_credor | string | não | Máx. 300. Nome do credor/fornecedor. |
cpg_serie | string | não | Máx. 20. Série do documento de pagamento. Parte da chave natural. |
cpg_num | int | não | Número do documento de pagamento. Parte da chave natural. |
cpg_doc | string | não | Máx. 20. Identificador do documento na origem (número, data DDMMAAAA ou competência MM/AAAA, conforme o relatório). Parte da chave natural. |
cpg_dt_doc_emiss | datetime | não | Data de emissão do documento. Parte da chave natural. |
ipg_parc | int | não | Número da parcela. Parte da chave natural. |
total_parc | int | não | Total de parcelas do documento. |
ipg_valor | Decimal | não | Valor da parcela. |
valor_emissao | Decimal | não | Valor na emissão (relatórios ir_pcc_inss/terceiros_pj). |
valor_pagamento | Decimal | não | Valor efetivamente pago. |
valor_bruto | Decimal | não | Valor do documento (só servicos_tomados preenche - não confundir com ipg_valor, que é a parcela). |
ipg_irrf | Decimal | não | IRRF retido. |valor| < 10.000.000.000.000. |
ipg_inss | Decimal | não | INSS retido. Mesmo limite de faixa. |
ipg_iss | Decimal | não | ISS retido. Mesmo limite de faixa. |
ipg_imp_pis | Decimal | não | PIS retido. Mesmo limite de faixa. |
ipg_imp_cofins | Decimal | não | COFINS retido. Mesmo limite de faixa. |
ipg_imp_cssl | Decimal | não | CSLL retido. Mesmo limite de faixa. |
indic | string | não | Máx. 20. Grupo/classificador do tributo. Parte da chave natural. |
indic_1 | string | não | Máx. 20. Classificador adicional de origem. |
indic_2 | string | não | Máx. 100. Tipo de compromisso, sem acento (ex.: Titulos). |
fis_jur | string | não | Máx. 20. Natureza jurídica do credor (J/F). |
cfo | string | não | Máx. 300. Código fiscal de operação. |
conta_contabil | string | não | Máx. 300. Conta contábil de destino. |
banco | string | não | Máx. 100. Banco do pagamento. |
SmartImpostosRetidosUpdate
Corpo do PUT /smart-impostos-retidos/{registro_id}. extra="forbid". Não aceita os 10 campos da chave natural: cnpj, tipo_relatorio, emp_cgc, cpg_serie, cpg_num, cpg_doc, cpg_dt_doc_emiss, ipg_parc, ipg_dt_pgto, indic.
| Campo permitido | Tipo | Campo permitido | Tipo |
|---|---|---|---|
cfg_emp | string | ipg_imp_pis | Decimal |
gcc_descr | string | ipg_imp_cofins | Decimal |
cde_nome | string | ipg_imp_cssl | Decimal |
cpg_credor | string | indic_1 | string |
total_parc | int | indic_2 | string |
ipg_valor | Decimal | fis_jur | string |
valor_emissao | Decimal | cfo | string |
valor_pagamento | Decimal | conta_contabil | string |
valor_bruto | Decimal | banco | string |
ipg_irrf | Decimal | ipg_inss | Decimal |
ipg_iss | Decimal |
SmartImpostosRetidosRead
Retorno de leitura. Estende SmartImpostosRetidosCreate com id e data_hora_criacao.
| Campo | Tipo | Observações |
|---|---|---|
id | int | Identificador do registro. |
data_hora_criacao | datetime | Data/hora de criação do registro. |
| (demais campos) | - | Todos os campos de SmartImpostosRetidosCreate, incluindo ipg_dt_pgto. |
ImportacaoLoteRequest
Corpo do POST /smart-impostos-retidos/importar. extra="forbid". O envelope é a autoridade sobre tipo_relatorio/cnpj: o que vier no item é sobrescrito.
| Campo | Tipo | Obrigatório | Observações |
|---|---|---|---|
tipo_relatorio | string | sim | Um dos 4 valores do vocabulário acima. |
cnpj | string | sim | 1 a 30 caracteres. CNPJ do cliente da planilha. |
itens | List[ImportacaoItem] | sim | 1 a 5000 itens. |
ImportacaoItem aceita os mesmos campos de SmartImpostosRetidosCreate (exceto tipo_relatorio, que é opcional aqui pois vem do envelope), mais:
- Aliases de nome por relatório:
ir/inss/iss/pis/cofins/csllsão aceitos como sinônimos deipg_irrf/ipg_inss/ipg_iss/ipg_imp_pis/ipg_imp_cofins/ipg_imp_cssl;tipo_compromissoé sinônimo deindic_2;cpg_fis_jur/emp_fis_jursão sinônimos defis_jur. - Os 7 campos
mcc_irrf,mcc_inss,mcc_iss,mcc_imp_pis,mcc_imp_cofins,mcc_imp_cssl,mcc_valor_emissao(todosDecimal, opcionais) são aceitos e comparados com as colunasipg_*/valor_emissaocorrespondentes, mas não são persistidos. Divergência entre ummcc_*e a coluna correspondente recusa o lote inteiro com422.
ImportacaoResultado
Corpo de data na resposta de sucesso do POST /smart-impostos-retidos/importar.
| Campo | Tipo | Observações |
|---|---|---|
total | int | Total de itens únicos processados (após dedup intra-lote). |
criados | int | Quantos viraram linha nova. |
atualizados | int | Quantos já existiam e tiveram colunas não-chave atualizadas. |
duplicados_no_lote | int | Itens com a mesma chave natural e payload idêntico, colapsados. |
avisos | List[string] | Mensagens informativas (ex.: sobre itens colapsados). |
Notas
- Sucesso segue o envelope
{ status: "success", message, data }. Erros levantados comoHTTPException(404, 409, 422) respondem{ message }com o código HTTP correspondente. - A mesma retenção pode estar gravada até 4 vezes (uma por
tipo_relatorio). Toda soma/agregação deve filtrar portipo_relatorioemGET /smart-impostos-retidos/, sob risco de contar o mesmo valor múltiplas vezes. - Os 10 campos monetários (
ipg_valor,valor_emissao,valor_pagamento,valor_bruto,ipg_irrf,ipg_inss,ipg_iss,ipg_imp_pis,ipg_imp_cofins,ipg_imp_cssl) sãoDecimalno schema eDECIMAL(15,2)no banco - divergindo de propósito do restante da família Smart, que usafloat, porque este é o único domínio Smart cujo dado alimenta apuração de tributo. valor_bruto(documento) eipg_valor(parcela) não são a mesma coisa e não devem ser somados/fundidos - só coincidem quando o documento tem parcela única.- A chave natural (
cnpj,tipo_relatorio,emp_cgc,cpg_serie,cpg_num,cpg_doc,cpg_dt_doc_emiss,ipg_parc,ipg_dt_pgto,indic) é a base da idempotência dePOST /smart-impostos-retidos/importare do conflito409doPOST /smart-impostos-retidos/. POST /smart-impostos-retidos/importaraceita no máximo 5000 itens por chamada; reimportar o mesmo lote não duplica linhas.