API v1

Integre o Capflux ao seu ERP ou sistema: envie documentos, puxe a fila pronta para lançar, confirme o lançamento, informe o pagamento, sincronize fornecedores e consulte cards para BI.

Ambiente de testes: captura.bsph.com.br/v1, empresa Sandbox, sem garantia de disponibilidade.

Endereços

GET/v1/eu

Testar a chave

Mostra a empresa, os escopos e o limite por minuto da chave.

Respostas

200Chave válida.
401Chave ausente, inválida, revogada ou vencida.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl https://api.capflux.com.br/v1/eu \
  -H "Authorization: Bearer $CHAVE"
JavaScript
const r = await fetch('https://api.capflux.com.br/v1/eu', {
  headers: { Authorization: `Bearer ${process.env.CHAVE}` },
});
console.log(await r.json());
Python
import os, requests

r = requests.get('https://api.capflux.com.br/v1/eu', headers={'Authorization': f"Bearer {os.environ['CHAVE']}"})
print(r.json())

POST/v1/documentos

Enviar documentos (nota, boleto, anexos)

Cenário 1. Escopo documents:write (todos os planos). Até 20 arquivos e 25 MB por envio: PDF, XML fiscal, imagem, ZIP ou Word. O documento entra na caixa de entrada como qualquer outro; o card aparece quando a leitura termina (consulte GET /v1/documentos/{id}).

ParâmetroOndeTipoDescrição
Idempotency-Key *cabeçalhostringObrigatório em toda escrita. A mesma chave com o mesmo corpo devolve a mesma resposta (sem duplicar); com outro corpo, 409.

Corpo (JSON; * = obrigatório)

CampoTipoDescrição
arquivos *array
assuntostringex.: "NF 123 — Fornecedor Fictício Ltda"
observacaostring

Respostas

202Recebido; a leitura segue em segundo plano.
400Pedido inválido (ex.: sem Idempotency-Key).
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
409Idempotency-Key já usada com outro pedido.
413Envio maior que 25 MB.
415Tipo de arquivo ou de corpo não aceito.
422Campo faltando ou inválido.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl https://api.capflux.com.br/v1/documentos \
  -H "Authorization: Bearer $CHAVE" \
  -H "Idempotency-Key: erp-nota-000123" \
  -F "arquivos=@nota-000123.pdf" \
  -F "arquivos=@nota-000123.xml" \
  -F "assunto=NF 123 — Fornecedor Fictício Ltda"
JavaScript
import { readFile } from 'node:fs/promises';

const pdf = await readFile('nota-000123.pdf');
const r = await fetch('https://api.capflux.com.br/v1/documentos', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHAVE}`,
    'Idempotency-Key': 'erp-nota-000123',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    assunto: 'NF 123 — Fornecedor Fictício Ltda',
    arquivos: [{ nome: 'nota-000123.pdf', conteudo_base64: pdf.toString('base64') }],
  }),
});
console.log(r.status, await r.json()); // 202 { documento_id, situacao: 'recebida', ... }
Python
import os, requests

with open('nota-000123.pdf', 'rb') as pdf:
    r = requests.post(
        'https://api.capflux.com.br/v1/documentos',
        headers={'Authorization': f"Bearer {os.environ['CHAVE']}", 'Idempotency-Key': 'erp-nota-000123'},
        files=[('arquivos', ('nota-000123.pdf', pdf, 'application/pdf'))],
        data={'assunto': 'NF 123 — Fornecedor Fictício Ltda'},
    )
print(r.status_code, r.json())

GET/v1/documentos/{id}

Situação de um documento enviado

ParâmetroOndeTipoDescrição
id *no endereçostring

Respostas

200Situação atual.
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
404Não existe nesta empresa.
curl
curl https://api.capflux.com.br/v1/documentos/$DOCUMENTO_ID \
  -H "Authorization: Bearer $CHAVE"
JavaScript
const r = await fetch(`https://api.capflux.com.br/v1/documentos/${documentoId}`, {
  headers: { Authorization: `Bearer ${process.env.CHAVE}` },
});
const { situacao, card_id } = await r.json(); // 'virou_card' quando a leitura termina
Python
r = requests.get(f'https://api.capflux.com.br/v1/documentos/{documento_id}', headers={'Authorization': f"Bearer {os.environ['CHAVE']}"})
print(r.json()['situacao'], r.json()['card_id'])

