Este é o contrato v1 dos títulos do ERP da Inteligência Financeira Consolidada. O parceiro (ERP, BPO ou plataforma) envia uma fotografia completa das contas a pagar e a receber de um perfil financeiro, com as liquidações recentes. A Malvo usa esses títulos no diagnóstico de liquidez e na conciliação assistida.
Rotas da F2. A carga é recebida por POST /financial-profiles/{id}/obligation-imports (JSON) e por POST /financial-profiles/{id}/obligation-imports/preview (CSV), atrás de chaves desligadas por padrão. As rotas, os códigos de resposta e a cadência estão em Títulos do ERP (F2); o upload de planilha, no guia CSV. O schema obligation-import-v1.schema.json (JSON Schema 2020-12) e o modelo obligation-import-v1.csv estão no repositório da documentação.
A carga é dado do parceiro e não é dado de Open Finance. Ela não vem de uma instituição participante, não depende de consentimento Open Finance e não aparece em /accounts, /transactions nem nos demais recursos de Open Finance. A finalidade e a base legal desses dados são do parceiro e ficam no contrato com ele, separadas do consentimento bancário. Revogar um consentimento bancário não apaga os títulos; o perfil só deixa de usar aquela fonte bancária nas novas análises.A Malvo não dá baixa no ERP. O ERP continua sendo a fonte de verdade do título e das baixas. Sugestões e confirmações de pagamento da Malvo nunca gravam nada no ERP. Se o parceiro registrar a baixa no sistema dele, devolve o payment_match_id na liquidação da próxima carga.

A carga

Uma carga é a fotografia completa dos títulos de um perfil para um recorte declarado:
  • todos os títulos em aberto, inclusive os vencidos, com vencimento até due_date_to;
  • os títulos liquidados ou cancelados desde closed_since, com as liquidações deles.
Para contas a pagar com completeness: "complete", due_date_to cobre pelo menos 30 dias a partir da data de source_as_of em America/Sao_Paulo, e closed_since volta pelo menos 7 dias antes de source_as_of. Contas a receber têm cobertura própria. Se ela faltar, o diagnóstico conservador continua possível quando a cobertura de contas a pagar for válida. A carga é validada inteira antes de substituir a carga ativa, numa troca atômica. Se falhar ou chegar incompleta, a carga ativa continua igual. Não há aceite parcial de linhas válidas. Um título que some de uma nova fotografia completa do mesmo recorte sai do conjunto ativo. A ausência não prova pagamento nem cancelamento. Uma carga finalizada com zero títulos significa “nenhum título em aberto no recorte declarado”, na data e no escopo da carga. Não significa que a empresa não tem dívidas.

O título

Sem contraparte, a correspondência entre débito e título tem menos evidência, mas o título é aceito.

Estado e valor em aberto

O estado tem de ser coerente com o valor em aberto: Juros, multa ou desconto que mudem o total devido entram como nova versão do título, com original_amount atualizado na origem.

Liquidações

Cada liquidação recente fica dentro do título. No CSV, ela vai numa linha própria ligada ao título. A soma das liquidações listadas não pode passar de original_amount - outstanding_amount. Como só vão as liquidações recentes, a soma pode ser menor.

payment_match_id

Quando a Malvo confirma que um débito bancário pagou um título, ela publica payment_match.confirmed com o payment_match_id. O parceiro decide se dá baixa no ERP. Se der, devolve o payment_match_id na liquidação correspondente da carga seguinte. A Malvo então absorve o ajuste por referência explícita (absorption_basis: "explicit_reference"), sem nova revisão. A devolução é recomendada, mas não obrigatória. Sem ela, a absorção pode ser inferida (inferred_exact) se a carga seguinte reduzir o valor em aberto exatamente pelo valor alocado, sem outra alteração. Nos demais casos, o ajuste vai para revisão (manual_review). Um payment_match_id que a Malvo não reconhece para o perfil não invalida a carga; a liquidação segue para inferência ou revisão.

Valores decimais

Valores monetários são string decimal, no mesmo padrão de valor da API Contas do Open Finance Brasil 2.5.1 para saldo bloqueado e limite: ^\d{1,15}\.\d{2,4}$. Até 15 dígitos inteiros, ponto como separador decimal, 2 a 4 casas, sem sinal e sem separador de milhar. Número JSON é recusado. A Malvo não arredonda na entrada e preserva as casas recebidas. Somas são exatas: 0.10 + 0.20 = 0.30 e 1000.0400 + 0.0001 = 1000.0401, sem passar por ponto flutuante. currency segue ^[A-Z]{3}$: BRL é aceito, brl é recusado. USD e outras moedas são recusadas na v1 e nunca entram numa soma em BRL.

Datas e instantes

  • Data civil (due_date, due_date_to): AAAA-MM-DD, sem hora e sem fuso. Vale como data no calendário da empresa; a Malvo interpreta janelas em America/Sao_Paulo.
  • Instante (source_as_of, source_updated_at, settled_at, closed_since): RFC 3339 com fuso obrigatório, como 2026-10-13T10:05:00-03:00 ou 2026-10-13T13:05:00Z. Instante sem fuso é recusado.

