Guides

Webhooks

Receive delivery, creative, billing, and reporting events at an HTTPS endpoint you register. Each webhook includes a signed JSON payload. Failed deliveries are retried, and signing keys can rotate with an overlap period.

Payload

Use webhooks when another application needs to respond to a change without repeatedly polling Riptide. A creative-approval event, for example, can update your team's review queue. The payload below identifies the event and creative; verify its signature and deduplicate its ID before acting on it.

POST https://hooks.acme.example/riptide
Content-Type: application/json
X-Riptide-Webhook-Timestamp: 1767225600
X-Riptide-Webhook-Signature-256: t=1767225600,v1=9f2c...e1

{ "id": "evt_01J...", "type": "creative.approved", "occurred_at": "2026-01-01T00:00:00Z",
  "tenant_id": "1c9e...", "data": { "creative_id": "...", "ref": "spring-15s" } }
Event typeWhen
delivery.impression, delivery.clickPer-event delivery notifications (subscribe narrowly; volume follows traffic).
delivery.line_item_endedA line item reached its end date or goal.
delivery.alert_firedA delivery alert rule fired (under-delivery, pacing, error rate).
creative.approved, creative.rejectedCreative review outcomes.
billing.invoice_created, billing.payment_failedAn invoice was created or a payment failed.
reporting.scheduled_report_deliveredA scheduled report's result was delivered.

Verify the signature

Each v1 value is HMAC-SHA256(secret, "<timestamp>.<raw body>"), hex encoded. Recompute it under your secret over the exact bytes received, accept when any v1 matches, and require the timestamp to be within five minutes of your current time. Deduplicate accepted events by ID before processing them. During rotation, the header carries two v1 values, with the current secret first.

// Go (reference verifier in the repository: libs/webhooks)
mac := hmac.New(sha256.New, secret)
mac.Write([]byte(ts + "." + string(body)))
ok := hmac.Equal(mac.Sum(nil), providedV1)

# Python
expected = hmac.new(secret, f"{ts}.".encode() + body, hashlib.sha256).hexdigest()
ok = any(hmac.compare_digest(expected, v1) for v1 in provided_v1s) and abs(time.time() - int(ts)) < 300

Retries and rotation

The default policy allows five delivery attempts in total. After a non-2xx response or timeout, retries wait 30 seconds, 1 minute, 2 minutes, and 4 minutes. After the last failed attempt, replay the delivery from the API or console once you have fixed the cause. Call rotateWebhookSecret to receive a new secret. Both secrets sign deliveries during the grace period, allowing your receiver to switch keys.

OperationPurpose
createWebhookSubscriptionRegister the URL and event types. Save the signing secret returned in the response; it is shown once.
listWebhookSubscriptions, getWebhookSubscription, updateWebhookSubscription, deleteWebhookSubscriptionManage subscriptions.
listWebhookDeliveries, replayWebhookDeliveryInspect attempts and replay a delivery by id.
rotateWebhookSecretStart a rotation: deliveries carry two signatures until the grace window ends.

Connect a webhook receiver

Start with a receiver that verifies signatures and stores accepted events. Use the Python SDK to register its public HTTPS endpoint and the event types your application needs.