POST requests with a JSON body and an HMAC-SHA256 signature. Subscribe and inspect delivery logs in Portal → Webhooks.
Event types
Two categories — lifecycle events fire when a chain log appears at confirmation depth (one event per log), operational events fire from the daily metrics processor (one per product per day at most). We add new event types over time. Treat unknownevent_type values as a no-op — don’t reject them.
Lifecycle events (tx-driven)
event_type | Trigger | Confirmation depth |
|---|---|---|
deposit.confirmed | Engine Deposit log seen at confirmation depth — shares minted | per chain (see Deposit/Redeem Lifecycle) |
redeem.requested | Engine RedeemRequested log — async vaults only (no synchronous redeem) | same |
redeem.confirmed | Engine Withdraw log — shares burnt, asset transferred | same |
deposit.confirmed / redeem.confirmed):
redeem.requested — async vaults only):
/position endpoint.
Operational events (daily aggregate)
event_type | Trigger | Payload fields |
|---|---|---|
apy_change | Net APY moved by more than ±10% day-over-day on one of your products | slug, previous_apy, current_apy, change_pct, date |
tvl_alert | Engine total assets moved by more than ±20% day-over-day | slug, previous_tvl, current_tvl, change_pct, date |
vault_pause | A product was set to paused (manual ops or upstream vault halt) | slug, status |
Request envelope
X-Barker-Event— same asevent_typein the table above.X-Barker-Signature— hex HMAC-SHA256 of the raw request body with your webhook secret. Always verify this before trusting the payload.
2xx response within 10 seconds. Any other status (or a timeout) counts as a failure.
Retries
Failed deliveries are retried up to 3 attempts total (the original try plus 2 retries). The full attempt history and last response code is visible in the Portal under each delivery row (attempts, status ∈ pending / delivered / failed, response code, response body excerpt).
If your endpoint is down longer than the retry budget, the event row is durably stored — you can manually replay from the Portal once you’re back up.
Verifying the signature
The signature is HMAC-SHA256 over the exact bytes of the request body, hex-encoded. Verify on the raw bytes, not afterJSON.parse + re-stringify — once you re-serialize, byte equivalence breaks (key order, whitespace, number formatting all differ across runtimes).
Idempotency
Network failures + retries mean you may receive the same delivery more than once. Dedupe key depends on the event family:event_type | Dedupe key | Notes |
|---|---|---|
deposit.confirmed / redeem.confirmed / redeem.requested | (event_type, chain_id, tx_hash, log_index) | At most one delivery per chain log. Persist these four fields and reject duplicates. |
apy_change / tvl_alert | (event_type, slug, date) | At most one per product per day. |
vault_pause | (event_type, slug) | Re-emitted while status remains paused. |
Configure in Portal
- Open Portal → Webhooks
- Add a destination URL (HTTPS only — we won’t deliver to plain HTTP)
- Pick the events you want
- Copy the secret that appears once on creation. We hash it after that — there’s no way to retrieve it later, only rotate.
What about inbound webhooks?
Most partner integrations only need outbound events — we tell you when something changes on the chain or product side, and you react. If you have a hybrid flow where your system needs to push state into Barker (e.g. KYC tier promotion, off-chain reconciliation confirmation), there’s an authenticatedPOST /api/partner/webhooks/inbound endpoint — see the API Reference. Email us first if you think you need it; usually a normal API call is the simpler answer.