Developers · Webhooks

HMAC-signed webhooks for the off-ramp lifecycle.

When your product needs asynchronous lifecycle state, register webhook endpoints and verify each delivery. The signature binds the timestamp to the exact raw body so you can reject tampered or replayed payloads.

01

Lifecycle events

EventMeaning
deposit.createdA seller deposit was created on Base
deposit.partially_filledA deposit filled in part
deposit.filledA deposit fully filled
deposit.closedA seller closed or withdrew remaining balance
otc.takenA private OTC deposit was taken by the approved buyer
02

Verify every delivery

  1. 1Read the X-Usdctofiat-Signature header in the form t=<unix>,v1=<hex>.
  2. 2Build the signed payload as the string timestamp.rawBody using the raw, unparsed body.
  3. 3Compute HMAC-SHA256 over that payload with your endpoint secret.
  4. 4Compare in constant time against the v1 hex value before trusting the event.
  5. 5Optionally reject deliveries whose timestamp is older than your chosen window.
03

Replay protection is your choice

The reference receiver in the starters repo treats timestamps older than 5 minutes as stale to guard against replays. That window is enforced by your verifier, not the sender, so you can tighten or loosen it to fit your latency and retry tolerance.

Because the signature covers timestamp.rawBody, parse the JSON only after the HMAC check passes. Verifying the parsed object instead of the raw bytes is the most common way to get signature verification subtly wrong.

04

Register and operate

  • Register endpoints with your Peerlytics API key; one key authenticates the offramp and Peerlytics surfaces.
  • Endpoints that hit repeated consecutive delivery failures can be disabled until you fix them.
  • Use the starters repo receiver as a known-good HMAC verification reference.
  • Treat webhooks as state hints; reconcile against onchain truth with deposits() when it matters.

Common questions

How are USDCtoFiat webhooks signed?

Each delivery carries X-Usdctofiat-Signature: t=<unix>,v1=<hex>, an HMAC-SHA256 over the string timestamp.rawBody. Recompute the HMAC with your endpoint secret over the raw body and compare in constant time before trusting the event.

How do I prevent replayed webhooks?

Reject deliveries whose signed timestamp is older than a window you choose. The reference receiver uses 5 minutes. The sender does not enforce a window, so this is your verifier's responsibility.

Do I need an API key for webhooks?

Yes. Creating deposits is permissionless, but registering webhook endpoints uses a Peerlytics API key. The same key also authenticates the Peerlytics API.