Provider webhooks are one of the three ways evidence enters ReconLayer, alongside file imports and integration polling.
Provider webhooks: Bridge
Today, ReconLayer ships a native inbound webhook integration for Bridge. Each Bridge integration you configure gets its own dedicated webhook URL:{integrationKey} is the integrationKey you chose when creating the Bridge integration (POST /v1/bridge-integrations), and it’s how ReconLayer resolves which organization and which signing key the incoming payload belongs to — there is no Authorization or x-organization-id header on this route.
Signature verification
Bridge signs every webhook with the header:webhookPublicKey:
- Parses
t=(timestamp, milliseconds) andv0=(base64-encoded signature) from the header. Missing or malformed headers fail verification immediately. - Rejects the webhook if
|now - t|exceeds a 10-minute (600,000 ms) replay tolerance window. - Verifies an RSA-SHA256 signature over the string
${timestamp}.${rawBody}using the integration’s public key.
Even when the signature is invalid, ReconLayer still persists the payload as a
RawRecord (with validationStatus: 'failed', signatureValid: false) for audit purposes — the matching engine is skipped, but nothing is silently dropped. The 400 response includes details.rawRecordId and details.sourceRef so you can locate the record.Responses
object
Returned when the signature is valid. Same shape used across all evidence endpoints:
object
The
integrationKey in the path does not resolve to a known, active Bridge integration.object
Signature missing, malformed, expired (outside the 10-minute window), or failed RSA-SHA256 verification.
FlowLegs, see Bridge Integration.
Listing configured inbound endpoints
GET /v1/webhook-endpoints lists the inbound webhook URLs ReconLayer has generated for your active integrations (currently Bridge):
No native webhook for your provider? Submit evidence directly
If you’re integrating a provider, bank, or system that doesn’t have a native ReconLayer webhook adapter, push evidence directly through the canonical evidence endpoints. These are the same entry points used internally by Bridge polling and on-chain ingestion — they go through the identicalingestEvidence pipeline and produce the same EvidenceAcceptanceResponse.
Both endpoints require Authorization, x-organization-id, and an Idempotency-Key header.
POST /v1/evidence/provider
Use this for any provider/PSP-side settlement, payout, or transfer event.string
required
Provider identifier, e.g.
"acme-psp".string
required
A stable identifier unique per
(organizationId, source) — used for duplicate detection.string
Link directly to a known
PaymentIntent if you already know it.string
The provider’s own transfer/transaction ID.
string
Your reference, used for matching against
PaymentIntent.externalReference.string
e.g.
intermediary_in, transfer, intermediary_out, destination (defaults to intermediary_in for provider evidence).string
default:"confirmed"
A
FlowLeg status, e.g. pending, confirmed, failed, reversed.object
required
{ "amount": string, "currency": string }.string
ISO 8601 timestamp of when the event occurred.
array
Additional
FlowLegReference key/value entries.object
required
The raw payload as received from the provider — stored verbatim on the
RawRecord.POST /v1/evidence/onchain
Use this for an on-chain transfer observed by your own indexer or RPC node, for chains/providers not covered by a native on-chain integration.string
default:"evm"
Currently only
evm is supported — other values raise an error during normalization.string
required
The on-chain transaction hash. Lowercased during normalization.
number
required
EVM chain ID (e.g.
1 for Ethereum, 137 for Polygon).string
Sender address.
string
Recipient address.
string
ERC-20 token contract address, if applicable.
string
Your reference, used for matching against
PaymentIntent.externalReference.string
default:"confirmed"
A
FlowLeg status.object
required
{ "amount": string, "currency": string }.string
Optional override for the dedup key; if omitted, derived from
txHash.object
required
The raw payload — stored verbatim on the
RawRecord.tx_hash/external_reference references, chainFamily/networkId metadata).
Idempotency on evidence endpoints
Both endpoints requireIdempotency-Key. ReconLayer hashes the request body and stores it against the key:
- Same key + same body → replays the original response with
Idempotency-Replayed: true. - Same key + different body →
409 idempotency_key_conflict. - Same key while the original request is still processing →
409 idempotency_request_in_progress.
201 for newly accepted evidence and 200 if ingestEvidence determined the record was a (organizationId, source, sourceRef) duplicate (duplicate: true in the response body) — this is independent of, and in addition to, the Idempotency-Key mechanism.
Next steps
- Ingestion Flows — see how webhook-delivered evidence flows into the matching engine.
- Bridge Integration — full lifecycle for connecting, enabling, and polling Bridge.
- On-chain Integrations — chain-indexer-based polling and push ingestion.
- Outbound Webhooks — get notified by ReconLayer when expectations and cases change.