GET/v1/cards

Notas aprovadas para lançar · consultar cards

Escopo cards:read (Profissional). Duas leituras no mesmo endereço. Cenário 7, com pronto_para_lancar=true: os cards cuja etapa atual tem passagem de lançamento para "lançado" no fluxo da empresa — a fila pronta para o ERP. Adiantamento não entra: o encerramento depende de prestação de contas/compensação e é feito na tela. Cenário 8, sem pronto_para_lancar: consulta geral para BI (Power BI, Looker), com filtros de etapa, situação, período de criação e atualizado_desde (carga incremental). Cada item traz também atualizado_em e tempos: tempo corrido em segundos em cada etapa e no total, calculado pelo Capflux; o relógio para quando o card entra numa etapa final (lançado ou descartado). Paginação por cursor (ordem de criação): repita a chamada com o proximo_cursor da resposta até ele vir nulo. A fila também pode chegar por webhook.

ParâmetroOndeTipoDescrição
pronto_para_lancarna consultabooleantrue = só a fila pronta para lançar (cenário 7; não combina com os filtros abaixo).
etapana consultastringChaves de etapa separadas por vírgula (ex.: cap,triagem). Etapa que não existe = 422 etapa_desconhecida.
situacaona consultastring: em_andamento, lancado, descartado
criado_dena consultastringCriado a partir deste dia (horário de Brasília).
criado_atena consultastringCriado até este dia, inclusive.
atualizado_desdena consultastringSó cards que mudaram desde este momento (ISO 8601 com fuso). Guarde o horário da última carga e repita.
limitena consultaintegerItens por página (1 a 200; padrão 50).
cursorna consultastringO proximo_cursor da página anterior.

Respostas

200Uma página (da fila ou da consulta). Na consulta, cada item tem também atualizado_em e tempos.
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
422Filtro, limite ou cursor inválido; etapa desconhecida.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl "https://api.capflux.com.br/v1/cards?pronto_para_lancar=true&limite=50" \
  -H "Authorization: Bearer $CHAVE"
# Próxima página: acrescente &cursor=<proximo_cursor>

# Consulta para BI (cenário 8): o que mudou desde a última carga, com os tempos
curl "https://api.capflux.com.br/v1/cards?atualizado_desde=2026-11-10T08:00:00-03:00&limite=200" \
  -H "Authorization: Bearer $CHAVE"
JavaScript
// Puxa a fila inteira, página por página.
let cursor = null;
do {
  const q = new URLSearchParams({ pronto_para_lancar: 'true', limite: '50', ...(cursor ? { cursor } : {}) });
  const r = await fetch(`https://api.capflux.com.br/v1/cards?${q}`, { headers: { Authorization: `Bearer ${process.env.CHAVE}` } });
  const page = await r.json();
  for (const card of page.itens) console.log(card.codigo, card.fornecedor.nome, card.valores.liquido);
  cursor = page.proximo_cursor;
} while (cursor);

// Consulta para BI (cenário 8): sem pronto_para_lancar, com filtros e tempos.
const q = new URLSearchParams({ situacao: 'lancado', criado_de: '2026-11-01', criado_ate: '2026-11-30', limite: '200' });
const bi = await (await fetch(`https://api.capflux.com.br/v1/cards?${q}`, { headers: { Authorization: `Bearer ${process.env.CHAVE}` } })).json();
for (const c of bi.itens) console.log(c.codigo, c.tempos.total_segundos / 86400, 'dias');
Python
import os, requests

h = {'Authorization': f"Bearer {os.environ['CHAVE']}"}
params = {'pronto_para_lancar': 'true', 'limite': 50}
while True:
    page = requests.get('https://api.capflux.com.br/v1/cards', headers=h, params=params).json()
    for card in page['itens']:
        print(card['codigo'], card['fornecedor']['nome'], card['valores']['liquido'])
    if not page['proximo_cursor']:
        break
    params['cursor'] = page['proximo_cursor']

