Skip to content

Financeiro da instituição ​

API de integração do financeiro da própria instituição: contas a pagar, contas a receber, conciliação bancária e tesouraria. Serve para ligar o ERP, a contabilidade, o BI ou outro sistema da instituição ao módulo financeiro, sem passar pela tela.

Público desta página

Estes endpoints NÃO são para parceiros que operam contas de clientes. Eles só respondem para a credencial de um parceiro marcado pela instituição como integração própria. Uma credencial comum recebe 403 finance_integration_not_enabled mesmo que alguém lhe conceda os escopos abaixo por engano.

Como o acesso é decidido ​

  1. OAuth2 client_credentials, igual ao restante do canal (POST /api/partner/v1/oauth/token).
  2. Escopo por rota. Leitura e escrita são escopos separados por domínio; uma chave de leitura nunca escreve.
  3. Parceiro marcado como integração da instituição. A instituição dos dados é a do parceiro dono da credencial. Nada no corpo, na URL ou em cabeçalho escolhe a instituição.
  4. Tudo é auditado com a credencial como autor (partner_api:<client_id>). Campo de autor no corpo é recusado com 403.
EscopoPermite
finance_master:readConsultar os cadastros vinculados à própria fonte
finance_master:writeReceber versões externas de cadastros, respeitando autoridade por campo
finance_ap:readPosição, aging e parcelas de contas a pagar
finance_ap:writeCriar título a pagar
finance_ar:readContas a receber na data de corte, recebimentos e estornos
finance_ar:writeCriar título a receber e registrar recebimento
finance_reconciliation:readPainel e pendentes da conciliação
finance_reconciliation:writeImportar lançamentos de extrato
finance_treasury:readFluxo de caixa projetado e remessas de pagamento
finance_accounting:readListar e baixar os lotes de lançamentos contábeis para o ERP
finance_accounting:writeConfirmar o recebimento de um lote pelo ERP

O que a API não faz, de propósito ​

Aprovar título, liberar lote de pagamento, gerar remessa ao banco, conciliar manualmente e fechar o dia exigem uma segunda pessoa nomeada e continuam na tela. Um título criado pela API entra na alçada normal da instituição e só é pago depois de aprovado por quem tem alçada.

Escrita: idempotência ​

Toda escrita exige o cabeçalho Idempotency-Key (8 a 180 caracteres). Repetir a mesma chave com o mesmo conteúdo devolve o mesmo resultado. Na criação de AP/AR, a resposta também inclui x-idempotent-replay: true; os demais comandos não dependem desse cabeçalho para indicar sucesso. A mesma chave com conteúdo diferente devolve 409.

Valores ​

Há duas escalas, e o nome do campo diz qual é:

  • campos terminados em _minor e os campos amount, valor e saldo do contas a pagar, extrato, fluxo de caixa e remessas: centavos (inteiro). R$ 456,00 é 45600.
  • campos terminados em _base_units (criação de título a receber e registro de recebimento): décimos de milésimo de real (inteiro, ou o mesmo inteiro como texto de dígitos). R$ 1,00 é 10000; R$ 456,00 é 4560000. Os relatórios do contas a receber (aging e receipts) já devolvem em centavos, nos campos _minor.

A especificação OpenAPI (GET /api/openapi) descreve cada corpo de requisição e de resposta com tipo, escala e exemplo, e as respostas reais são validadas contra ela na suíte do produto.

Relatórios: regras que o integrador precisa conhecer ​

  • Recebimentos e estornos (receivables/receipts): cada fato entra no período em que ocorreu. received_minor soma os recebimentos com data no período pelo valor bruto, mesmo que tenham sido estornados depois; reversed_minor soma os estornos com data no período, seja qual for a data do recebimento original (eles vêm na lista reversals); net_minor é a diferença. O relatório de um mês fechado não muda quando um estorno acontece meses depois.
  • Aging do contas a receber (receivables/aging): a chave de agrupamento por devedor (rows[].key, detail[].debtor_key) é um identificador opaco e estável dentro da instituição (dbt_...). Não é o documento nem derivado público dele. Nenhuma resposta traz hash, impressão digital de comando ou chave de idempotência.
  • Fluxo de caixa (treasury/cash-flow): com account_id, o previsto e o realizado são só daquela conta. Na próxima publicação registrada no changelog, campos monetários _minor usarão número JSON entre -9007199254740991 e 9007199254740991, e texto decimal exato fora desse intervalo, inclusive agregados acima de bigint. Exemplo: "18446744073709551614" centavos. Escala, sinais e null de saldo ausente são conservados; IDs/contagens não mudam. O integrador deve calcular e formatar esses textos como inteiros exatos.

