Webhooks
Two directions: Stripe events into COLVO for verification and reconciliation, and COLVO alerts out to Slack, email or your own webhook.
Inbound: Stripe → COLVO
When you connect a Stripe account to a project, COLVO gives you a webhook endpoint for that connection:
POST https://colvo.app/v1/webhooks/stripe/{connection_id}Add it in the Stripe dashboard with the signing secret shown once in COLVO. Events are signature-verified (stripe-signature), appended to a durable inbox and processed by the worker; a missing or invalid signature is refused (400), bodies over 1 MB too (413). Subscribe to refund.created, refund.updated, charge.refunded, customer.subscription.updated and customer.subscription.deleted (the Connect Stripe screen lists them). Events feed verification and reconciliation; COLVO never acts on an unsigned event.
Paddle. Add a notification destination in Paddle with the URL COLVO shows (/v1/webhooks/paddle/{connection_id}) and the events adjustment.created, adjustment.updated, subscription.updated, subscription.canceled, subscription.paused, subscription.resumed. The Paddle-Signature header is verified with the destination’s secret key (timestamps older than 5 minutes are refused). adjustment.updated finishes a refund that was waiting for Paddle’s review; a rejected refund opens an incident and releases the budget.
Chargebee. Chargebee protects webhooks with HTTP basic auth instead of a signature: add a webhook in Chargebee with the URL (/v1/webhooks/chargebee/{connection_id}), the username colvo and the password COLVO showed when you connected, and the events credit_note_created, payment_refunded, subscription_cancellation_scheduled, subscription_cancelled, subscription_scheduled_cancellation_removed, subscription_paused, subscription_pause_scheduled, subscription_resumed, subscription_scheduled_pause_removed, subscription_changed. A wrong or missing password is refused (401). Events are hints: verification always re-reads Chargebee.
Changes made outside COLVO
A refund or cancellation that no COLVO operation or observation accounts for — an old key still in the agent, a manual refund in the Dashboard — opens an UNEXPECTED_ACTION incident and fires your alerts, after a one-minute second look (our own write may still be committing). Per connection: auto (default: alert once Guard has executed on this account, so observation-only connections stay quiet), alert or ignore — PATCH /v1/projects/{id}/connections/{connection_id} with { "out_of_band": "alert" }, or the select on the project page.
Outbound: alert channels
GET / POST /v1/alert-channels, DELETE /v1/alert-channels/{id}, POST /v1/alert-channels/{id}/test. Per project; events: run.failed, incident.opened, drift.detected, cap.threshold, approval.requested, approval.reminder, approval.expired.
{ "project_id": "…", "name": "ops", "events": ["run.failed", "incident.opened"],
"config": { "kind": "webhook", "url": "https://yourco.example/hooks/colvo", "secret": "optional shared secret" } }
// kinds: "slack" { webhook_url } · "email" { to: [...] } · "webhook" { url, secret? }Webhook deliveries are JSON with an X-Colvo-Signature HMAC-SHA256 header when a secret is set, and retried with backoff. Slack uses an incoming-webhook URL; email uses Resend with COLVO’s branded template.