Skip to main content

Webhooks

The API receives inbound webhooks from Bridge to observe fiat and off-ramp events. Handler: apps/api/src/webhooks/bridge.ts.

Endpoint

POST /webhooks/bridge

Unauthenticated by JWT — verified by RSA-SHA256 signature over <timestamp>.<raw body>.

Verification

Events handled

EventHandlerWhat it does
customer.updatedhandleCustomerUpdatedUpdates kyc_verifications.status when Bridge marks a customer approved/rejected.
virtual_account.activity.funds_receivedhandleVirtualAccountActivityCreates a transactions row (type = deposit) for the inbound fiat, status = pending.
virtual_account.activity.payment_submittedhandleVirtualAccountActivityAdvances the deposit's status toward completion.
virtual_account.activity.payment_processedhandleVirtualAccountActivityMarks deposit completed.
liquidation_address.drain_completedhandleLiquidationDrainMarks the linked PIX / withdraw transaction completed; stores pixEndToEndId / bridgeTransferId.
liquidation_address.drain_failedhandleLiquidationDrainMarks the transaction failed with failureReason.

Any other event types are recorded in webhook_events but otherwise ignored.

Idempotency

Every webhook is recorded in webhook_events before processing (unique on bridgeEventId). A replayed webhook returns 200 immediately without side effects. The handler updates processedAt only on successful completion — a mid-processing crash lets the retry re-run the handler.

Configuring Bridge

  • URL: https://<api-host>/webhooks/bridge
  • Secret: the RSA public key/secret pair from the Bridge dashboard; store the verification secret as the BRIDGE_WEBHOOK_SECRET Cloudflare secret.
  • Events to subscribe to: customer.*, virtual_account.activity.*, liquidation_address.drain_* at minimum.

Debugging

  • Look in the webhook_events table for the raw payload, event type, and processing timestamp.
  • Cloudflare Workers logs (wrangler tail) show signature failures and handler errors.