Idempotência e versões

O conteúdo é comparado campo a campo, com o texto exato dos valores. A ordem dos títulos e das liquidações não importa. API e CSV compartilham a identidade da origem e a ordem de versões: um upload não sobrescreve uma fotografia mais recente da mesma origem.

Validação

Um erro material impede a ativação da carga inteira. Códigos da validação do contrato: A recepção da F2 acrescenta códigos de identidade, de campo e de arquivo: Uma carga válida que não pode ser ativa fica not_activated com NOT_FINALIZED, PARTIAL_COVERAGE ou PREVIEW_EXPIRED em status_reason.

Modelo CSV

O CSV leva os mesmos campos, com cabeçalho em inglês. Cada linha tem um record_type:
  • obligation: um título. As colunas de liquidação ficam vazias.
  • settlement: uma liquidação, ligada ao título pelo external_obligation_id. As colunas do título ficam vazias. Toda liquidação precisa de uma linha obligation com o mesmo identificador no arquivo.
Os campos da carga (import_id, financial_profile_id, source_system, source_as_of, coverage, contagens e finalização) são informados no upload, com os mesmos nomes, e não no arquivo. Formato do arquivo: Modelo com os títulos do exemplo de absorção explícita:
obligation-import-v1.csv

Exemplos

Todos os dados abaixo são sintéticos. O CNPJ é um número de exemplo com dígito verificador válido.

Carga inicial

Em 12/10/2026, o ERP informa o título T-1001 de R$ 1.000,00 em aberto, o T-1002 liquidado por débito em 10/10 e o recebível R-2001 de 1000.0400, com 4 casas preservadas.
Carga inicial
Em 13/10, um débito de R600,00aparecenacontaconectadaeeˊconfirmadocomopagamentoparcialdo‘T−1001‘,com‘paymentmatchid‘‘3f2b8c1e−9d4a−4e6b−8a71−2c5d0e9f4b13‘.OERPaindamostraR 600,00 aparece na conta conectada e é confirmado como pagamento parcial do `T-1001`, com `payment_match_id` `3f2b8c1e-9d4a-4e6b-8a71-2c5d0e9f4b13`. O ERP ainda mostra R 1.000,00 em aberto. A reserva efetiva passa a R$ 400,00. A Malvo não altera o título nem o ERP.

Absorção explícita (AC-055)

Na carga de 14/10, o ERP informa a versão 8 do T-1001: partially_settled, R400,00emabertoeumaliquidac\ca~odeR 400,00 em aberto e uma liquidação de R 600,00 com o payment_match_id da confirmação.
Absorção explícita
A absorção usa a base explicit_reference, sem revisão. O ajuste separado vai a zero e a reserva efetiva continua R$ 400,00.

Absorção inferida (AC-056)

Mesma situação, mas o ERP não devolve o payment_match_id.
Absorção inferida
Há uma única alocação confirmada, de R600,00.OvaloremabertocaiuexatamentedeR 600,00. O valor em aberto caiu exatamente de R 1.000,00 para R400,00,aliquidac\ca~otemomesmovaloreeˊposterioraodeˊbito,evalororiginal,vencimento,moedaecontrapartena~omudaram.Aabsorc\ca~oeˊ‘inferredexact‘,registradacomoinferidaereversıˊvel.AreservaefetivacontinuaR 400,00, a liquidação tem o mesmo valor e é posterior ao débito, e valor original, vencimento, moeda e contraparte não mudaram. A absorção é `inferred_exact`, registrada como inferida e reversível. A reserva efetiva continua R 400,00. Se a carga de 14/10 reduzisse o valor em aberto para R450,00(liquidac\ca~odeR 450,00 (liquidação de R 550,00), o ajuste iria para revisão. A reserva não fica negativa e a confirmação antiga não é subtraída de novo. Estes exemplos ilustram o contrato. A regra completa de conciliação e de absorção está em Conciliação assistida (F2).

Dados pessoais

A contraparte pode ser pessoa física (CPF e nome). Envie esses campos só quando disponíveis e autorizados pelo seu contrato com a empresa. Sem eles a carga é aceita. Não use dado real em sandbox ou em testes. A retenção dos títulos segue a política acordada no contrato com o parceiro.

Fontes

  • API Contas do Open Finance Brasil, versão 2.5.1 (api_accounts_-_open_finance_brasil/2.5.1.yaml, lido em 10/10/2026): amount como string, padrão ^\d{1,15}\.\d{2,4}$ para bloqueado e limite, moeda ^[A-Z]{3}$, exemplo 1000.0400 / BRL. Títulos de ERP não fazem parte dessa API; este contrato só reusa o padrão de valor. A especificação não define arredondamento.
  • Lei nº 13.709/2018 (LGPD), art. 6º, I e III (finalidade e necessidade), art. 7º, art. 15, art. 16 e art. 18: planalto.gov.br.