Recebimento que cita um crédito PIX ​

Quando a reference de POST /receivables/{id}/receipts é o E2E de um crédito PIX recebido numa conta da instituição, o recebimento identifica esse crédito, em qualquer channel. A partir da publicação registrada no changelog do financeiro, ele passa pelas mesmas regras da tela:

  • a data do recebimento (received_on) é a data do crédito (Brasília);
  • a conta de destino, se informada, é a conta que recebeu o crédito; sem conta, o recebimento herda a do crédito;
  • o crédito só identifica título que pode receber naquela conta (conta de destino do título ou conta de filial da empresa do título);
  • os recebimentos ativos que citam o crédito, somados à parte já devolvida ao pagador, nunca passam do valor dele. O valor medido é o caixa em reais do recebimento (para título em moeda estrangeira, o valor convertido pela cotação do dia).

Referência que não é E2E de crédito da instituição continua sendo só declaração, sem essas regras.

HTTPerrordetailO que fazer
422receipt_date_differs_from_creditcredit_dateReenviar com received_on igual a credit_date
422credit_day_closedcredit_dateO dia do crédito está fechado na tesouraria; identificar exige a reabertura autorizada daquele dia, pela tela
422treasury_day_closeddateO dia informado está fechado na tesouraria (regra anterior, inalterada)
422receipt_exceeds_creditavailable_base_unitsO crédito já está identificado ou devolvido além do que sobra; available_base_units é o que resta
422receipt_account_differs_from_creditA conta informada não é a do crédito, ou o crédito está numa conta que o título não pode receber
422credit_already_returnedO crédito foi devolvido por inteiro ao pagador
422invalid_receipt_accountA conta do crédito não está ativa
503credit_state_unavailableO estado do crédito não pôde ser lido agora; nada foi gravado, repetir depois

Os valores em available_base_units seguem a escala _base_units (R$ 1,00 é 10000). A mudança está no changelog do financeiro.

Endpoints ​

Método e rotaEscopo
GET /api/partner/v1/finance/counterpartiesfinance_master:read
POST /api/partner/v1/finance/counterparties/synchronizationsfinance_master:write
GET /api/partner/v1/finance/payablesfinance_ap:read
GET /api/partner/v1/finance/payables/agingfinance_ap:read
GET /api/partner/v1/finance/payables/{id}/installmentsfinance_ap:read
POST /api/partner/v1/finance/payablesfinance_ap:write
GET /api/partner/v1/finance/receivables/agingfinance_ar:read
GET /api/partner/v1/finance/receivables/receiptsfinance_ar:read
POST /api/partner/v1/finance/receivablesfinance_ar:write
POST /api/partner/v1/finance/receivables/{id}/receiptsfinance_ar:write
GET /api/partner/v1/finance/reconciliation/panelfinance_reconciliation:read
GET /api/partner/v1/finance/reconciliation/pendingfinance_reconciliation:read
POST /api/partner/v1/finance/reconciliation/statementsfinance_reconciliation:write
GET /api/partner/v1/finance/treasury/cash-flowfinance_treasury:read
GET /api/partner/v1/finance/treasury/remittancesfinance_treasury:read
GET /api/partner/v1/finance/accounting/exportsfinance_accounting:read
GET /api/partner/v1/finance/accounting/exports/{id}/filefinance_accounting:read
POST /api/partner/v1/finance/accounting/exports/{id}/acknowledgefinance_accounting:write

A especificação OpenAPI completa, com parâmetros, sai de GET /api/openapi e a interface navegável de GET /api/swaggerui. A coleção Postman do canal traz uma requisição pronta para cada rota, na pasta "Financeiro (integração da instituição)".

Lançamentos contábeis para o ERP ​

