WebhooksEvents & payloads

Events & payloads

The envelope

Every webhook is the same JSON envelope. The event-specific data is in data:

{
  "id": "0191...e7",
  "tenant_id": "550e8400-e29b-41d4-a716-446655440000",
  "event_type": "order.paid",
  "created_at": "2026-06-10T14:30:45.123Z",
  "data": { "order_id": "0191...a1" }
}
FieldMeaning
idThe delivery id (UUID). Matches the X-Orchard-Delivery header. Your idempotency key.
tenant_idYour tenant.
event_typeOne of the events below. Matches the X-Orchard-Event header.
created_atISO-8601 timestamp the envelope was built.
dataEvent-specific payload (see each event below).

Headers

Every POST carries:

HeaderValue
Content-Typeapplication/json
X-Orchard-Eventthe event_type
X-Orchard-Deliverythe delivery id (idempotency key)
X-Orchard-Signaturet=<unix_seconds>,v1=<hex_hmac> — see Verifying signatures

Event catalog

Payloads are intentionally thin — they identify the entity; fetch the full object from the API when you need detail. All ids are UUIDs unless noted.

EventWhendata
order.paidAn order’s payment is captured{ order_id }
order.refundedA refund is recorded against an order{ order_id, refund_id, amount_cents, currency }
subscription.createdA subscription is created{ stripe_subscription_id, status }
subscription.updatedA subscription changes (plan, status, pause, period){ stripe_subscription_id, status }
subscription.canceledA subscription is canceled{ stripe_subscription_id, status }
webhook.pingYou clicked Test in the admin{ message, endpoint_id, sent_at }

Notes

  • amount_cents is an integer in the smallest currency unit (e.g. 4200 = $42.00); currency is a lowercase ISO code (e.g. "usd").
  • Subscription events key on stripe_subscription_id (sub_…) and carry the current status (active, past_due, paused, canceled, …). Treat them as a state snapshot — act on the latest, not on event ordering.
  • order.canceled is a reserved event type but is not currently emitted (there is no cancellation trigger wired yet). Don’t rely on receiving it.

Fetching detail

A thin payload gives you the id; resolve the rest through the API. For example, after order.paid:

curl https://api.theorchard.dev/api/v1/orders/<order_id> \
  -H "Authorization: Bearer sk_live_your_key"

See the API Reference for the order, refund, and subscription shapes.