BlendFi
Webhooks

Catálogo de eventos

Cada evento de webhook da BlendFi com exemplos de payload, quando dispara e o que fazer.

Os tipos de evento que a BlendFi entrega, agrupados por recurso: conversion, transaction e user (KYC). Todo payload segue o mesmo formato; apenas o conteúdo de data muda por tipo. Ao registrar um endpoint, você pode assinar qualquer um dos nomes de evento válidos; os eventos que de fato disparam hoje são os de conversão, transação e KYC documentados abaixo.

O formato do payload

Toda entrega de webhook faz POST de um body JSON no formato:

{
  "id": "evt_01J…",
  "type": "conversion.completed",
  "created_at": "2026-05-04T13:00:00Z",
  "api_version": "2026-05-01",
  "data": {
    "object": "conversion",
    "...": "..."
  }
}
CampoNotas
idULID; bate com o header X-Blendfi-Event-Id. Use como sua chave de controle de duplicatas.
typeUm dos nomes de evento abaixo. Estável.
created_atISO-8601 UTC. Quando a BlendFi montou o evento.
api_versionVersão do schema. Campos novos podem ser adicionados em uma versão futura; campos existentes nunca mudam de formato.
data.objectconversion, transaction ou user.
data.…O objeto completo no momento da mudança de estado.

Eventos de conversão

conversion.created

Dispara: conversão criada via POST /v1/quotes/:id/accept. O endereço de depósito (offramp) ou QR Pix (onramp) está emitido; a janela de 15 minutos começou.

Você costuma: mostrar ao cliente final o endereço de depósito ou o QR Pix.

{
  "id": "evt_01J...",
  "type": "conversion.created",
  "created_at": "2026-05-04T13:00:00Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "user_id": "usr_01J...",
    "transaction_type": "pix_offramp",
    "status": "awaiting_deposit",
    "expected_source_amount": "100.00",
    "deposit_address": "0xabc…",
    "deposit_address_network": "polygon",
    "deposit_window_expires_at": "2026-05-04T13:15:00Z"
  }
}

conversion.standby

Dispara: conversão entrou em standby. Apenas para offramp; o onramp não tem standby. Payload inclui standby_reason (um de under_funded, over_funded, window_expired, duplicate_deposit, wrong_address, late_post_window; veja Standby).

Você costuma: decidir entre POST /v1/conversions/:id/liquidate ou aguardar resolução manual. Veja Standby e liquidação manual.

{
  "id": "evt_01J...",
  "type": "conversion.standby",
  "created_at": "2026-05-04T13:05:00Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "status": "standby",
    "standby_reason": "under_funded",
    "expected_source_amount": "100.00",
    "received_amount": "97.50",
    "standby_at": "2026-05-04T13:05:00Z",
    "standby_expires_at": "2026-05-11T13:05:00Z"
  }
}

conversion.completed

Dispara: caminho feliz terminal. Onramp entregou USDT on-chain ou offramp entregou Pix ao destinatário.

Você costuma: finalizar o pedido visível ao cliente final; emitir o seu evento de negócio nos sistemas seguintes.

{
  "id": "evt_01J...",
  "type": "conversion.completed",
  "created_at": "2026-05-04T13:00:20Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "status": "completed",
    "completed_at": "2026-05-04T13:00:20Z",
    "pix_e2e_id": "E12345...",
    "usdt_tx_hash": "0xabc…"
  }
}

conversion.failed

Dispara: caminho terminal de falha. failure_reason carrega o código.

Você costuma: bifurcar em failure_reason para decidir entre erro visível ao cliente final, retentativa a partir de cotação nova, ou escalação ao suporte.

{
  "id": "evt_01J...",
  "type": "conversion.failed",
  "created_at": "2026-05-04T13:00:25Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "status": "failed",
    "failure_reason": "pix_send_failed",
    "failure_details": {
      "error_code": "upstream_rejected",
      "message": "Recipient bank rejected"
    }
  }
}

conversion.expired

Dispara: terminal. A janela de 15 minutos passou sem pagamento (onramp) ou sem depósito on-chain (offramp). A reserva de limite é liberada.

Você costuma: marcar o pedido visível ao cliente final como expirado; se o cliente ainda quiser operar, recomece a partir de uma cotação nova.

{
  "id": "evt_01J...",
  "type": "conversion.expired",
  "created_at": "2026-05-04T13:15:00Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "user_id": "usr_01J...",
    "quote_id": "qte_01J...",
    "transaction_type": "pix_onramp",
    "status": "expired"
  }
}

conversion.canceled

Dispara: terminal. Você chamou POST /v1/conversions/:id/cancel com a conversão em awaiting_deposit. A reserva de limite é liberada.

Você costuma: a própria chamada de cancel já devolveu a conversão cancelada para o seu cliente. O webhook é a cópia do system-of-record; use para dedup, auditoria ou painel de operações.

{
  "id": "evt_01J...",
  "type": "conversion.canceled",
  "created_at": "2026-05-04T13:02:00Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "user_id": "usr_01J...",
    "quote_id": "qte_01J...",
    "transaction_type": "pix_offramp",
    "status": "canceled",
    "expected_source_amount": "100.00"
  }
}

conversion.abandoned