A contabilidade da instituição gera, pela tela, lotes numerados com os lançamentos contábeis do financeiro, já com a conta do ERP pelo de/para publicado. O ERP lista os lotes, baixa o arquivo CSV (ponto e vírgula, UTF-8; o cabeçalho x-content-sha256 traz o SHA-256 para conferência) e confirma o recebimento com o seu protocolo. Um lançamento sai em um único lote; reclassificações posteriores saem como lançamentos novos no lote seguinte. Lote confirmado não pode mais ser cancelado.

Colunas do arquivo: lote; sequencia; data; conta_debito; conta_debito_erp; conta_credito; conta_credito_erp; valor_centavos; moeda; historico; tipo_evento; origem; lancamento.

Exemplo: criar um título a pagar ​

http
POST /api/partner/v1/finance/payables
Authorization: Bearer {{access_token}}
Idempotency-Key: 0b9f6c1e-4a57-4d0a-9a36-2f2f6f1f0a11
Content-Type: application/json
json
{
  "company_id": "…", "branch_id": "…", "source_account_id": 1042, "financial_account_id": "…",
  "supplier_name": "Fornecedor exemplo", "supplier_document": "00000000000191",
  "description": "Serviço prestado", "document_reference": "NF-0001",
  "amount": 150000, "due_date": "2026-10-15", "competence_date": "2026-09-01",
  "payment_method": "PIX", "pix_key": "financeiro@example.com"
}

Resposta 201 com o título em status: "pending" (aguardando alçada). Mesmo fornecedor e mesma referência de documento sem justificativa devolvem 409 duplicate_payable.

Erros comuns ​

CódigoSignificado
401Token ausente, expirado ou de credencial revogada
403 forbiddenA credencial não tem o escopo da rota
403 finance_integration_not_enabledO parceiro não está ativo ou não é integração da instituição
403 actor_comes_from_credentialO corpo trouxe campo de autor
403 financial_product_disabledO produto financeiro correspondente está desligado na instituição
422 idempotency_key_requiredEscrita sem Idempotency-Key
409Duplicidade, conflito de idempotência ou orçamento excedido

Versionamento e depreciação: veja Versões e depreciação.

Sincronização de fornecedores e clientes ​

Em Parceiros → Novo parceiro, o administrador seleciona Integração do financeiro da instituição. A instituição vem da sessão administrativa. Depois cria uma chave com os escopos finance_master:read e/ou finance_master:write e a lista de IPs autorizados. As credenciais não podem ser usadas no navegador do cliente final. Os escopos AP/AR não dão acesso ao mestre.

http
POST /api/partner/v1/finance/counterparties/synchronizations
Authorization: Bearer {{access_token}}
Idempotency-Key: {{master_sync_key}}
Content-Type: application/json
json
{
  "source_reference": "FORNECEDOR-001",
  "source_version": 1,
  "document": "L9J5BYRT000101",
  "fields": {
    "name": "Fornecedor sintético de demonstração",
    "roles": ["supplier"],
    "email": "financeiro@example.test"
  }
}

source_reference identifica o cadastro no sistema de origem; preserva letras, caixa e pontuação (espaços externos são removidos). source_version é inteiro crescente por referência, entre 1 e 9007199254740991. CPF/CNPJ, inclusive alfanumérico, é validado e normalizado. Documento e referência não podem ser remapeados. Na primeira versão, nome e papéis (supplier, customer ou ambos) são obrigatórios. Nas seguintes, fields é parcial: campo ausente conserva valor; null limpa apenas nome fantasia, e-mail ou telefone. status aceita active ou inactive.

A fonte pode criar um cadastro novo. Para atualizar um cadastro manual já existente, o operador precisa vincular a referência e conceder autoridade sobre os campos em Cadastros financeiros → Definir responsável pelos campos. Alterar um campo manualmente retira a autoridade externa daquele campo. Qualquer mudança fora da autoridade da fonte recusa o evento inteiro com 409 source_authority_conflict e a lista dos campos; não há atualização parcial. Após resolver a autoridade, o evento recusado pode ser reenviado com a mesma chave.

A resposta contém event_id, counterparty_id, counterparty_version_id, master_version, source_version e status: created, updated, unchanged ou obsolete. Versão antiga recebida depois é registrada como obsolete e não sobrescreve o mestre. Mesma versão com dados divergentes recebe 409 source_version_conflict. Mesma versão e conteúdo com outra chave devolve o mesmo evento, sem criar nova versão do cadastro. Replay devolve o resultado original; consulte a listagem para obter o estado atual.

