Skip to main content
Delivery is in calibration. Registration, signing, test events and replay all work today, but live delivery to public endpoints is gated until the verdict rule confirms calibration v1 on 2026-06-11. Register and test now — production delivery switches on at the gate.
Webhooks deliver state transitions to your URL within seconds of the engine detecting them. Every payload is signed with Ed25519 so you can verify authenticity without trusting the transport.

Why webhooks (vs WebSocket)

  • WebSocket — you hold a connection. Best for read-only consumers with strict freshness needs (dashboards, agent runtimes).
  • Webhooks — we push to your URL. Best for fire-and-forget reactions (notifications, automated risk pauses, audit logging). No connection to maintain.
For most B2B integrations (lending protocol pausing collateral, insurance trigger, prediction-market settlement) webhooks are the right fit.

Quickstart

  1. Register a webhook via the dashboard at pegana.xyz/account/webhooks. Telegram Login required.
  2. Implement signature verification at your endpoint (see signing).
  3. Test with the dashboard’s “Send test event” button.
Or via API:
curl -X POST https://api.pegana.xyz/v1/me/webhooks \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://your-domain.com/pegana-hook",
    "asset": "USDC",
    "threshold_bps": 50
  }'

Payload shape

The body is JSON, exactly:
{
  "asset": "sUSDe",
  "from_state": "PEGGED",
  "to_state": "DRIFT",
  "discount_bps": -47,
  "ts": "2026-05-26T22:55:00Z",
  "alert_id": "550e8400-e29b-41d4-a716-446655440000"
}
FieldTypeNotes
assetstringSymbol (e.g. USDC, jitoSOL)
from_statestringOne of PEGGED, DRIFT, DEPEG, CRITICAL, BLACK_SWAN, UNKNOWN
to_statestringSame enum
discount_bpsintegerSpread at trigger, basis points, signed
tsstringISO 8601 timestamp of the state change
alert_idstringUUID. Use for idempotency.

HTTP headers we send

POST /your-path HTTP/1.1
Host: your-domain.com
Content-Type: application/json
User-Agent: Pegana/0.1.0
x-pegana-timestamp: 1779889253
x-pegana-signature: ed25519:<base64 64-byte sig>
x-pegana-event-id: 550e8400-e29b-41d4-a716-446655440000
x-pegana-delivery-id: 9d6b420f-3f92-476a-b237-f465d29a57f8
x-pegana-attempt: 1/6

<JSON body>
Note the ed25519: prefix on the signature value — your verifier strips it before base64-decoding. See signing for the full algorithm. We do not ship the public key in a header on every request. Active keys are published at https://api.pegana.xyz/v1/meta/webhook-keys; your verifier should cache that list or read it from an env override.

URL requirements

  • Must be https:// — we refuse HTTP
  • We SSRF-guard the URL: rejects private IP ranges (10.x, 172.16.x, 192.168.x), localhost, *.local, *.internal, and metadata endpoints
  • Returns must be 2xx for the delivery to count as successful. 3xx redirects are not followed
  • We expect a response within 10 seconds. Beyond that, treated as failed and retried

What to do in your handler

A robust receiver does three things, in order:
  1. Verify the signature (webhooks-signing)
  2. Check x-pegana-timestamp is within ±300 seconds of now (replay protection)
  3. Idempotency: check x-pegana-event-id against your local record — if seen already, return 200 OK without re-acting
After those three, your business logic can act on the payload — pause collateral, fire a notification, settle a position.

Retry policy

Failures (non-2xx, timeout, TLS error) trigger retries. Dispatcher config (crates/dispatcher-rs/src/main.rs): max_attempts: 6, backoffs [5s, 30s, 5m, 30m, 2h].
AttemptWait before this attempt
1 (initial)0s
25s
330s
45m
530m
62h
After the 6th failure (~2h35m total), the delivery is logged as failed and written to the webhook dead-letter queue. Your endpoint can inspect delivery history or manually replay missed events. See retry policy.

Example receivers

We ship reference receivers in three languages, each with full verification logic (production code, not docs prose):

TypeScript / Cloudflare Worker

Web Crypto API. Works on edge, Vercel functions, Node 18+.

Rust / axum

ed25519-dalek strict-mode verification.

Python / FastAPI

cryptography library.

Listing and managing webhooks

# List
curl https://api.pegana.xyz/v1/me/webhooks \
  -H "Authorization: Bearer $JWT"

# Delete (soft, sets is_active = false)
curl -X DELETE https://api.pegana.xyz/v1/me/webhooks/$ID \
  -H "Authorization: Bearer $JWT"
The dashboard UI at pegana.xyz/account/webhooks exposes the same actions plus delivery history.

Next

Signing details

Ed25519 algorithm, signing input format, public key.

Retry policy

Failure modes, backoff schedule, and replay.