API B2B para compra (PIX → stablecoin) e venda (stablecoin → PIX) com cadastro de titular (KYC/KYB) feito pela BlindPay. Este documento cobre só o trilho BlindPay — o provedor ativo da API v2.
- Base URL:
https://api.defibank.digital - Autenticação: header
X-API-Key: dbk_live_...em todas as rotas públicas - Formato: JSON (exceto o upload de documento, que é
multipart/form-data) - Limite: 120 requisições por minuto, por chave
- Valores: decimais normais (
500= R$ 500,00;92.19= 92,19 USDT) - Notificações: não há webhook para o parceiro. O acompanhamento é por consulta
(polling) e pela listagem incremental (
updatedSince)
Resposta de sucesso:
{ "success": true, "data": { ... } }
Resposta de erro:
{ "error": "<código>", "message": "<texto>" }
1. Mapa de endpoints
Cadastro do titular
| Método | Rota | O que faz |
|---|---|---|
| POST | /api/v2/onramp/kyc/tos |
Abre a sessão de aceite dos Termos e devolve o link para o titular |
| POST | /api/v2/onramp/kyc/tos/confirm |
Registra o tos_id que voltou no redirect depois do aceite |
| GET | /api/v2/onramp/kyc/tos/:document |
Diz se o aceite dos Termos chegou até nós |
| POST | /api/v2/onramp/kyc/documents |
Sobe um arquivo de documento e devolve a fileUrl |
| POST | /api/v2/onramp/kyc |
Cria o titular (pessoa física ou jurídica) na BlindPay |
| GET | /api/v2/onramp/kyc/:document |
Consulta ao vivo o status do KYC do titular |
Compra (on-ramp)
| Método | Rota | O que faz |
|---|---|---|
| GET | /api/v2/onramp/quote |
Cota quanto de stablecoin um valor em BRL compra |
| POST | /api/v2/onramp/orders |
Cria a ordem de compra e devolve o PIX copia-e-cola |
| GET | /api/v2/onramp/orders |
Lista as ordens de compra da chave (paginado, com filtros) |
| GET | /api/v2/onramp/orders/:orderId |
Detalhe e status de uma ordem de compra |
Venda (off-ramp)
| Método | Rota | O que faz |
|---|---|---|
| GET | /api/v2/offramp/quote |
Cota quanto em BRL uma quantia de stablecoin rende |
| POST | /api/v2/offramp/orders |
Cria a ordem de venda e devolve o endereço de depósito |
| POST | /api/v2/offramp/orders/:orderId/confirm |
Opcional: informa o hash do depósito e devolve o status |
| GET | /api/v2/offramp/orders |
Lista as ordens de venda da chave (paginado, com filtros) |
| GET | /api/v2/offramp/orders/:orderId |
Detalhe e status de uma ordem de venda |
O titular é um só para os dois sentidos: quem fez o KYC pela rota /onramp/kyc
já pode comprar e vender.
2. Redes e moedas
| Rede | Código | Compra | Venda | Moedas |
|---|---|---|---|---|
| BNB Smart Chain | BSC |
sim | sim | USDT, USDC |
| Polygon | POLYGON |
sim | sim | USDT, USDC |
| Tron | TRX |
sim | sim | USDT |
- O campo
asseté opcional e assumeUSDTquando ausente. - Endereços
BSCePOLYGON: formato EVM,0x+ 40 caracteres hexadecimais. - Endereços
TRX: Base58,T+ 33 caracteres.
3. Cadastro do titular (KYC / KYB)
Nenhuma ordem é criada sem um titular aprovado. O cadastro é idempotente por documento: repetir com o mesmo CPF/CNPJ devolve o titular existente.
A ordem importa: os Termos vêm ANTES do cadastro. A BlindPay só cria o titular com um aceite de Termos válido.
1. POST /kyc/tos → devolve tosUrl
2. titular abre o link e aceita (volta ao seu redirectUrl com ?tos_id=to_...)
3. POST /kyc/tos/confirm → registra o tos_id (recomendado)
4. POST /kyc/documents → uma chamada por arquivo, devolve fileUrl
5. POST /kyc → cria o titular
6. GET /kyc/:document → consulta até kycStatus = approved
Os passos 2 e 4 são independentes: dá para subir os documentos enquanto o titular lê os Termos.
3.1POST/api/v2/onramp/kyc/tosiniciar o aceite dos Termos
Abre uma sessão de aceite na BlindPay e devolve o link para o titular.
Corpo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
document |
string | sim | CPF (11) ou CNPJ (14 dígitos) |
redirectUrl |
string | não, mas recomendado | Para onde o titular volta depois de aceitar. Recebe ?tos_id=to_... |
force |
boolean | não | true descarta a sessão aberta e gera outra |
curl -X POST https://api.defibank.digital/api/v2/onramp/kyc/tos \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{
"document": "12345678901",
"redirectUrl": "https://seu-app.com/kyc/retorno"
}'
Resposta 200
{
"success": true,
"data": {
"tosUrl": "https://app.blindpay.com/e/terms-of-service?session_token=...",
"idempotencyKey": "123e4567-e89b-12d3-a456-426614174000",
"expiresAt": "2026-09-01T13:57:12.000Z",
"reused": false,
"document": "12345678901"
}
}
| Campo | Descrição |
|---|---|
tosUrl |
Link para o titular abrir e aceitar |
expiresAt |
Validade real do link. Depois disso, gere outro |
reused |
true quando devolvemos uma sessão já aberta em vez de criar outra |
idempotencyKey |
Correlação interna, não precisa guardar |
Chamar de novo reaproveita a sessão enquanto o link valer e o redirectUrl
for o mesmo. Se o link venceu ou o titular o perdeu, mande "force": true.
Erros: 400 tos_error.
3.2POST/api/v2/onramp/kyc/tos/confirmregistrar o aceite
O aceite chega até nós por webhook da BlindPay automaticamente, mas não dependa
só disso: ao capturar o tos_id no seu redirectUrl, registre-o aqui. É o
caminho determinístico.
Corpo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
document |
string | sim | CPF/CNPJ do titular |
tosId |
string | sim* | to_... do redirect |
tos_id |
string | sim* | Alias de tosId (a grafia do query param) |
* Um dos dois.
curl -X POST https://api.defibank.digital/api/v2/onramp/kyc/tos/confirm \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{"document":"12345678901","tosId":"to_MR1mjSH9x1e3"}'
Responde com o mesmo corpo do GET /kyc/tos/:document (abaixo).
Erros: 400 invalid_request (sem tosId), 400 tos_error.
3.3GET/api/v2/onramp/kyc/tos/:documentestado do aceite
Diz se o aceite chegou até nós. Use para entender um 409 tos_required que
parece errado.
curl https://api.defibank.digital/api/v2/onramp/kyc/tos/12345678901 \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"document": "12345678901",
"accepted": true,
"tosId": "to_MR1mjSH9x1e3",
"consumed": false,
"idempotencyKey": "123e4567-...",
"tosUrl": "https://app.blindpay.com/e/terms-of-service?...",
"expiresAt": "2026-09-01T13:57:12.000Z",
"acceptedAt": "2026-09-01T13:42:08.000Z"
}
}
| Campo | Descrição |
|---|---|
accepted |
O aceite chegou até nós |
tosId |
Id do aceite (to_...) |
consumed |
true quando esse aceite já foi usado para criar o titular. Cada aceite serve para um titular só |
expiresAt |
Validade do link de aceite |
acceptedAt |
Quando registramos o aceite |
accepted: false depois de o titular ter aceitado no navegador significa que o
aceite não chegou até nós — resolva com o confirm do passo 3.2.
3.4POST/api/v2/onramp/kyc/documentssubir documento
Um arquivo por chamada, no campo file (multipart/form-data).
- Tamanho máximo: 10 MB
- Formatos: JPEG, PNG, WebP, HEIC ou PDF
curl -X POST https://api.defibank.digital/api/v2/onramp/kyc/documents \
-H "X-API-Key: dbk_live_..." \
-F "file=@documento-frente.jpg"
{
"success": true,
"data": {
"fileUrl": "https://files.blindpay.com/1712345678901-documento-frente.jpg",
"documentId": "7c1f0b2e-..."
}
}
Guarde cada fileUrl: é ela que vai nos campos de documento do POST /kyc
(idDocFrontUrl, selfieUrl, owners[].id_doc_front_file etc.). URLs públicas
de outros lugares não são aceitas pela BlindPay — todo arquivo tem que passar
por esta rota. O documentId é referência interna.
| Erro | Significado |
|---|---|
502 storage_failed |
Falha ao arquivar do nosso lado. O arquivo não foi enviado a lugar nenhum — repita |
502 upload_failed |
A BlindPay recusou o arquivo. Confira formato e tamanho |
400 upload_error |
Falha genérica no upload |
3.5POST/api/v2/onramp/kyccriar o titular
Cria o titular na BlindPay com dados e documentos. 14 dígitos = CNPJ (KYB),
11 dígitos = CPF (KYC) — o tamanho do documento decide, não o documentType.
Se já existir titular para o documento, a resposta devolve o existente e nada é reenviado: os dados de KYC de um titular não podem ser alterados depois de criados.
Pessoa física (CPF)
curl -X POST https://api.defibank.digital/api/v2/onramp/kyc \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{
"document": "12345678901",
"documentType": "CPF",
"name": "Maria Aparecida Silva",
"email": "maria@email.com",
"phone": "+5511987654321",
"dateOfBirth": "1990-01-31",
"address": {
"street": "Avenida Paulista, 1000",
"city": "São Paulo",
"state": "SP",
"postalCode": "01310-100"
},
"idDocType": "ID_CARD",
"idDocFrontUrl": "https://files.blindpay.com/...-frente.jpg",
"idDocBackUrl": "https://files.blindpay.com/...-verso.jpg",
"selfieUrl": "https://files.blindpay.com/...-selfie.jpg",
"tosId": "to_MR1mjSH9x1e3"
}'
Campos — pessoa física
| Campo | Obrigatório | Observação |
|---|---|---|
document |
sim | CPF, só números |
name |
sim | Nome completo |
email |
sim | — |
dateOfBirth |
sim | YYYY-MM-DD |
address.street |
sim | Rua e número |
address.city |
sim | — |
address.state |
sim | UF |
address.postalCode |
sim | CEP |
address.street2 |
não | Complemento |
idDocType |
sim | ID_CARD, DRIVERS ou PASSPORT |
idDocFrontUrl |
sim | fileUrl da frente do documento |
selfieUrl |
sim | fileUrl da selfie |
idDocBackUrl |
recomendado | fileUrl do verso (RG e CNH têm verso) |
phone |
recomendado | E.164. Aceita com ou sem +; normalizamos |
proofOfAddressUrl |
não | fileUrl do comprovante de endereço. Evita pedido de documento extra depois |
proofOfAddressDocType |
não | Tipo do comprovante (lista abaixo). Padrão UTILITY_BILL |
ipAddress |
não | IP do titular |
Pessoa jurídica (CNPJ) — KYB
Exige bem mais: website, três documentos da empresa e o quadro societário com
documentos de cada sócio.
{
"document": "55070622000188",
"documentType": "CNPJ",
"name": "EMPRESA EXEMPLO LTDA",
"email": "financeiro@empresa.com",
"phone": "+5511987654321",
"dateOfBirth": "2024-05-09",
"website": "https://empresa.com.br",
"address": {
"street": "Avenida Paulista, 1000",
"city": "São Paulo",
"state": "SP",
"postalCode": "01310-100"
},
"incorporationDocUrl": "https://files.blindpay.com/...-contrato-social.pdf",
"proofOfOwnershipDocUrl": "https://files.blindpay.com/...-quadro-societario.pdf",
"proofOfAddressUrl": "https://files.blindpay.com/...-comprovante-empresa.pdf",
"owners": [
{
"role": "beneficial_controlling",
"first_name": "João",
"last_name": "da Silva",
"date_of_birth": "1985-02-01",
"tax_id": "12345678901",
"address_line_1": "Rua X, 10",
"city": "São Paulo",
"state_province_region": "SP",
"country": "BR",
"postal_code": "01310-100",
"id_doc_country": "BR",
"id_doc_type": "ID_CARD",
"id_doc_front_file": "https://files.blindpay.com/...-rg-socio.jpg",
"id_doc_back_file": "https://files.blindpay.com/...-rg-socio-verso.jpg",
"proof_of_address_doc_type": "UTILITY_BILL",
"proof_of_address_doc_file": "https://files.blindpay.com/...-comprovante-socio.pdf",
"ownership_percentage": 100
}
],
"tosId": "to_..."
}
Campos da empresa
| Campo | Obrigatório | Observação |
|---|---|---|
document |
sim | CNPJ, só números |
name |
sim | Razão social |
email |
sim | — |
dateOfBirth |
sim | Data de constituição, YYYY-MM-DD |
address |
sim | Mesmos campos da pessoa física |
website |
sim | URL válida. Sem site próprio, use o perfil público que comprove o negócio (instagram.com/empresa, linkedin.com/company/empresa, loja em marketplace). Não invente domínio |
incorporationDocUrl |
sim | Contrato social / certidão, todas as páginas |
proofOfOwnershipDocUrl |
sim | Quadro societário com percentuais e beneficiários finais |
proofOfAddressUrl |
sim | Comprovante de endereço da empresa, até 90 dias |
owners[] |
sim | Ao menos um sócio |
phone |
recomendado | E.164 |
Campos de cada sócio (em snake_case, como a BlindPay espera)
| Campo | Obrigatório | Observação |
|---|---|---|
role |
sim | beneficial_owner, controlling_person ou beneficial_controlling |
first_name, last_name |
sim | — |
date_of_birth |
sim | YYYY-MM-DD ou datetime ISO; convertemos |
tax_id |
sim | CPF do sócio |
address_line_1, city, state_province_region, country, postal_code |
sim | Endereço do sócio |
id_doc_country |
sim | BR |
id_doc_type |
sim | ID_CARD, DRIVERS ou PASSPORT |
id_doc_front_file |
sim | fileUrl |
proof_of_address_doc_type |
sim | Lista abaixo |
proof_of_address_doc_file |
sim | fileUrl |
id_doc_back_file |
não | fileUrl do verso |
ownership_percentage |
não | Percentual de participação |
title |
não | Cargo |
Valores antigos de role (owner, director, beneficiary) ainda são aceitos
e traduzidos automaticamente.
proof_of_address_doc_type / proofOfAddressDocType: UTILITY_BILL,
BANK_STATEMENT, RENTAL_AGREEMENT, TAX_DOCUMENT, GOVERNMENT_CORRESPONDENCE.
Uma empresa com três sócios passa de dez uploads — cada arquivo é uma chamada ao
POST /kyc/documents.
Campos comuns opcionais
| Campo | Observação |
|---|---|
documentType |
CPF ou CNPJ. Informativo: o tamanho do documento decide |
tosId / tos_id |
to_... do redirect. Se não vier, usamos o aceite já registrado para o documento |
tosRedirectUrl |
Usado quando o /kyc precisa abrir a sessão de Termos sozinho (ver 409 abaixo) |
kycType |
standard (padrão) ou enhanced (exige também comprovante de endereço e origem de recursos) |
extra |
Objeto repassado cru à BlindPay na criação (ex.: occupation, source_of_funds_doc_*). Sobrescreve campos com o mesmo nome |
Respostas
200 — titular criado (ou já existente)
{
"success": true,
"data": {
"customerId": "re_000000000000",
"kycStatus": "verifying",
"kycType": "standard",
"verificationLink": null,
"tosAccepted": true,
"document": "12345678901",
"provider": "blindpay"
}
}
400 — campos faltando (lista completa de uma vez, não um por vez)
{
"error": "missing_fields",
"message": "Campos obrigatórios ausentes: idDocType, selfieUrl, address.postalCode",
"missing": ["idDocType", "selfieUrl", "address.postalCode"]
}
409 — Termos ainda não aceitos
{
"error": "tos_required",
"message": "Os Termos precisam ser aceitos antes do cadastro. ...",
"reason": "tos",
"verificationLink": "https://app.blindpay.com/e/terms-of-service?session_token=..."
}
Apresente o verificationLink ao titular e repita a mesma chamada depois do
aceite. Ou seja: dá para pular o passo 3.1 e deixar o próprio /kyc abrir a
sessão de Termos — o 409 já traz o link (com tosRedirectUrl, se informado).
400 — kyc_error: recusa da BlindPay ou documento inválido. O message traz
o motivo.
3.6GET/api/v2/onramp/kyc/:documentstatus do titular
Consulta o status ao vivo na BlindPay e atualiza o nosso registro.
curl https://api.defibank.digital/api/v2/onramp/kyc/12345678901 \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"customerId": "re_000000000000",
"kycStatus": "approved",
"kycType": "standard",
"verificationLink": null,
"tosAccepted": true,
"document": "12345678901",
"provider": "blindpay"
}
}
Erro: 404 not_found quando não existe titular para o documento.
Valores de kycStatus
| Status | Significado | Pode transacionar? |
|---|---|---|
verifying |
Em análise | não |
approved |
Aprovado | sim |
rejected |
Recusado | não |
compliance_request |
A compliance pediu informação adicional; pagamentos bloqueados | não |
approved_rfi |
Aprovado com pendência documental | não (tratado como não aprovado) |
pending_review |
Em revisão manual | não |
A aprovação costuma sair em cerca de 1 minuto. Consulte a cada 30 segundos
enquanto estiver em verifying.
Recusa ou pedido de informação (rejected, compliance_request,
approved_rfi): os dados de um titular não podem ser alterados pela API, e o
envio de informação adicional não está exposto na API externa. Nesses casos,
acione o suporte da Definity com o document e o customerId.
4. Compra — PIX para stablecoin
O titular paga um PIX e recebe a stablecoin na carteira informada.
4.1GET/api/v2/onramp/quotecotar a compra
Query
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
amountBrl |
sim | Valor em reais |
network |
sim | BSC, POLYGON ou TRX |
asset |
não | USDT (padrão) ou USDC |
curl "https://api.defibank.digital/api/v2/onramp/quote?amountBrl=500&network=POLYGON&asset=USDT" \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"amountBrl": 500,
"network": "POLYGON",
"asset": "USDT",
"provider": "blindpay",
"route": "binance",
"quote": {
"currency": "USDT",
"effectiveRate": 5.4231,
"estimatedUsdt": 92.198,
"breakdown": {
"grossUsdt": 93.35,
"spreadUsdt": 0.9335,
"networkFeeUsdt": 0.2185,
"netUsdt": 92.198
}
},
"quoteId": "pq_...",
"validFor": 300
}
}
| Campo | Descrição |
|---|---|
quote.estimatedUsdt |
O que chega na carteira, já com todas as taxas descontadas |
quote.effectiveRate |
BRL pago por unidade recebida (amountBrl / estimatedUsdt) |
breakdown.grossUsdt |
Conversão bruta do provedor |
breakdown.spreadUsdt |
Taxa de serviço da sua chave |
breakdown.networkFeeUsdt |
Taxa de rede da entrega |
validFor |
Validade em segundos (5 min) |
A cotação é informativa: a ordem trava a própria taxa no momento em que é
criada. quoteId é só referência.
Valor mínimo: definido pelo provedor, em torno de US$ 5 por operação. Abaixo
disso a resposta é 400 quote_error com a faixa aceita na message.
Erros: 400 invalid_amount, 400 invalid_network, 400 quote_error.
4.2POST/api/v2/onramp/orderscriar a ordem de compra
Exige titular com kycStatus: "approved" e Termos aceitos.
Corpo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amountBrl |
number | sim | Valor do PIX em reais (máx. R$ 20.000.000) |
network |
string | sim | BSC, POLYGON ou TRX |
walletAddress |
string | sim | Carteira que recebe a stablecoin, no formato da rede |
payerName |
string | sim | Nome do titular |
payerDocument |
string | sim | CPF/CNPJ do titular, só números |
asset |
string | não | USDT (padrão) ou USDC |
payerDocumentType |
string | não | CPF ou CNPJ |
customerId |
string | não | re_... do titular. Atalho que dispensa a busca por documento |
curl -X POST https://api.defibank.digital/api/v2/onramp/orders \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountBrl": 500,
"network": "POLYGON",
"asset": "USDT",
"walletAddress": "0xDD6a3aD0949396e57C7738ba8FC1A46A5a1C372C",
"payerName": "Maria Aparecida Silva",
"payerDocument": "12345678901"
}'
Resposta 201
{
"success": true,
"data": {
"orderId": "8f2c1a90-...",
"status": "pending",
"pix": {
"brCode": "00020101021226790014br.gov.bcb.pix...",
"pixKey": null,
"qrCodeBase64": "",
"expiresAt": "2026-08-31T15:30:00.000Z"
},
"amounts": { "amountBrl": 500, "estimatedUsdt": 92.198, "spotRate": 5.4231 },
"network": "POLYGON",
"asset": "USDT",
"walletAddress": "0xDD6a3aD0949396e57C7738ba8FC1A46A5a1C372C",
"createdAt": "2026-08-31T14:30:00.000Z"
}
}
pix.brCodeé o PIX copia-e-cola. Renderize o QR Code a partir dele —qrCodeBase64vem vazio epixKeyvemnullneste trilho.- Janela de pagamento: 1 hora (
pix.expiresAt). Não apresente o PIX depois disso. - Só o CPF/CNPJ de
payerDocumentconsegue pagar. PIX de terceiro é recusado. Titular CNPJ tem que pagar da conta da empresa.
Erros: 400 invalid_wallet, 400 order_error, 409 kyc_required (ver
seção 8).
4.3GET/api/v2/onramp/orders/:orderIdacompanhar a compra
curl https://api.defibank.digital/api/v2/onramp/orders/8f2c1a90-... \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"orderId": "8f2c1a90-...",
"status": "completed",
"amounts": { "amountBrl": 500, "estimatedUsdt": 92.198 },
"network": "POLYGON",
"asset": "USDT",
"walletAddress": "0xDD6a3aD0949396e57C7738ba8FC1A46A5a1C372C",
"pix": null,
"txHash": null,
"errorMessage": null,
"paidAt": "2026-08-31T14:32:10.000Z",
"completedAt": "2026-08-31T14:33:45.000Z",
"createdAt": "2026-08-31T14:30:00.000Z",
"updatedAt": "2026-08-31T14:33:45.000Z"
}
}
| Campo | Descrição |
|---|---|
pix |
{ brCode, expiresAt } enquanto pending; null depois |
amounts.estimatedUsdt |
Valor que será entregue na carteira |
paidAt |
Quando o PIX foi identificado |
completedAt |
Quando o envio para a carteira foi emitido |
txHash |
Hash da entrega on-chain. Pode vir null neste trilho mesmo com a ordem concluída — confira o recebimento direto na carteira de destino |
errorMessage |
Motivo, quando failed |
Ciclo da compra: pending → processing (PIX pago, conversão em andamento) →
completed. Falha no pagamento ou estorno do provedor leva a failed.
Consulte a cada 15–30 segundos enquanto estiver em pending ou processing.
Erro: 404 not_found (a ordem não existe ou é de outra chave).
5. Venda — stablecoin para PIX
O titular envia stablecoin para o endereço que devolvemos, e o favorecido recebe um PIX.
5.1GET/api/v2/offramp/quotecotar a venda
Query
| Parâmetro | Obrigatório | Descrição |
|---|---|---|
amountUsdt |
sim | Quantidade de stablecoin que o titular vai enviar (bruto) |
network |
sim | BSC, POLYGON ou TRX |
asset |
não | USDT (padrão) ou USDC |
pixKey |
não | Chave PIX de destino — cota contra a conta real do pedido |
pixKeyType |
não | CPF, CNPJ, EMAIL, PHONE ou RANDOM |
payerDocument |
não | CPF/CNPJ do titular (usado junto com pixKey) |
Enviar pixKey + pixKeyType + payerDocument é recomendado: a cotação passa a
usar a mesma conta PIX que a ordem vai usar.
curl "https://api.defibank.digital/api/v2/offramp/quote?amountUsdt=200&network=POLYGON&asset=USDT" \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"amountUsdt": 200,
"asset": "USDT",
"network": "POLYGON",
"minAmountUsdt": 20,
"provider": "blindpay",
"route": "binance",
"quote": {
"currency": "BRL",
"estimatedBrl": 1060.35,
"spotRate": 5.3371,
"netUsdt": 198.67,
"spreadUsdt": 0.7,
"deliveryFeeUsdt": 0.63
},
"validFor": 300
}
}
| Campo | Descrição |
|---|---|
minAmountUsdt |
Mínimo real para essa rede e moeda. Confira antes de oferecer o valor |
quote.estimatedBrl |
Valor estimado do PIX |
quote.spotRate |
BRL por unidade convertida |
quote.netUsdt |
O que efetivamente é convertido em BRL |
quote.spreadUsdt |
Taxa de serviço da sua chave |
quote.deliveryFeeUsdt |
Taxa de rede da liquidação |
validFor |
Validade em segundos (5 min) |
Abaixo do mínimo: 400 quote_error com "Valor mínimo é X USDT".
Erros: 400 invalid_amount, 400 invalid_network, 400 quote_error.
5.2POST/api/v2/offramp/orderscriar a ordem de venda
Exige titular (payerDocument) com kycStatus: "approved" e Termos aceitos. A
chave PIX de destino pode ser de terceiro.
Corpo
| Campo | Tipo | Obrigatório | Descrição |
|---|---|---|---|
amountUsdt |
number | sim | Quantidade que o titular vai enviar |
network |
string | sim | BSC, POLYGON ou TRX |
pixKey |
string | sim | Chave PIX do favorecido |
pixKeyType |
string | sim | CPF, CNPJ, EMAIL, PHONE (formato +5511987654321) ou RANDOM (UUID) |
payerDocument |
string | sim | CPF/CNPJ do titular, só números |
asset |
string | não | USDT (padrão) ou USDC |
payerDocumentType |
string | não | CPF ou CNPJ |
customerId |
string | não | re_... do titular |
curl -X POST https://api.defibank.digital/api/v2/offramp/orders \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{
"amountUsdt": 200,
"network": "POLYGON",
"asset": "USDT",
"pixKey": "12345678901",
"pixKeyType": "CPF",
"payerDocument": "12345678901"
}'
Resposta 201
{
"success": true,
"data": {
"orderId": "3b9d7e42-...",
"status": "pending",
"correlationId": "ext-offramp-...",
"deposit": {
"address": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
"network": "POLYGON",
"asset": "USDT",
"amountUsdt": 200,
"expiresAt": "2026-08-31T15:30:00.000Z",
"usdtContract": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F",
"tokenContract": "0xc2132D05D31c914a87C6611C10748AEb04B58e8F"
},
"amounts": { "amountUsdt": 200, "estimatedBrl": 1060.35, "spotRate": 5.3371 },
"pix": { "pixKey": "12345678901", "pixKeyType": "CPF" },
"createdAt": "2026-08-31T14:30:00.000Z"
}
}
Instrua o titular a enviar exatamente deposit.amountUsdt da moeda
deposit.asset para deposit.address, na rede deposit.network. Moeda ou rede
diferentes resultam em perda dos fundos.
- O depósito é detectado automaticamente — não é preciso informar o hash.
- Janela de depósito: 1 hora (
deposit.expiresAt). Sem depósito nesse prazo, a ordem vai paraexpired. Não envie depois de expirada; se enviou, acione o suporte com oorderIde o hash. tokenContracté o contrato do token na rede.usdtContracté o mesmo valor, mantido por compatibilidade.- A chave PIX é validada na criação: uma chave recusada falha aqui, antes do depósito.
Erros: 400 order_error (inclui chave PIX inválida e valor abaixo do mínimo),
409 kyc_required.
5.3POST/api/v2/offramp/orders/:orderId/confirmconfirmar depósito (opcional)
Não é necessário: o depósito é detectado sozinho. A rota existe por compatibilidade — valida o formato do hash, se enviado, e devolve o status atual.
curl -X POST https://api.defibank.digital/api/v2/offramp/orders/3b9d7e42-.../confirm \
-H "X-API-Key: dbk_live_..." \
-H "Content-Type: application/json" \
-d '{"txHash":"0xdef..."}'
{
"success": true,
"data": {
"orderId": "3b9d7e42-...",
"status": "processing",
"txHash": "0xdef...",
"note": "Deposits are auto-detected on the master Binance; confirm is optional."
}
}
Erros: 400 invalid_tx_hash, 404 not_found.
5.4GET/api/v2/offramp/orders/:orderIdacompanhar a venda
curl https://api.defibank.digital/api/v2/offramp/orders/3b9d7e42-... \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"orderId": "3b9d7e42-...",
"status": "completed",
"correlationId": "ext-offramp-...",
"amounts": { "amountUsdt": 200, "estimatedBrl": 1060.35, "finalBrl": 1060.35 },
"network": "POLYGON",
"asset": "USDT",
"deposit": null,
"pix": { "pixKey": "12345678901", "pixKeyType": "CPF" },
"txHash": "0xdef...",
"offrampId": "po_...",
"errorMessage": null,
"processingStartedAt": "2026-08-31T14:35:00.000Z",
"completedAt": "2026-08-31T14:41:02.000Z",
"createdAt": "2026-08-31T14:30:00.000Z",
"updatedAt": "2026-08-31T14:41:02.000Z"
}
}
| Campo | Descrição |
|---|---|
deposit |
{ address, asset, amountUsdt, expiresAt } enquanto pending; null depois |
amounts.finalBrl |
Valor efetivamente pago no PIX. Pode diferir de estimatedBrl por variação de câmbio |
txHash |
Hash do depósito do titular |
offrampId |
Id do pagamento no provedor (po_...) |
processingStartedAt |
Quando o depósito foi reconhecido |
errorMessage |
Motivo, quando failed ou expired |
Ciclo da venda: pending (aguardando depósito) → processing (depósito
reconhecido, PIX em liquidação) → completed. Sem depósito em 1 hora: expired.
Falha no pagamento: failed.
Erro: 404 not_found.
6. Listagem e reconciliação
GET /api/v2/onramp/orders e GET /api/v2/offramp/orders — mesmos parâmetros.
curl "https://api.defibank.digital/api/v2/onramp/orders?limit=50&updatedSince=2026-08-31T00:00:00Z" \
-H "X-API-Key: dbk_live_..."
{
"success": true,
"data": {
"orders": [ { "orderId": "...", "status": "completed", "...": "..." } ],
"pagination": { "total": 128, "limit": 50, "offset": 0, "hasMore": true }
}
}
Cada item de orders tem o mesmo formato do detalhe (GET /orders/:orderId).
| Parâmetro | Descrição |
|---|---|
limit |
Padrão 50, máximo 200 |
offset |
Deslocamento para paginar |
status |
Um dos status da seção 7 |
from / to |
Intervalo de criação, ISO-8601 |
updatedSince |
Ordens alteradas a partir da data — para sincronização incremental |
- Ordenação: mais recentes primeiro.
- Uma chave só enxerga as próprias ordens.
- Parâmetro inválido:
400 invalid_querycom o campo emfield.
Reconciliação recomendada: guarde o updatedAt da última sincronização e
chame com updatedSince a cada poucos minutos. Isso pega qualquer mudança que o
polling individual tenha perdido.
7. Status das ordens
Mesmo vocabulário nos dois sentidos.
| Status | Compra | Venda | Terminal |
|---|---|---|---|
pending |
Aguardando o PIX | Aguardando o depósito | não |
processing |
PIX pago, conversão e entrega em andamento | Depósito reconhecido, PIX em liquidação | não |
completed |
Stablecoin enviada à carteira | PIX pago | sim |
failed |
Pagamento recusado/estornado — veja errorMessage |
Pagamento do PIX falhou — veja errorMessage |
sim |
expired |
— | 1 hora sem depósito | sim |
O filtro da listagem aceita também paid e cancelled, que não são usados
neste trilho.
Pare o polling ao chegar em um status terminal.
8. Erros
| HTTP | error |
Quando | O que fazer |
|---|---|---|---|
| 400 | invalid_amount |
Valor não positivo | Corrija o valor |
| 400 | invalid_network |
Rede fora da lista | Use BSC, POLYGON ou TRX |
| 400 | invalid_wallet |
Endereço fora do formato da rede | Corrija o walletAddress |
| 400 | quote_error |
Cotação recusada (mínimo, rede indisponível etc.) | Leia a message |
| 400 | order_error |
Ordem recusada (mínimo, chave PIX inválida etc.) | Leia a message |
| 400 | missing_fields |
Faltam obrigatórios no cadastro | missing[] traz a lista completa |
| 400 | kyc_error |
Cadastro recusado | Leia a message |
| 400 | tos_error |
Falha ao abrir ou registrar os Termos | Leia a message |
| 400 | invalid_request |
confirm sem tosId |
Envie tosId ou tos_id |
| 400 | invalid_query |
Filtro de listagem inválido | Veja field |
| 400 | invalid_tx_hash |
Hash fora do formato da rede | Corrija ou omita |
| 400 | upload_error |
Falha genérica no upload | Repita |
| 401 | unauthorized |
X-API-Key ausente ou inválida |
Confira a chave |
| 404 | not_found |
Ordem ou titular inexistente para esta chave | — |
| 409 | tos_required |
Cadastro sem Termos aceitos | Apresente o verificationLink e repita |
| 409 | kyc_required |
Titular não liberado para transacionar | Veja abaixo |
| 422 | — | Corpo ou query fora do schema (tipo, tamanho, enum) | Corrija o campo apontado |
| 429 | rate_limit_exceeded |
Mais de 120 req/min | Reduza a frequência |
| 500 | internal_error |
Falha na listagem | Repita |
| 502 | storage_failed |
Falha ao arquivar o documento | Nada foi enviado — repita |
| 502 | upload_failed |
A BlindPay recusou o arquivo | Confira formato e tamanho |
| 503 | service_unavailable |
Manutenção | Respeite o header Retry-After |
409 kyc_required
Devolvido por POST /onramp/orders e POST /offramp/orders.
{
"error": "kyc_required",
"message": "O titular precisa concluir o KYC antes de comprar. Cadastre via POST /api/v2/onramp/kyc.",
"reason": "kyc",
"kycStatus": "verifying",
"verificationLink": null,
"customerId": "re_000000000000"
}
reason diz o que falta:
"kyc"— titular inexistente (kycStatus: "none") ou não aprovado. Cadastre (seção 3.5) ou aguarde a aprovação (seção 3.6)."tos"— falta o aceite dos Termos. Apresente overificationLink.
9. Manutenção
Durante manutenção programada, todas as rotas públicas de /api/v2/onramp e
/api/v2/offramp respondem:
HTTP 503
Retry-After: 300
{
"error": "service_unavailable",
"message": "External API is under maintenance. Please retry later. Existing orders keep being processed."
}
Ordens já criadas continuam sendo processadas normalmente.