GET /api/partner/v1/finance/counterparties retorna no máximo 100 cadastros vinculados à própria fonte, com items e next_cursor. Para continuar, envie ?after=<next_cursor>. A autoridade de cada campo é manual, this_source ou another_source. Não são devolvidos hashes, credenciais nem dados de outras fontes. A sincronização não altera contas bancárias, não aprova títulos e não faz pagamentos.

Webhooks do financeiro da instituição ​

O administrador cadastra o destino e seleciona os eventos em Financeiro → Integrações e controles → Webhooks. Esse cadastro pertence à instituição; é separado dos webhooks de contas de clientes. O catálogo inclui payable.created, payable.approved, payable.paid, payable.payment_failed, receivable.received, reconciliation.matched, integration.alert, escrow.released, bank_fee.divergent e tax_obligation.status. Para receber o novo evento, cadastre uma assinatura que o inclua; assinaturas existentes não são ampliadas automaticamente.

Falha de tentativa de pagamento ​

payable.payment_failed informa uma rejeição registrada de tentativa. A ordem eletrônica entra em rejected, ou o retorno CNAB recusa um item ainda enviado/aceito. A mensagem contém os campos abaixo em data:

CampoConteúdo
sourceelectronic_dispatch ou cnab_return
payment_order_idIdentificador da ordem; somente no despacho eletrônico
remittance_item_idIdentificador do item; somente no CNAB
payable_id, installment_idIdentificadores do título e da parcela
channelpix, ted ou cnab
amount_minor, currencyValor líquido programado em centavos e BRL; a remessa CNAB admite títulos sem retenção
attemptContador da ordem eletrônica; pode ser zero se a revalidação recusar antes de chamar a cabine
error_codeCategoria estável da rejeição
bank_occurrencesCódigos de ocorrência do retorno; somente no CNAB

As categorias eletrônicas são dict_key_not_found, dict_error, dict_key_blocked, dict_owner_mismatch, insufficient_balance, max_attempts_exceeded, installment_changed_since_order, installment_no_longer_dispatchable, contingency_cnab, rail_rejected, rail_timeout e rail_cancelled. Outros erros são apresentados como payment_rejected, sem repassar texto livre do fornecedor. O CNAB utiliza bank_rejected com seus códigos de ocorrência. Nenhum evento contém nome, documento, chave PIX, conta bancária ou mensagem livre da contraparte/cabine.

A retentativa transitória, uma divergência de valor/direção/trilho em conferência, o cancelamento pelo operador antes do despacho e a confirmação bancária com baixa local bloqueada por fechamento não emitem esse evento. Uma rejeição tardia de item CNAB já baixado é conflito de conciliação. Uma tentativa antes rejeitada pode posteriormente ser confirmada e produzir payable.paid: o recebimento da falha não autoriza um novo pagamento automático. Consulte o estado atual e o motivo antes de agir.

A rejeição e a entrega pendente são gravadas na mesma transação. Cada rejeição eletrônica possui um fact_key próprio; se uma nova tentativa também for rejeitada, terá outro fato. Para CNAB, a identidade é o item da remessa, mesmo quando o banco repete o arquivo com outro conteúdo de transporte. Repetir o comando ou a sincronização não cria nova entrega do mesmo fato.

Recebimento e verificação ​

O POST contém id, event_type, fact_key, occurred_at e data. O cabeçalho x-monetarie-event-id coincide com id. Valide x-monetarie-signature como sha256= seguido do HMAC-SHA256 hexadecimal de timestamp, ponto e bytes exatos do corpo, usando o segredo fornecido no cadastro. O timestamp está em x-monetarie-timestamp. Compare assinaturas em tempo constante e aplique uma janela de tempo compatível com o relógio do receptor. Durante as 24 horas posteriores à rotação, x-monetarie-signature-previous permite validar com o segredo anterior.

O receptor deve deduplicar pelo id: retentativas e reenvios manuais conservam essa identidade. Há até oito tentativas automáticas para falhas transitórias; depois a entrega fica disponível para revisão e reenvio manual. Uma resposta HTTP 2xx confirma o recebimento. HTTP 400, 401, 403, 404, 410 e 422 encerram a tentativa automática como falha permanente. O recebimento da mensagem não executa pagamento nem modifica o título.

VULCI Partner API