# Consulta para BI (cenário 8): o que mudou desde a última carga, com os tempos
bi = requests.get('https://api.capflux.com.br/v1/cards', headers=h, params={'atualizado_desde': '2026-11-10T08:00:00-03:00', 'limite': 200}).json()
for card in bi['itens']:
    for etapa in card['tempos']['por_etapa']:
        print(card['codigo'], etapa['chave'], etapa['segundos'])

POST/v1/pedidos-pagamento

Criar pedido de pagamento sem nota

Cenário 6. Escopo requests:write (Profissional). Reembolso, adiantamento ou despesa de outro sistema viram card na Triagem, como o lançamento manual; as regras de caminho da empresa decidem dali (o tipo é a condição "tipo de documento"), e a resposta já traz a etapa decidida. Sem leitura por IA: os dados são os enviados. A descrição vira a primeira observação do card; o Histórico mostra "API · <nome da chave>". Mesmo número + tipo + favorecido = 409 pedido_duplicado com o card_id (além da Idempotency-Key). Dado bancário do favorecido não entra por aqui: vem do cadastro do fornecedor (PUT /v1/fornecedores, com aprovação na tela). Corpo em JSON (anexos em base64) ou multipart/form-data (campos soltos: tipo, favorecido_nome, favorecido_cnpj_cpf, valor, vencimento, descricao, numero, filial_cnpj, competencia; arquivos em "anexos").

ParâmetroOndeTipoDescrição
Idempotency-Key *cabeçalhostringObrigatório em toda escrita. A mesma chave com o mesmo corpo devolve a mesma resposta (sem duplicar); com outro corpo, 409.

Corpo (JSON; * = obrigatório)

CampoTipoDescrição
tipo *string: reembolso, adiantamento, despesa
favorecido *object
valor *numberex.: 150.4
vencimentostring
descricao *stringex.: "Táxi para visita ao cliente"
numerostringNúmero do pedido no sistema de origem.
filial_cnpjstringCNPJ da filial que paga (precisa existir na empresa).
competenciastringex.: "2026-11"
anexosarrayRecibo, comprovante ou autorização: PDF ou imagem, até 10 MB cada.

Respostas

201Card criado (com a etapa já decidida pelas regras).
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
409pedido_duplicado (com card_id) ou Idempotency-Key reaproveitada com outro corpo.
413Anexo acima de 10 MB.
415Anexo que não é PDF nem imagem.
422Campo faltando ou inválido; filial_desconhecida.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl -X POST https://api.capflux.com.br/v1/pedidos-pagamento \
  -H "Authorization: Bearer $CHAVE" \
  -H "Idempotency-Key: despesas-RB-2026-0042" \
  -H "Content-Type: application/json" \
  -d '{
    "tipo": "reembolso",
    "favorecido": { "nome": "Pessoa Fictícia", "cnpj_cpf": "12345678909" },
    "valor": 150.40,
    "vencimento": "2026-11-30",
    "descricao": "Táxi para visita ao cliente fictício",
    "numero": "RB-2026-0042"
  }'
