Pular para o conteúdo principal
O Reporter permite gerar relatórios baseados em XML que seguem a estrutura oficial do CADOC, exatamente como exigido pelo Banco Central do Brasil (BACEN). Este guia apresenta a estrutura e a lógica utilizadas para gerar o relatório CADOC 4111 em XML.
Estes relatórios seguem o padrão COSIF e devem corresponder à estrutura XML definida pelo BACEN. Você pode adaptar a lógica ao seu próprio modelo de dados, mas o formato XML deve ser respeitado.

O que é o CADOC 4111?


O CADOC 4111 é um documento regulatório exigido pelo Banco Central do Brasil (BACEN) que reporta saldos diários de contas contábeis agrupados por código COSIF (Plano Contábil das Instituições do Sistema Financeiro Nacional).

O que o BACEN espera receber

  • Saldos consolidados por código COSIF
  • Data-base do relatório
  • CNPJ da instituição (primeiros 8 dígitos)
  • Tipo de remessa (I = Inclusão, S = Substituição)

Requisitos de envio

DocumentoPrazoCódigo STA
4111Dia seguinte à data de referência (ou próximo dia útil)ACOS011
O código STA identifica o tipo de documento no sistema de transmissão do BACEN. Use ACOS011 ao enviar o CADOC 4111.

Entendendo a estrutura de dados


Antes de construir o template, é essencial entender como os dados são organizados no ledger do Midaz.

Rotas de operação

As rotas de operação funcionam como classificadores contábeis. Cada rota possui:
  • Identificador único (id): Usado internamente para relacionar operações
  • Código COSIF (code): O código contábil de 10 dígitos que será reportado ao BACEN
Quando uma operação é registrada no Midaz, ela é associada a uma rota. Essa rota carrega o código COSIF correspondente.
Pense nas rotas como “rótulos contábeis” vinculados a cada operação, indicando em qual categoria do plano de contas aquele movimento deve ser classificado.

Operações

As operações representam movimentações financeiras no ledger. Cada operação contém:
  • Conta associada (account_id): Qual conta foi afetada
  • Rota (route): ID da rota/classificação contábil aplicada
  • Saldo após a operação (available_balance_after): O saldo da conta imediatamente após esta operação
  • Data e hora (created_at): Quando a operação ocorreu
O campo de saldo após a operação representa o saldo acumulado da conta naquele momento, não o valor da operação em si.

Relacionamento entre rotas e operações

Cada rota pode ter múltiplas operações vinculadas a ela ao longo do dia.

Estrutura do CADOC


Formato base

O relatório CADOC deve ser um arquivo XML e deve seguir a estrutura definida pelo BACEN:
<?xml version="1.0" encoding="UTF-8"?>
<documento codigoDocumento="4111" cnpj="99999999" dataBase="2025-11" tipoRemessa="I">
  <contas>
    <conta codigoConta="1000000009" saldoDia="99.99" />
    <conta codigoConta="1100000002" saldoDia="99.99" />
  </contas>
</documento>

Campos obrigatórios

Estes campos são obrigatórios e devem ser incluídos: <?xml version="1.0" encoding="UTF-8"?> Sempre inicia o arquivo. Define a versão do XML e a codificação para que o sistema saiba como ler o conteúdo. Tag <documento> Envolve toda a estrutura do CADOC e inclui:
CampoDescriçãoFormato
codigoDocumentoIdentificador fixo"4111"
cnpjPrimeiros 8 dígitos do CNPJNumérico, 8 posições
dataBaseData de referênciaYYYY-MM
tipoRemessaTipo de remessa"I" ou "S"
Se o seu primeiro envio foi rejeitado por erros, você ainda precisa usar "I" na próxima tentativa. Use "S" apenas para substituir dados previamente aprovados.
Tag <contas> Agrupa todas as entradas de contas do período de reporte. Tag <conta>
  • codigoConta: Código COSIF da rota de operação (10 dígitos numéricos)
  • saldoDia: Saldo consolidado em formato decimal (duas casas decimais)

Lógica de construção do template


Estrutura geral

