DCTFWeb: Catálogos

Dois endpoints de leitura pura que expõem o vocabulário da DCTFWeb: as categorias de declaração e os sistemas de origem da guia. São os catálogos que a interface consome para montar seletores, rótulos e regras de campo condicional sem reimplementar as tabelas em TypeScript.

Nenhum dos dois toca o Serpro, o banco ou qualquer emissão - são estáticos por natureza, porque o domínio é definido pela Receita e não é configurável por cliente. Vêm por HTTP, e não hard-coded no front, para que rótulo, descrição e ressalva possam ser corrigidos sem redeploy do frontend.

Ambos exigem autenticação. Veja Autenticação para o fluxo de API Key. O Swagger oficial está em api.contabilidadealcance.com.br/docs (tag DCTFWeb: Catálogos).

Base path

/api/v1/dctfweb

Os dois caminhos são completos, sem sub-prefixo: /dctfweb/categorias e /dctfweb/sistemas-origem.

Escopos necessários

  • dctfweb:read - as duas rotas são GET.

Estes caminhos nasceram sob o prefixo consolidado: não existe alias legado para eles, e nunca existiram sob /dctfweb-guias, /dctfweb-recibos ou /integra-contador/*.

Endpoints

GET /dctfweb/categorias

Catálogo das 7 categorias de declaração da DCTFWeb, ordenado por código.

Parâmetros

Nenhum - sem parâmetros de rota, query ou corpo.

Response 200 OK

{
  "status": "success",
  "message": "Categorias da DCTFWeb recuperadas com sucesso!",
  "data": [
    {
      "codigo": 40,
      "rotulo": "GERAL_MENSAL",
      "nome": "Mensal — Pessoa Jurídica",
      "descricao": "A declaração do dia a dia da empresa. Use no fechamento de cada competência para declarar as contribuições previdenciárias e as retenções apuradas naquele mês.",
      "exigeMesPA": true,
      "camposExtras": [],
      "habilitadaTransmissao": true,
      "observacao": ""
    },
    {
      "codigo": 41,
      "rotulo": "GERAL_13o_SALARIO",
      "nome": "13º salário — Pessoa Jurídica",
      "descricao": "Declaração exclusiva da folha do décimo terceiro salário. É ANUAL: não se informa mês de apuração, apenas o ano.",
      "exigeMesPA": false,
      "camposExtras": [],
      "habilitadaTransmissao": true,
      "observacao": "Não informe o mês de apuração — esta declaração é anual."
    }
  ]
}

O data é uma lista, não um objeto.

Escopo: dctfweb:read

Campos de cada item

CampoTipoObservações
codigointCódigo numérico do contrato. O Serpro aceita ele ou o rotulo.
rotulostrRótulo técnico, como vai no campo categoria da requisição ao Serpro.
nomestrNome amigável em pt-BR, para exibição.
descricaostrQuando usar, em linguagem de contador.
exigeMesPAboolmesPA é obrigatório? false só nas categorias de 13º (41 e 51), que são anuais.
camposExtrasList[str]Campos que existem nesta categoria, além de anoPA/mesPA. Vazio na maioria.
habilitadaTransmissaoboolA transmissão (TRANSDECLARACAO310) aceita esta categoria?
observacaostrRessalva operacional exibível ao usuário. String vazia quando não há.

As 7 categorias

codigorotulonomeexigeMesPAcamposExtras
40GERAL_MENSALMensal — Pessoa Jurídicatrue-
41GERAL_13o_SALARIO13º salário — Pessoa Jurídicafalse-
44AFERICAOAferição de obra (CNO)true["cnoAfericao"]
45ESPETACULO_DESPORTIVOEspetáculo desportivotrue["diaPA"]
46RECLAMATORIA_TRABALHISTAReclamatória trabalhistatrue["numProcReclamatoria"]
50PF_MENSALMensal — Pessoa Físicatrue-
51PF_13o_SALARIO13º salário — Pessoa Físicafalse-

Todas retornam habilitadaTransmissao: true hoje.

Regras de campo condicional

O que a interface precisa derivar do catálogo, sem if por categoria espalhado no código:

  • mesPA - obrigatório em todas, exceto nas categorias de 13º salário (41 e 51), que são anuais: nelas se informa apenas anoPA. É exatamente o que exigeMesPA: false sinaliza.
  • diaPA - existe somente na categoria 45 (espetáculo desportivo). A apuração é por dia do evento.
  • numProcReclamatoria - existe somente na categoria 46 (reclamatória trabalhista). É o número do processo na Justiça do Trabalho.
  • cnoAfericao - existe somente na categoria 44 (aferição de obra). É o número da obra (CNO).

Cada um desses campos aparece em camposExtras da categoria correspondente - prefira ler camposExtras a repetir a regra no cliente.

`RETIFICACAO` e `RECLAMATORIA` não existem

Se seu código ainda tem esses dois valores, remova-os: nenhum dos dois faz parte do contrato. Não há categoria de retificação - retificar é indicado dentro do XML, na tag indRetificacao, e não trocando a categoria da declaração. O valor correto para reclamatória trabalhista é RECLAMATORIA_TRABALHISTA (código 46).

`observacao` da categoria 44 traz uma ressalva em aberto

A observação devolvida para AFERICAO (44) registra que o envio do cnoAfericao na transmissão ainda não foi confirmado junto à Receita: o campo está documentado nos serviços de consulta e de emissão de guia, mas não na página oficial do TRANSDECLARACAO310. A categoria segue com habilitadaTransmissao: true - a validação será empírica. Trate esse texto como aviso ao usuário, não como contrato fechado.

GET /dctfweb/sistemas-origem

Catálogo dos 5 sistemas de origem da guia (idsSistemaOrigem), mais os presets sugeridos e a observação sobre omissão do campo.

Parâmetros

Nenhum - sem parâmetros de rota, query ou corpo.

Response 200 OK

{
  "status": "success",
  "message": "Sistemas de origem recuperados com sucesso!",
  "data": {
    "sistemas": [
      {
        "codigo": 1,
        "rotulo": "eSocial",
        "nome": "eSocial (folha de pagamento)",
        "descricao": "Traz para a guia as contribuições previdenciárias apuradas na folha enviada ao eSocial: INSS descontado dos segurados, contribuição patronal, RAT/FAP e Terceiros, incluindo 13º salário e rescisões.",
        "presets": ["pessoal"]
      },
      {
        "codigo": 8,
        "rotulo": "MIT",
        "nome": "MIT — Módulo de Inclusão de Tributos",
        "descricao": "Traz para a guia os débitos não previdenciários informados no MIT dentro da DCTFWeb (IRPJ, CSLL, PIS, COFINS, IPI, IOF e demais tributos federais da apuração fiscal).",
        "presets": ["fiscal"]
      }
    ],
    "presets": {
      "pessoal": [1, 6, 7],
      "fiscal": [8]
    },
    "observacao": "Campo opcional no Integra Contador: quando informado, a guia é gerada contendo apenas as receitas dos sistemas de origem escolhidos; quando omitido, a guia sai com todas as receitas."
  }
}

Escopo: dctfweb:read

Estrutura do data

CampoTipoObservações
sistemasList[object]Os 5 sistemas, na ordem do catálogo.
presetsDict[str, List[int]]Conjuntos sugeridos de códigos, por nome de preset.
observacaostrSemântica oficial do campo opcional - ver o aviso abaixo.

Cada item de sistemas:

CampoTipoObservações
codigointO inteiro que vai no payload do GERARGUIA31.
rotulostrNome técnico, exatamente como na documentação do Integra Contador.
nomestrNome amigável em pt-BR, para a tela.
descricaostrO que passa a entrar na guia ao incluir o sistema.
presetsList[str]Presets em que este código já vem marcado. Vazio quando nenhum.

Os 5 sistemas

codigorotulonomepresets
1eSocialeSocial (folha de pagamento)["pessoal"]
5SeroSero (aferição de obra de construção civil)[]
6Reinf CPEFD-Reinf — contribuição previdenciária["pessoal"]
7Reinf RETEFD-Reinf — retenções na fonte (série R-4000)["pessoal"]
8MITMIT — Módulo de Inclusão de Tributos["fiscal"]

Não há códigos 2, 3 e 4 - a numeração do domínio oficial é descontínua.

Presets

PresetCódigosCorresponde a
pessoal[1, 6, 7]eSocial + Reinf CP + Reinf RET - o conjunto do fluxo de folha.
fiscal[8]MIT - o conjunto do fluxo fiscal.

São sugestões de valor inicial para a tela, espelhando o que os fluxos de emissão já enviam hoje ([1, 6, 7] na variante eSocial, [8] na variante MIT). Não são restrições: qualquer subconjunto não vazio dos 5 códigos é válido, inclusive combinando pessoal e fiscal na mesma guia - o próprio exemplo oficial do Integra Contador mistura eSocial e MIT ([1, 8]).

Omitir o campo NÃO é o mesmo que enviar lista vazia

Esta é a regra mais fácil de errar ao montar a interface, e ela vem escrita na própria observacao do catálogo:

  • Campo omitido (ausente do payload) → a Receita gera a guia com TODAS as receitas. É um estado legítimo e é o default.
  • Lista vazia ([]) → erro. Uma guia de nenhuma origem não existe. A API recusa antes de chegar ao Serpro, com a mensagem: "'idsSistemaOrigem' não pode ser uma lista vazia — informe ao menos um sistema de origem, ou omita o campo para gerar a guia com todas as receitas."

Na prática: um seletor "todas as origens" deve não enviar o campo, e nunca enviar []. Desmarcar todas as opções não pode virar [] no payload - ou é "todas" (omitir), ou é bloqueado na tela.

Demais regras de validação

Quando o campo é informado, a lista é validada de forma fail-closed antes de qualquer chamada ao Serpro - o valor segue cru para a Receita, e o erro do gateway (APIGUIA03 — IdSistemaOrigem inválido: X) é opaco. As regras:

RegraMotivo
Precisa ser lista (não string)"167" iteraria como ["1", "6", "7"] e passaria por acidente.
Não pode ser vaziaVer o aviso acima - lista vazia ≠ campo omitido.
Cada item precisa ser inteiro estritoSem coerção: "1", true e 1.0 são recusados. Em Python True é int e viraria o código 1 (eSocial) em silêncio.
Cada código precisa estar no domínio oficialCódigos aceitos: 1, 5, 6, 7, 8.
Não pode repetir códigoCada sistema de origem se informa uma única vez.

Violações resultam em 422, com a mensagem em pt-BR e a lista dos códigos aceitos.

A tipagem é ESTRITA - o Pydantic não coage aqui

O campo é declarado como lista de inteiros estritos, e não de int. Isso desliga a coerção que o Pydantic aplicaria por padrão - justamente o comportamento que a maioria dos integradores espera. Envie inteiros JSON, sem aspas: [1, 6, 7], nunca ["1", "6", "7"].

Onde esse campo é usado hoje

Dois endpoints aceitam idsSistemaOrigem vindo do cliente:

  • POST /dctfweb/emissao/guias/emitir - a emissão sob demanda, em que o campo define as origens das receitas da guia emitida.
  • Transmissão - em que ele define as origens da guia encadeada, emitida logo após a declaração ser entregue.

As demais rotas de emissão (baixar-todas e baixar-mensal/*) enviam listas fixas ([1, 6, 7] ou [8]), definidas no código de cada variante e não parametrizáveis.

Notas

  • Os dois endpoints são GET puros: não leem banco, não chamam o Serpro e não têm efeito colateral. São seguros para cachear no cliente por sessão.
  • As categorias vêm da mesma fonte de verdade que alimenta as regras condicionais dos schemas de emissão e transmissão - o catálogo não é uma segunda tabela que possa divergir.
  • Os textos de nome, descricao e observacao são apenas de exibição: nenhuma lógica os lê. Podem ser reescritos sem impacto funcional.
  • Prefira consumir exigeMesPA e camposExtras a codificar as regras por categoria no cliente - foi para isso que o catálogo foi exposto.