JavaScript
const r = await fetch('https://api.capflux.com.br/v1/pedidos-pagamento', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHAVE}`,
    'Idempotency-Key': 'despesas-RB-2026-0042',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    tipo: 'reembolso',
    favorecido: { nome: 'Pessoa Fictícia', cnpj_cpf: '12345678909' },
    valor: 150.4,
    descricao: 'Táxi para visita ao cliente fictício',
    numero: 'RB-2026-0042',
    anexos: [{ nome: 'recibo.pdf', conteudo_base64: reciboBase64 }],
  }),
});
const card = await r.json(); // 201: card.etapa diz para onde as regras mandaram
Python
import os, requests

with open('recibo.pdf', 'rb') as f:
    r = requests.post(
        'https://api.capflux.com.br/v1/pedidos-pagamento',
        headers={'Authorization': f"Bearer {os.environ['CHAVE']}", 'Idempotency-Key': 'despesas-RB-2026-0042'},
        data={'tipo': 'reembolso', 'favorecido_nome': 'Pessoa Fictícia', 'favorecido_cnpj_cpf': '12345678909',
              'valor': '150.40', 'descricao': 'Táxi para visita ao cliente fictício', 'numero': 'RB-2026-0042'},
        files=[('anexos', ('recibo.pdf', f, 'application/pdf'))],
    )
print(r.status_code, r.json()['etapa'])

PUT/v1/fornecedores/{cnpj_cpf}

Sincronizar um fornecedor

Cenário 4. Escopo suppliers:write (Profissional). Cria ou atualiza o fornecedor pelo CNPJ/CPF do endereço (com ou sem pontuação). O cadastro (nome, nome_erp, situacao e, por filial, codigo_erp, prazo_pagamento_dias, email_cobranca) entra direto; o que não vier não muda. Conta bancária e Pix NUNCA entram direto: cada item de dados_pagamento vira alteração pendente, que alguém com permissão de alterar dado bancário aprova ou recusa na tela de Fornecedores, sempre com motivo. Até a aprovação, vale o cadastro anterior; os administradores recebem um aviso. Reenviar o mesmo dado não abre outra pendência; dado diferente substitui a pendência anterior. Depois de aprovada, a troca liga o alerta de segurança "dados bancários alterados há pouco" nos cards do fornecedor por 30 dias: o lançamento pela API responde 422 requer_confirmacao_na_tela até uma pessoa conferir. A resposta traz só o dado mascarado (últimos dígitos). Tudo ou nada: com um item inválido, nada é gravado.

ParâmetroOndeTipoDescrição
cnpj_cpf *no endereçostring
Idempotency-Key *cabeçalhostringObrigatório em toda escrita. A mesma chave com o mesmo corpo devolve a mesma resposta (sem duplicar); com outro corpo, 409.

Corpo (JSON; * = obrigatório)

CampoTipoDescrição
nomestringRazão social. Obrigatório para fornecedor novo.
nome_erpstring
situacaostring: ativo, inativo
empresasarrayDados por filial (filial_cnpj nulo = todas as empresas do grupo).
dados_pagamentoarrayFica pendente de aprovação na tela.
motivostringMostrado a quem aprova (ex.: "conta nova informada pelo fornecedor").

Respostas

200Atualizado.
201Criado.
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
415Corpo que não é JSON.
422Campo inválido (com o campo, ex.: dados_pagamento[0]); filial_desconhecida; nome faltando para fornecedor novo.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl -X PUT https://api.capflux.com.br/v1/fornecedores/11222333000181 \
  -H "Authorization: Bearer $CHAVE" \
  -H "Idempotency-Key: erp-forn-11222333000181-20261111" \
  -H "Content-Type: application/json" \
  -d '{
    "nome": "Fornecedor Fictício Ltda",
    "empresas": [{ "codigo_erp": "F001", "prazo_pagamento_dias": 28 }],
    "dados_pagamento": [{ "tipo": "banco", "banco": "341", "agencia": "1234", "conta": "12345-6", "tipo_conta": "corrente" }],
    "motivo": "Conta nova informada pelo fornecedor"
  }'
# dados_pagamento volta com situacao "pendente_aprovacao": vale depois que alguém aprovar na tela.
JavaScript
const r = await fetch('https://api.capflux.com.br/v1/fornecedores/11222333000181', {
  method: 'PUT',
  headers: {
    Authorization: `Bearer ${process.env.CHAVE}`,
    'Idempotency-Key': 'erp-forn-11222333000181-20261111',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    nome: 'Fornecedor Fictício Ltda',
    empresas: [{ codigo_erp: 'F001', prazo_pagamento_dias: 28 }],
    dados_pagamento: [{ tipo: 'pix', tipo_chave: 'email', chave: 'financeiro@fornecedor.exemplo' }],
  }),
});
const { fornecedor, dados_pagamento } = await r.json(); // dado bancário só mascarado
Python
import os, requests

r = requests.put(
    'https://api.capflux.com.br/v1/fornecedores/11222333000181',
    headers={'Authorization': f"Bearer {os.environ['CHAVE']}", 'Idempotency-Key': 'erp-forn-11222333000181-20261111'},
    json={'nome': 'Fornecedor Fictício Ltda', 'situacao': 'ativo', 'empresas': [{'codigo_erp': 'F001', 'prazo_pagamento_dias': 28}]},
)
print(r.status_code, r.json()['fornecedor']['id'])

GET/v1/cards/{id}

Um card

Escopo cards:read (Profissional). Os mesmos dados de um item da fila, inclusive a versao para enviar nas escritas.

ParâmetroOndeTipoDescrição
id *no endereçostring

Respostas

200O card.
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
404Não existe nesta empresa.
curl
curl https://api.capflux.com.br/v1/cards/$CARD_ID \
  -H "Authorization: Bearer $CHAVE"
JavaScript
const r = await fetch(`https://api.capflux.com.br/v1/cards/${cardId}`, { headers: { Authorization: `Bearer ${process.env.CHAVE}` } });
const card = await r.json(); // card.versao vai nas escritas
Python
card = requests.get(f'https://api.capflux.com.br/v1/cards/{card_id}', headers={'Authorization': f"Bearer {os.environ['CHAVE']}"}).json()