O template segue uma lógica de agregação em dois níveis:
  1. Primeiro nível: Iterar por todas as rotas de operação disponíveis
  2. Segundo nível: Para cada rota, somar os saldos das operações vinculadas

Cabeçalho do documento

O cabeçalho do XML deve conter:
  • Código do documento: Identificador fixo 4111
  • CNPJ: Extraído dos dados da organização, limitado aos primeiros 8 dígitos
  • Data-base: Data de geração do relatório no formato YYYY-MM
  • Tipo de remessa: I para inclusão
Os dados da organização são obtidos da fonte de dados de onboarding do Midaz, especificamente da entidade de organização.

Iterando sobre as rotas

O template deve iterar por todas as rotas de operação registradas. Para cada rota:
  1. Verificar o código COSIF: Apenas rotas com um código COSIF válido devem gerar linhas no relatório
  2. Filtrar operações: Selecionar apenas as operações pertencentes àquela rota específica
  3. Calcular o saldo: Somar os saldos das operações filtradas
Nem todas as rotas possuem um código COSIF preenchido. Rotas sem código são usadas para controles internos e não devem aparecer no relatório regulatório.

Filtrando operações por rota

A associação entre operações e rotas é feita por meio do identificador da rota. O template usa esse identificador para:
  1. Acessar uma rota específica
  2. Encontrar todas as operações que referenciam essa rota
  3. Processar apenas essas operações na agregação
Ao construir o template, evite usar o mesmo nome para a variável de iteração e o campo de filtro, pois isso pode causar conflitos na interpretação do template.

Somando saldos

Para cada conjunto de operações de uma rota, o template soma os saldos disponíveis. O campo utilizado é o saldo disponível após cada operação. A função de agregação itera por todas as operações que atendem aos critérios de filtro (mesma rota) e acumula os valores do campo de saldo.

Usando o Reporter


Aqui está o template completo para gerar o CADOC 4111 no Reporter:
<?xml version="1.0" encoding="UTF-8"?>
<documento codigoDocumento="4111" cnpj="{{ midaz_onboarding.organization.0.legal_document|slice:":8" }}" dataBase="{% date_time "YYYY-MM" %}" tipoRemessa="I">
  <contas>
{%- for op_route in midaz_transaction.operation_route %}
{%- if op_route.code %}
    <conta codigoConta="{{ op_route.code }}" saldoDia="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
{%- endif %}
{%- endfor %}
  </contas>
</documento>

Detalhamento do código


Linha 1 - Declaração XML

<?xml version="1.0" encoding="UTF-8"?>
Cabeçalho XML padrão com codificação UTF-8.

Linha 2 - Elemento raiz <documento>

<documento codigoDocumento="4111" cnpj="{{ midaz_onboarding.organization.0.legal_document|slice:":8" }}" dataBase="{% date_time "YYYY-MM" %}" tipoRemessa="I">
  • codigoDocumento="4111": Identificador fixo do tipo de documento
  • cnpj: Acessa o documento legal da organização e extrai os primeiros 8 caracteres usando o filtro slice
  • dataBase: Gera a data atual no formato exigido pelo BACEN usando a tag date_time
  • tipoRemessa="I": Indica inclusão de dados

Linha 4 - Início do loop for

{%- for op_route in midaz_transaction.operation_route %}
  • op_route: Variável que recebe cada rota durante a iteração (nome escolhido para evitar conflito com o campo route nas operações)
  • midaz_transaction.operation_route: Coleção de todas as rotas de operação

Linha 5 - Condição if

{%- if op_route.code %}
Verifica se a rota possui um código COSIF preenchido. Rotas sem código são ignoradas.

Linha 6 - Elemento <conta>

<conta codigoConta="{{ op_route.code }}" saldoDia="{% sum_by midaz_transaction.operation by "available_balance_after" if route == op_route.id %}" />
  • codigoConta: Exibe o código COSIF da rota atual
  • saldoDia: Usa a tag sum_by para somar saldos, filtrando apenas as operações cuja rota corresponde ao identificador da rota atual (op_route.id)

Linhas 7-8 - Fechamento dos blocos

{%- endif %}
{%- endfor %}
Fecham a condição e o loop respectivamente.

Referência de tags e filtros