Dispara: apenas offramp; conversão passou 7 dias em standby sem /liquidate. Resolução é manual fora da plataforma.

Você costuma: abrir chamado com o suporte da BlendFi citando conversion_id.

{
  "id": "evt_01J...",
  "type": "conversion.abandoned",
  "created_at": "2026-05-11T13:05:00Z",
  "data": {
    "object": "conversion",
    "id": "cnv_01J...",
    "status": "abandoned",
    "received_amount": "97.50"
  }
}

Sem webhooks intermediários de conversão

A BlendFi não emite eventos conversion.* para funded ou liquidated: esses são estados transitórios que avançam automaticamente. O evento de conversão de interesse é o desfecho (completed, failed, standby, expired, canceled, abandoned). Para visibilidade da etapa de liquidação, veja os eventos de transação abaixo.

Eventos de transação

Uma transação é a etapa de liquidação subjacente de uma conversão: o pagamento Pix (onramp) ou a transferência on-chain. Esses eventos dão visibilidade mais granular da liquidação do que o ciclo de vida da conversão. São opcionais: os eventos conversion.* são os sinais primários recomendados, e a maioria das integrações não precisa do detalhe no nível de transação. Aqui data.object é transaction, e esses eventos disparam junto com o evento de conversão correspondente.

transaction.sending_pix

Dispara: liquidação do onramp iniciada; a BlendFi está enviando o pagamento Pix ao destinatário.

Você geralmente: nada. É informativo; aguarde o conversion.completed.

transaction.completed

Dispara: a etapa de liquidação foi concluída. Dispara junto com conversion.completed.

Você geralmente: prefira conversion.completed como gatilho; use este apenas para reconciliação no nível de liquidação.

transaction.failed

Dispara: a etapa de liquidação falhou. Dispara junto com conversion.failed.

Você geralmente: ramifique pelo failure_reason da conversão.

Nomes de evento de transação reservados

O conjunto de nomes de evento válidos aceitos ao registrar um endpoint também inclui nomes transaction.* adicionais (por exemplo transaction.payment_received, transaction.refunded). Eles são reservados para uso futuro e não são emitidos hoje: assiná-los é inofensivo, mas eles não vão disparar.

Eventos de KYC do cliente final

user.kyc_pending

Dispara: cliente final iniciou submissão de KYC.

Você costuma: mostrar UI "verificação em análise".

{
  "id": "evt_01J...",
  "type": "user.kyc_pending",
  "created_at": "2026-05-04T13:00:00Z",
  "data": {
    "object": "user",
    "id": "usr_01J...",
    "kyc_status": "pending",
    "latest_submission": {
      "id": "kyc_01J...",
      "submitted_at": "2026-05-04T13:00:00Z"
    }
  }
}

user.kyc_approved

Dispara: verificação aprovou o cliente final. Liberado para transacionar.

Você costuma: desbloquear o resto do seu fluxo para este cliente final.

{
  "id": "evt_01J...",
  "type": "user.kyc_approved",
  "created_at": "2026-05-04T13:05:00Z",
  "data": {
    "object": "user",
    "id": "usr_01J...",
    "kyc_status": "approved",
    "kyc_approved_at": "2026-05-04T13:05:00Z",
    "kyc_expires_at": "2027-05-04T13:05:00Z"
  }
}

user.kyc_rejected

Dispara: verificação rejeitou. Cliente final não pode transacionar.

Você costuma: mostrar o motivo da rejeição; oferecer caminho de remediação ou contato com suporte.

{
  "id": "evt_01J...",
  "type": "user.kyc_rejected",
  "created_at": "2026-05-04T13:05:00Z",
  "data": {
    "object": "user",
    "id": "usr_01J...",
    "kyc_status": "rejected",
    "latest_submission": {
      "id": "kyc_01J...",
      "rejection_reason": "document_unreadable"
    }
  }
}

user.kyc_expired

Dispara: KYC antes aprovado caducou.

Você costuma: pedir reverificação ao cliente final; bloquear transações até a reverificação.

{
  "id": "evt_01J...",
  "type": "user.kyc_expired",
  "created_at": "2027-05-04T13:05:00Z",
  "data": {
    "object": "user",
    "id": "usr_01J...",
    "kyc_status": "expired"
  }
}

Assinando

Passe os tipos que você quer ao registrar ou atualizar o endpoint:

curl -X POST $BLENDFI_BASE/v1/webhook_endpoints \
  -H "Authorization: Bearer $BLENDFI_KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "content-type: application/json" \
  -d '{
    "url": "https://your-app.example.com/blendfi-webhooks",
    "event_types": [
      "conversion.created",
      "conversion.standby",
      "conversion.completed",
      "conversion.failed",
      "user.kyc_approved",
      "user.kyc_rejected"
    ]
  }'

A assinatura mínima útil para qualquer fluxo é conversion.completed e conversion.failed. Adicione conversion.standby se você opera offramp. Eventos de KYC são independentes do fluxo de operações mas valiosos para qualquer app voltado ao cliente final.

Eventos novos chegam de forma aditiva

Assinar um tipo de evento novo posteriormente não tem efeito sobre conversões e clientes finais já existentes; apenas mudanças de estado futuras disparam o evento novo.

Próximos passos

Nesta página