GET/v1/arquivos/{id}

Baixar um arquivo do card

Escopo cards:read (Profissional). O arquivo_id vem na lista "arquivos" do card (nota, XML, boleto, anexos).

ParâmetroOndeTipoDescrição
id *no endereçostring

Respostas

200O arquivo, com o tipo e o nome no cabeçalho.
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
404Não existe nesta empresa.
curl
curl -OJ https://api.capflux.com.br/v1/arquivos/$ARQUIVO_ID \
  -H "Authorization: Bearer $CHAVE"
JavaScript
import { writeFile } from 'node:fs/promises';

const r = await fetch(`https://api.capflux.com.br/v1/arquivos/${arquivoId}`, { headers: { Authorization: `Bearer ${process.env.CHAVE}` } });
await writeFile('nota.pdf', Buffer.from(await r.arrayBuffer()));
Python
r = requests.get(f'https://api.capflux.com.br/v1/arquivos/{arquivo_id}', headers={'Authorization': f"Bearer {os.environ['CHAVE']}"})
open('nota.pdf', 'wb').write(r.content)

POST/v1/cards/{id}/lancamento

Confirmar o lançamento no ERP

Cenário 2. Escopo erp:write (Profissional). Informe o número e a data do documento no ERP: o card segue para "lançado" pela mesma passagem da tela, com os mesmos campos obrigatórios, e o Histórico mostra "API · <nome da chave>". Adiantamento não é lançado pela API (422 nao_pronto_para_lancar com a etapa): o encerramento depende de prestação de contas e é feito na tela. Alerta comum do pagamento (possível duplicada) pede a justificativa no campo justificativa. Alerta de SEGURANÇA do pagamento (dados bancários do fornecedor alterados há pouco, beneficiário do boleto diferente do fornecedor, boleto suspeito) nunca é liberado pela API: a resposta é 422 requer_confirmacao_na_tela e o card espera uma pessoa conferir na tela; depois disso, reenvie com outra Idempotency-Key.

ParâmetroOndeTipoDescrição
id *no endereçostring
Idempotency-Key *cabeçalhostringObrigatório em toda escrita. A mesma chave com o mesmo corpo devolve a mesma resposta (sem duplicar); com outro corpo, 409.

Corpo (JSON; * = obrigatório)

CampoTipoDescrição
numero_documento *stringex.: "5100001234"
data_lancamento *stringex.: "2026-11-10"
vencimento_erpstringVencimento lançado no ERP, quando o fluxo pede.
justificativastringSó para alerta comum do pagamento (possível duplicada).
versaointegerOpcional. Se vier e o card tiver mudado, 409 card_mudou.

Respostas

200Lançado. Devolve o card atualizado.
400Pedido inválido (ex.: sem Idempotency-Key).
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
404Card não existe nesta empresa.
409card_mudou (a versao enviada não é a atual) ou Idempotency-Key reutilizada.
422nao_pronto_para_lancar ou ja_lancado (com a etapa atual); campos_obrigatorios (lista em campos: complete na tela); justificativa_obrigatoria; requer_confirmacao_na_tela (alerta de segurança: só uma pessoa libera).
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl https://api.capflux.com.br/v1/cards/$CARD_ID/lancamento \
  -H "Authorization: Bearer $CHAVE" \
  -H "Idempotency-Key: lancamento-5100001234" \
  -H "Content-Type: application/json" \
  -d '{"numero_documento": "5100001234", "data_lancamento": "2026-11-10", "vencimento_erp": "2026-11-30"}'