ElementoTipoFunção
{{ variable }}ExpressãoExibe o valor de uma variável
{% tag %}TagExecuta lógica (loop, condição, agregação)
|slice:":8"FiltroExtrai os primeiros 8 caracteres
for ... inTagItera por uma coleção
ifTagCondição de execução
sum_by ... by ... ifTagSoma valores com filtro condicional
date_timeTagGera data formatada

Considerações sobre filtro de data


Exemplo de requisição com filtro de data

Para gerar o CADOC 4111 para um dia específico, envie uma requisição POST /v1/reports com o header X-Organization-Id e o seguinte corpo:
{
  "templateId": "CADOC_4111_TEMPLATE_ID",
  "filters": {
    "midaz_transaction": {
      "operation": {
        "created_at": {
          "between": ["2025-11-11T00:00:00Z", "2025-11-11T23:59:59Z"]
        }
      }
    }
  }
}

Explicação dos campos

CampoDescrição
templateIdIdentificador do template CADOC 4111 registrado no Reporter
filters.midaz_transaction.operationIndica que o filtro será aplicado à coleção de operações
created_at.betweenFiltra operações criadas dentro do intervalo especificado
between[0]Data e hora de início (meia-noite do dia desejado)
between[1]Data e hora de fim (último segundo do dia desejado)
As datas devem estar no formato ISO 8601 com fuso horário UTC (Z).

Evolução do template e extração de saldos


Estamos trabalhando na evolução do nosso template principal para suportar agregação de saldos em conformidade com o BACEN CADOC 4111, que exige o saldo final do último dia útil. Enquanto essa funcionalidade está sendo desenvolvida, fornecemos uma versão alternativa para extrair esses saldos usando o template a seguir.

Template de extração

Este template auxiliar foi projetado para calcular saldos corretamente, garantindo a conformidade dos seus relatórios por meio dos seguintes passos:
  1. Agrupar operações por conta
  2. Ordenar registros por data e hora
  3. Selecionar o último registro de cada conta para obter o saldo final
  4. Somar os saldos finais por código COSIF
Com essa opção, você pode extrair as informações necessárias para o CADOC 4111 e transferi-las para o formato de layout exigido pelo BACEN. Este template pode ajudar se você já possui um provedor que constrói arquivos CADOC.

Exemplo de template de extração

account_id;account_alias;codigo_cosif;created_at;saldo_disponivel
{%- for op_route in midaz_transaction.operation_route %}
{%- if op_route.code %}
{%- for op in filter(midaz_transaction.operation, "route", op_route.id) %}
{{ op.account_id }};{{ op.account_alias }};{{ op_route.code }};{{ op.created_at }};{{ op.available_balance_after }}
{%- endfor %}
{%- endif %}
{%- endfor %}

Saída da extração

O template exporta todas as operações em formato CSV, contendo:
  • Identificador da conta
  • Alias da conta
  • Código COSIF
  • Data e hora da operação
  • Saldo disponível
Você pode importar este CSV em uma planilha ou no seu sistema de conciliação existente para processar os saldos finais.

Boas práticas para construção de templates


Nomenclatura de variáveis

Use nomes descritivos e únicos para variáveis de iteração, evitando conflitos com nomes de campos das entidades.

Validação de campos

Sempre verifique se campos opcionais possuem valores antes de utilizá-los. Campos vazios podem gerar linhas indesejadas no relatório.

Formato de data

O BACEN exige datas no formato YYYY-MM. Certifique-se de configurar o formato corretamente no template.

Tratamento do CNPJ

O CNPJ deve ser apresentado apenas com os primeiros 8 dígitos, sem formatação (pontos, barras ou hifens).

Resumo dos componentes


ComponenteFonte de dadosUso no template
CNPJOrganização (Onboarding)Cabeçalho do documento
Código COSIFRota de operação (Transaction)Identificador da conta
SaldoOperação (Transaction)Valor a ser agregado
Data-baseFunção de data atualCabeçalho do documento
Sempre valide o XML renderizado contra o schema do BACEN antes de enviar. A estrutura por si só não é suficiente — os dados devem refletir o ledger real da sua instituição.