PIX
Envio de PIX, chaves DICT, consulta, cobrança imediata e com vencimento, leitura de BR Code, portabilidade de chave, MED (recuperação de fundos) e infrações DICT. Valores de entrada em centavos. As operações que tocam uma conta usam account_id, que precisa pertencer ao parceiro do token.
Enviar PIX
http
POST /api/partner/v1/pix/payments
Authorization: Bearer {{access_token}}
Content-Type: application/json
Idempotency-Key: {{uuid}}
{
"account_id": 1042,
"amount": 5000,
"pixKey": "destino@exemplo.com.br",
"recipientIspb": "12345678",
"endToEndId": "E99999008202608041200a1b2c3d4e5f",
"description": "Pagamento pedido 4210"
}- Escopo:
pix:write· Obrigatórios:account_id,amount,pixKey,recipientIspb,endToEndId.
O endToEndId é o identificador devolvido por GET /pix/dict/:key. Cada pagamento exige a sua própria consulta: o Manual Operacional do DICT define o EndToEndId como o identificador único da transação, e reusar um identificador entre pagamentos faz o BACEN recusar. Pagamento por chave sem endToEndId retorna 422 dict_lookup_required.
Resposta 202:
json
{ "status": "accepted", "transactionId": "PIXOUT20260711e5c2d176f788c964967f", "endToEndId": "E9999900820260711...", "amount": 5000, "message": "PIX enviado para processamento" }O status: "accepted" é o reconhecimento da API, não o desfecho. Acompanhe pela consulta de status e pelos webhooks pix.payout.confirmed e pix.payout.failed. Uma conta bloqueada responde 422 com code: "account_blocked"; saldo insuficiente responde 422.
Consultar status
http
GET /api/partner/v1/pix/payments/{id}
Authorization: Bearer {{access_token}}- Escopo:
pix:read
json
{
"data": {
"transactionId": "PIXOUT20260711...",
"type": "pix",
"status": "settled",
"amount": 5000,
"fee": 4,
"recipientKey": "destino@exemplo.com.br",
"endToEndId": "E9999900820260711...",
"errorReason": null,
"createdAt": "2026-07-11T10:12:00Z",
"completedAt": "2026-07-11T10:12:01Z"
}
}O campo fee traz a tarifa cobrada por esta transação, em centavos (0 quando não há tarifa).
Estados de uma transação
| Status | Significado | Final |
|---|---|---|
processing | Em andamento, aguardando a liquidação | Não |
accepted | Aceite intermediário recebido | Não |
settled / confirmed / completed | Liquidada com sucesso | Sim |
rejected | Rejeitada | Sim |
timeout | Sem resposta no prazo, valor devolvido ao pagador | Sim |
cancelled | Cancelada | Sim |
refunded | Devolvida após liquidação | Sim |
Um id desconhecido responde 404; uma transação de outro parceiro responde 403.
Devolver PIX
Devolve um PIX recebido pela conta do parceiro. A devolução é emitida pela VULCI Banco dentro da janela regulamentar de 90 dias contados da liquidação original. A devolução de um PIX que você enviou é feita pelo recebedor e chega a você pelo webhook pix.payout.returned, não por este endpoint.
http
POST /api/partner/v1/pix/payments/{id}/refund
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 1042, "amount": 5000, "reason": "MD06", "description": "Devolução solicitada pelo pagador" }- Escopo:
pix:write· Oidno caminho é a transação original recebida. Obrigatórios:account_id,amount(centavos). reasoné opcional (padrãoMD06) e restrito à listaMD06,SL02,BE08,FR01,AC03,AC06,AC07,AC14,AG03,AG13,AM09,AM18,RR04.- Devolução parcial é permitida, até o restante devolvível da transação; devoluções pendentes contam contra o restante.
Resposta 202 (aceite, não o desfecho):
json
{
"data": {
"refundId": "PIXRET20260718b1c2d3e4f5a6",
"originalTransactionId": "PIXIN20260718abc123",
"endToEndId": "E9999900820260718091500aa11bb22c",
"amount": 5000,
"remainingRefundable": 5000,
"status": "processing",
"message": "Devolução PIX enviada para processamento"
}
}Recusas: 404 quando a original não existe ou pertence a outra conta; 422 fora da janela de 90 dias, valor acima do restante devolvível, razão fora da lista ou saldo insuficiente. O desfecho chega pelos webhooks pix.refund.completed e pix.refund.failed, descritos em Webhooks.
Trilha de devoluções
http
GET /api/partner/v1/pix/payments/{id}/refunds?account_id=1042
Authorization: Bearer {{access_token}}- Escopo:
pix:read
Devolve a transação original, o restante devolvível e a lista de devoluções já solicitadas:
json
{
"data": {
"original": { "transactionId": "PIXIN20260718abc123", "endToEndId": "E9999900820260718091500aa11bb22c", "amount": 10000, "status": "settled", "completedAt": "2026-07-18T09:15:01Z" },
"remainingRefundable": 5000,
"refunds": [
{ "refundId": "PIXRET20260718b1c2d3e4f5a6", "rtrId": "D99999008202607180920aabbccddeef", "amount": 5000, "status": "settled", "reasonCode": "MD06", "reasonDescription": "Devolução solicitada pelo pagador", "requestedAt": "2026-07-18T09:20:00Z", "completedAt": "2026-07-18T09:20:02Z" }
]
}
}O campo rtrId fica nulo enquanto a devolução processa. Valores em centavos. Um id inexistente ou de outra conta responde 404.
Chaves PIX (DICT)
Registrar chave
http
POST /api/partner/v1/pix/keys
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 1042, "keyType": "EMAIL", "key": "maria@exemplo.com.br" }- Escopo:
pix:write·keyType:CPF,CNPJ,PHONE,EMAILouEVP.
Para CPF e CNPJ, a chave é o documento do titular. Para EVP (chave aleatória), a chave é gerada e devolvida na resposta. Para PHONE e EMAIL, informe o valor no campo key. Resposta 202:
json
{ "data": { "type": "email", "key": "maria@exemplo.com.br", "status": "pending" } }O desfecho do registro chega pelo webhook pix.key.registered; exclusão, bloqueio e desbloqueio chegam por pix.key.deleted, pix.key.blocked e pix.key.unblocked, descritos em Webhooks.
Listar e excluir chaves
http
GET /api/partner/v1/pix/keys?account_id=1042 # listar (pix:read)
DELETE /api/partner/v1/pix/keys/{key}?account_id=1042 # excluir (pix:write)
Authorization: Bearer {{access_token}}A listagem devolve { "data": [ { id, type, key, status, owner_name, created_at } ] }. A exclusão responde 202 com { "message": "Exclusão de chave PIX enviada para processamento" }.
Consultar chave externa
http
GET /api/partner/v1/pix/dict/{key}?accountId={id}
Authorization: Bearer {{access_token}}- Escopo:
pix:read accountIdé obrigatório.
Resolve uma chave no diretório e devolve os dados do titular e da instituição, para pagar.
O BACEN exige, em toda consulta lookup-to-pay, o documento de quem vai pagar (o cabeçalho PI-PayerId da API DICT). Esse documento é sempre o titular da conta informada em accountId, e por isso o parâmetro é obrigatório. Não existe consulta sem conta: a chamada morre antes de chegar ao diretório.
| Parâmetro | Obrigatório | Para que serve |
|---|---|---|
accountId | sim | conta demandante. O documento do titular dela é enviado como PI-PayerId |
payerDocument | não | conferência apenas. Se enviado, tem que bater com o titular de accountId |
payerDocument não é fonte do pagador. Ele existe só para o integrador confirmar que está consultando em nome de quem pensa estar. Divergiu, a requisição é recusada.
Resposta 200:
json
{
"data": {
"status": "found",
"end_to_end_id": "E99999008202608041200a1b2c3d4e5f",
"data": {
"account_number": "34967",
"account_type": "CACC",
"branch": "1",
"ispb": "99999004",
"key_type": "EMAIL",
"key_value": "joao.silva@exemplo.com.br",
"owner_document": "98765432100",
"owner_name": "João Silva",
"participant_name": "BANCO DESTINO S.A."
}
}
}Os dados de conta (branch, account_number, account_type) e o documento do titular são devolvidos integralmente, para uso interno da sua integração (validação de destino, conciliação e montagem do pagamento). Atenção à restrição de exibição do Manual Operacional do DICT (seções 8.1 e 13.2.5): ao usuário final do seu aplicativo, internet banking ou sistema, só podem ser exibidos o nome ou nome empresarial, o nome fantasia, o CPF mascarado ou o CNPJ, a chave consultada e, opcionalmente, o nome do PSP do recebedor. Agência, conta, tipo de conta e o CPF completo não podem, em hipótese alguma, ser exibidos a quem faz a consulta; esse corte na camada de exibição é responsabilidade do integrador.
account_number é sempre o número bancário canônico registrado no DICT. O contrato não muda quando a chave pertence ao próprio ISPB da VULCI Banco: esse campo nunca contém o ID interno da conta VULCI Banco/Vulci. O pagamento PIX por chave é roteado pelo servidor; para uma transferência interna explícita, obtenha o ID da conta pela API Partner de Contas e envie-o como destination_account_id em POST /transfers/internal. Não infira nem armazene um ID interno a partir de account_number.
Para o envio, use o end_to_end_id desta resposta ao chamar POST /pix/payments.
Respostas de erro
| HTTP | code | Quando |
|---|---|---|
422 | payer_account_required | accountId ausente, ou a conta não tem titular com documento |
422 | payer_document_mismatch | payerDocument não confere com o titular de accountId |
404 | key_not_found | chave não registrada no DICT |
403 | a conta em accountId não pertence à sua entidade |
Chave inexistente devolve 404 com corpo de erro estruturado, nunca um 200 de sucesso carregando status: "not_found" no corpo.
Cobrança imediata
http
POST /api/partner/v1/pix/charges
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 1042, "amount": 2599, "description": "Pedido 4210" }- Escopo:
pix:write· Obrigatórios:account_id,amount.
A cobrança dinâmica é gerada pelo motor canônico da plataforma: o BR Code aponta para a locationUrl, que serve o payload assinado (JWS) da cobrança, e o valor vive nesse payload.
Resposta 201:
json
{ "data": { "account_id": 1042, "brcode": "00020101021226...", "qrcode_base64": "data:image/png;base64,...", "amount": 2599, "description": "Pedido 4210", "txId": "GGFOZZRTXJOAMJPVLWOIIWLRMALW2", "locationUrl": "https://qrcode.demo.vulci.com.br/qr/v2/<token>", "expiresAt": "2026-07-11T03:22:23Z" } }QR estático (valor em aberto ou fixo)
http
POST /api/partner/v1/pix/qrcodes/static
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 1042, "description": "Doacao" }- Escopo:
pix:write· Obrigatório:account_id. · Opcionais:amount(centavos),pix_key,description,city.
Sem amount, o QR sai com valor em aberto: a tag de valor não é emitida e o pagador digita o valor no app dele. Com amount, o valor fica fixo no código. O QR estático é reutilizável e não expira.
Resposta 201:
json
{ "data": { "account_id": 1042, "type": "static", "brcode": "00020101021126...", "qrcode_base64": "data:image/png;base64,...", "amount": null, "description": "Doacao", "txId": "A1B2C3D4E5", "pixKey": "12345678901" } }Cobrança com vencimento (CobV)
http
POST /api/partner/v1/pix/cobv
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"account_id": 1042,
"amount": 12345,
"due_date": "2026-09-30",
"interest_type": "PERCENTUAL",
"interest_value": "1.00",
"fine_type": "FIXO",
"fine_value": "5.00",
"discount_type": "FIXO",
"discount_value": "2.00",
"debtor_name": "Cliente Exemplo",
"debtor_document": "12345678909"
}- Escopo:
pix:write· Obrigatórios:account_id,amount,due_date(AAAA-MM-DD). - Opcionais:
fine_type/fine_value,interest_type/interest_value,discount_type/discount_value(cada tipo aceitaFIXOouPERCENTUAL),rebate_value,debtor_name,debtor_document.
Resposta 201:
json
{
"data": {
"account_id": 1042,
"type": "cobv",
"brcode": "00020101021226960014br.gov.bcb.pix2574...",
"qrcode_base64": "data:image/png;base64,...",
"amount": 12345,
"dueDate": "2026-09-30",
"txId": "GGFOZZRTXJOAMJPVLWOIIWLRMALW2",
"locationUrl": "https://qrcode.demo.vulci.com.br/qr/v2/<token>",
"expiresAt": "2026-07-11T03:23:11Z"
}
}O pagador resolve a cobrança pelo locationUrl no momento do pagamento, e o valor final é calculado conforme a data. Sem due_date a resposta é 400.
Consultar cobrança
http
GET /api/partner/v1/pix/charges/{id}
Authorization: Bearer {{access_token}}- Escopo:
pix:read· Devolve{ "data": { txId, account_id, type, status, amount, description, brcode, expiresAt, paidAt } }.
Ler um BR Code
http
POST /api/partner/v1/pix/brcode/decode
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "brcode": "00020101021126..." }- Escopo:
pix:write
Decodifica um BR Code (copia e cola ou o conteúdo do QR), valida o CRC e devolve os campos interpretados, sem pagar:
json
{ "data": { "pixKey": "destino@exemplo.com.br", "amount": 10000, "amountStr": "100.00", "recipientName": "VULCI BANCO", "city": "SAO PAULO", "txId": "REVALTX123", "url": null, "type": "static", "countryCode": "BR", "currency": "986" } }amount vem em centavos; é nulo quando o BR Code não fixa valor. Um BR Code inválido responde 422 com code: "invalid_brcode"; ausência do campo responde 400 com code: "missing_brcode".
Portabilidade de chave
Traz uma chave PIX para uma conta do parceiro. O ciclo é criar, acompanhar e, conforme o caso, confirmar ou cancelar. Toda operação é escopada à conta informada (account_id).
http
POST /api/partner/v1/pix/claims
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 1042, "key": "maria@exemplo.com.br", "keyType": "EMAIL" }- Escopo:
pix:write· Obrigatórios:account_id,key,keyType.
http
GET /api/partner/v1/pix/claims?account_id=1042 # listar (pix:read)
GET /api/partner/v1/pix/claims/{id}?account_id=1042 # consultar (pix:read)
POST /api/partner/v1/pix/claims/{id}/confirm # confirmar (pix:write)
POST /api/partner/v1/pix/claims/{id}/complete # completar (pix:write)
POST /api/partner/v1/pix/claims/{id}/cancel # cancelar (pix:write)
Authorization: Bearer {{access_token}}A listagem devolve { "data": { "claims": [...], "total": 1 } } somente com as reivindicações que envolvem a conta informada, como reivindicadora ou doadora (claimer_account ou donor_account); aceita os filtros opcionais status, limit (padrão 50) e offset. O confirmar é a ação da conta doadora; o completar é a ação da reivindicadora ao fim da portabilidade ou reivindicação de posse.
Cada resposta traz { "data": { ... } } com o estado da reivindicação. Uma reivindicação que não envolve a conta informada responde 403; um id desconhecido responde 404.
Cada etapa da reivindicação também é notificada pelos webhooks pix.claim.created, pix.claim.acknowledged, pix.claim.confirmed, pix.claim.cancelled e pix.claim.completed, descritos em Webhooks.
MED (recuperação de fundos)
O MED é o mecanismo de recuperação de fundos do PIX. Quando um cliente relata fraude ou golpe em um PIX enviado, você abre uma intervenção para tentar recuperar o valor junto à instituição recebedora.
Abrir intervenção
http
POST /api/partner/v1/pix/med
Authorization: Bearer {{access_token}}
Content-Type: application/json
{
"account_id": 10024270,
"end_to_end_id": "E9999900820260714210000aabbccdd0",
"fraud_category": "SCAM",
"details": "Cliente relata golpe na negociação"
}- Escopo:
pix:write· Corpo:account_id,end_to_end_id,fraud_categoryedetails(descrição do caso). fraud_categoryaceitaFRAUDULENT_ACCESS,SCAM,ACCOUNT_TAKEOVERouOTHER.- A transação do
end_to_end_idprecisa pertencer à conta informada; caso contrário a resposta é422.
Resposta 202:
json
{
"data": {
"medId": "REC-...",
"status": "CREATED",
"rootTransactionId": "E9999900820260714210000aabbccdd0",
"fraudCategory": "SCAM",
"createdAt": "2026-07-14T21:05:00Z"
}
}Consultar e listar intervenções
http
GET /api/partner/v1/pix/med/{id}?account_id=10024270 # consultar (pix:read)
GET /api/partner/v1/pix/med?account_id=10024270 # listar (pix:read)
Authorization: Bearer {{access_token}}A consulta responde 404 quando a intervenção não pertence à conta informada. A listagem aceita limit (padrão 50) e devolve { "data": { "recoveries": [ { medId, status, rootTransactionId, fraudCategory, createdAt } ], "total": 1 } }, somente com as intervenções cuja transação raiz envolve a conta.
Cancelar intervenção
http
POST /api/partner/v1/pix/med/{id}/cancel
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 10024270 }- Escopo:
pix:write· Responde404quando a intervenção não pertence à conta informada.
A resposta traz o estado atualizado em data. O cancelamento também é notificado pelo webhook pix.med.cancelled.
Solicitar devolução dos fundos
http
POST /api/partner/v1/pix/med/{id}/refund
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 10024270, "amount": 5000 }- Escopo:
pix:write·amount(centavos) é opcional: sem ele, a devolução sai pelo valor integral da transação raiz.
Resposta 202 com data (refundId, recoveryId, status, amount), o aceite da solicitação, não o desfecho.
Acompanhe o andamento das intervenções pelos webhooks pix.med.created, pix.med.completed e pix.med.cancelled, descritos em Webhooks.
Infrações DICT
Relatos de infração sobre transações PIX da conta (marcação de fraude no DICT), e a defesa do cliente quando uma infração aberta por outra instituição bloqueia valores cautelarmente.
Abrir relato
http
POST /api/partner/v1/pix/infractions
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 10024270, "end_to_end_id": "E9999900820260714210000aabbccdd0", "details": "Cliente relata fraude na transação" }- Escopo:
pix:write· Obrigatórios:account_id,end_to_end_id.detailsdescreve o caso. - A transação do
end_to_end_idprecisa pertencer à conta informada; caso contrário a resposta é422.
Resposta 202 com data (infractionId, status, endToEndId, debtorIspb, creditorIspb, analysisResult, analysisDetails, createdAt, updatedAt), o aceite do relato, não o desfecho da análise.
Listar e consultar
http
GET /api/partner/v1/pix/infractions?account_id=10024270 # listar (pix:read)
GET /api/partner/v1/pix/infractions/{id}?account_id=10024270 # consultar (pix:read)
Authorization: Bearer {{access_token}}A listagem aceita limit (padrão 50) e offset, e devolve { "data": { "infractions": [...], "total": 1 } }, somente com relatos sobre transações da conta. Uma infração que não envolve a conta responde 404.
Cancelar relato
http
POST /api/partner/v1/pix/infractions/{id}/cancel
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 10024270 }- Escopo:
pix:write· Mesmo escopo da consulta: infração que não envolve a conta responde404.
Enviar defesa
Quando uma infração aberta por outra instituição bloqueia valores da conta cautelarmente, o cliente pode apresentar defesa.
http
POST /api/partner/v1/pix/infractions/{id}/defense
Authorization: Bearer {{access_token}}
Content-Type: application/json
{ "account_id": 10024270, "defense_text": "Prestação de serviço comprovada, nota fiscal 4210 anexada ao atendimento" }- Escopo:
pix:write· Obrigatórios:account_id,defense_text. Oidaceita o identificador da infração ou do bloqueio.
Resposta 200:
json
{ "data": { "infractionId": "b17c9a02-4a2f-4d5e-9b1a-77e0a1c2d3e4", "blockId": "3f21aa8c-1b2c-4d5e-8f90-0a1b2c3d4e5f", "status": "defense_submitted" } }Uma infração que não está mais em fase de defesa responde 422. O registro da defesa também é notificado pelo webhook pix.infraction.defense_submitted, e o desfecho da análise por pix.infraction.resolved, descritos em Webhooks.