Skip to main content
Bridge is a stablecoin payments infrastructure provider. A BridgeIntegration connects your Bridge account to ReconLayer so that transfer events — funding, on-chain movement, and payouts — are normalized into FlowLegs and matched against your PaymentIntents automatically.
Bridge evidence reaches ReconLayer through two of the three ingestion paths: inbound webhooks (real-time) and integration polling (catch-up / reconciliation).

Creating a Bridge integration

string
required
Display name shown in the dashboard.
string
required
Lowercase, snake_case identifier (^[a-z0-9_]+$), unique to this integration. Used to build the inbound webhook URL and resolve organization context on incoming webhooks.
string
required
Your Bridge API key, sent as Api-Key on calls to the Bridge API (https://api.bridge.xyz/v0). Never returned by the API — responses only include hasApiKey: true.
string
required
Must be https://. ReconLayer derives the full webhook URL by appending /webhooks/bridge/{integrationKey} to this base (path normalized to avoid double slashes).
string[]
default:"[\"transfer\"]"
At least one of: customer, kyc_link, liquidation_address.drain, static_memo.activity, transfer, virtual_account.activity, bridge_wallet.activity, card_account, card_transaction, card_withdrawal, posted_card_account_transaction, external_account.
boolean
default:"true"
Whether the background poll loop should include this integration.
On creation, ReconLayer:
  1. Builds the webhook URL: ${webhookBaseUrl}/webhooks/bridge/${integrationKey}.
  2. Calls the Bridge API to register a webhook for the requested eventCategories (POST /webhooks on https://api.bridge.xyz/v0, with an Idempotency-Key and event_epoch: 'webhook_creation').
  3. Stores the resulting webhookId, webhookUrl, and webhookStatus on the BridgeIntegrationDetail.
Response (BridgeIntegrationDetail):
webhookStatus mirrors Bridge’s own status enum: disabled, active, deleted. See Create a Bridge Integration.
If webhookBaseUrl is not https://, the request fails with 400 invalid_request (BridgeIntegrationValidationError: “Bridge webhook base URL must use https.”). Bridge integration calls that fail upstream surface as 502 bridge_upstream_error with an upstreamStatus reflecting Bridge’s HTTP status.

Managing integrations

If you change webhookBaseUrl while the integration’s webhookStatus is active, the request fails with 400 (“Disable the Bridge integration before changing its webhook URL.”) — disable first, update, then re-enable.

Enable / disable

See List Bridge Integrations, Get Bridge Integration Detail, Update a Bridge Integration, Enable a Bridge Integration, and Disable a Bridge Integration.

Receiving webhooks

Bridge sends events to POST /webhooks/bridge/{integrationKey}. ReconLayer verifies the X-Webhook-Signature (RSA-SHA256, 10-minute replay tolerance) before running matching — see Inbound Webhooks for the full signature verification flow and error responses.

Webhook normalization

Every Bridge webhook payload becomes a RawRecord with source: 'webhook', sourceType: 'psp_report', provider: 'bridge', and integrationKey set to your integration’s key. normalizedType is taken from event_type (falling back to event_category, then 'bridge.webhook'), and normalizedId is the Bridge transfer ID (falling back to sourceRef). From a single webhook, ReconLayer can produce up to two FlowLegs:
Created whenever the payload carries a Bridge transfer ID. Its status is derived from event_object_status / the transfer’s state via this mapping:FlowLegReferences captured: bridge_event_id, bridge_event_type, external_reference (from Bridge’s client_reference_id), customer_id (from on_behalf_of), destination_account_id.
Created when the payload includes a txHash, or when the source/destination payment rail is polygon or ethereum. Uses the same Bridge-state-to-status mapping above.chainId is derived from the payment rail:FlowLegReferences captured: tx_hash, bridge_transfer_id, external_reference. Includes fromAddress, toAddress, and tokenAddress when present in the Bridge payload.

Polling

In addition to (or instead of) webhooks, ReconLayer can poll Bridge for transfer state directly:
string
required
The Bridge transfer ID to fetch via GET /transfers/:id on the Bridge API.
Response (BridgeTransferPollResponse):
A polled transfer is wrapped as a synthetic webhook payload (event_category: 'transfer', event_type: 'bridge.transfer.polled') and run through the same normalization described above, with source: 'api', signatureValid: true always, and sourceRef set to {transferId}:{updatedAt|createdAt|state}. normalizedType becomes bridge.transfer.{state} (or bridge.transfer.snapshot if no state is available). Re-polling the same transfer is deduplicated by comparing the transfer’s updated_at/created_at/state (whichever is set first) against the value already recorded — if nothing changed, the existing record is returned as a duplicate rather than reprocessed. See Poll a Bridge Transfer.

Background poll loop

When pollingEnabled: true, the Bridge poll loop (apps/api/src/bridge-poller.ts) periodically calls pollActiveBridgeIntegrations across all active, polling-enabled integrations and feeds any new/changed transfers through ingestEvidence, using actor system:bridge_poller.

Next steps

  • Inbound Webhooks — signature verification details and the canonical evidence endpoints for providers without a native adapter.
  • Ingestion Flows — how Bridge evidence flows into the matching engine.
  • On-chain Integrations — for chains/networks beyond what a Bridge onchain_transfer leg captures.