JavaScript
const r = await fetch(`https://api.capflux.com.br/v1/cards/${cardId}/lancamento`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHAVE}`,
    'Idempotency-Key': 'lancamento-5100001234',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ numero_documento: '5100001234', data_lancamento: '2026-11-10', vencimento_erp: '2026-11-30' }),
});
if (r.status === 422) {
  const { erro } = await r.json();
  // requer_confirmacao_na_tela: alerta de segurança do pagamento; uma pessoa confere na tela e você reenvia.
  console.log(erro.codigo, erro.mensagem, erro.campos ?? erro.alertas);
}
Python
r = requests.post(
    f'https://api.capflux.com.br/v1/cards/{card_id}/lancamento',
    headers={'Authorization': f"Bearer {os.environ['CHAVE']}", 'Idempotency-Key': 'lancamento-5100001234'},
    json={'numero_documento': '5100001234', 'data_lancamento': '2026-11-10', 'vencimento_erp': '2026-11-30'},
)
print(r.status_code, r.json())

POST/v1/cards/{id}/pagamento

Informar o pagamento

Cenário 3. Escopo payments:write (Profissional). Só para card lançado. Data programada e/ou data paga, valor e comprovante (PDF ou imagem, até 10 MB) opcionais. Cada envio fica registrado (nada se apaga); vale o mais recente. Alimenta o Portal do Fornecedor. Valor diferente do card (líquido; sem líquido, o bruto) é aceito — o ERP manda o que pagou —, mas a resposta traz divergencia (valor_card, valor_pago, diferenca = pago − card), o Histórico registra e o card ganha o selo "Pago com diferença". Um pagamento seguinte com o valor certo tira o selo.

ParâmetroOndeTipoDescrição
id *no endereçostring
Idempotency-Key *cabeçalhostringObrigatório em toda escrita. A mesma chave com o mesmo corpo devolve a mesma resposta (sem duplicar); com outro corpo, 409.

Corpo (JSON; * = obrigatório)

CampoTipoDescrição
data_programadastringex.: "2026-11-20"
data_pagastringex.: "2026-11-20"
valornumberex.: 1234.56
observacaostring
comprovanteArquivo
versaointeger

Respostas

201Registrado.
400Pedido inválido (ex.: sem Idempotency-Key).
401Chave ausente, inválida, revogada ou vencida.
403Escopo insuficiente ou recurso fora do plano.
404Card não existe nesta empresa.
409Idempotency-Key já usada com outro pedido.
413Comprovante maior que 10 MB.
415Comprovante que não é PDF nem imagem.
422card_nao_lancado (com a etapa atual) ou campo faltando/inválido.
429Limite de chamadas por minuto da chave (60 no Essencial, 300 no Profissional). Veja Retry-After.
curl
curl https://api.capflux.com.br/v1/cards/$CARD_ID/pagamento \
  -H "Authorization: Bearer $CHAVE" \
  -H "Idempotency-Key: pagamento-5100001234" \
  -F "data_paga=2026-11-20" \
  -F "valor=1234.56" \
  -F "comprovante=@comprovante.pdf"
JavaScript
const r = await fetch(`https://api.capflux.com.br/v1/cards/${cardId}/pagamento`, {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.CHAVE}`,
    'Idempotency-Key': 'pagamento-5100001234',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({ data_programada: '2026-11-20', valor: 1234.56 }),
});
console.log(r.status, await r.json()); // 201 { pagamento_id, ... }
Python
with open('comprovante.pdf', 'rb') as f:
    r = requests.post(
        f'https://api.capflux.com.br/v1/cards/{card_id}/pagamento',
        headers={'Authorization': f"Bearer {os.environ['CHAVE']}", 'Idempotency-Key': 'pagamento-5100001234'},
        data={'data_paga': '2026-11-20', 'valor': '1234.56'},
        files={'comprovante': ('comprovante.pdf', f, 'application/pdf')},
    )
print(r.status_code, r.json())