Guides

Sending your first event

A complete walkthrough from creating a subscription to seeing a delivery land.

Sending your first event

This guide goes further than the Quickstart: you will create a real subscription, publish to it, and read the delivery log.

1

Create a subscription

A subscription binds an event-type pattern to a URL.

curl https://api.kestrel.dev/v1/subscriptions \
  -H "Authorization: Bearer $KESTREL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://example.com/webhooks/kestrel",
    "eventTypes": ["invoice.*"],
    "description": "Billing service"
  }'

The response includes signingSecret. It is shown once — store it in a secret manager now.

2

Publish an event

curl https://api.kestrel.dev/v1/events \
  -H "Authorization: Bearer $KESTREL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "type": "invoice.paid", "payload": { "invoiceId": "in_1024" } }'
3

Check the delivery

curl "https://api.kestrel.dev/v1/deliveries?eventId=evt_01HZX9K2QW" \
  -H "Authorization: Bearer $KESTREL_API_KEY"

A successful delivery looks like this:

{
  "data": [
    {
      "id": "dlv_01HZX9M4TT",
      "eventId": "evt_01HZX9K2QW",
      "subscriptionId": "sub_8213",
      "status": "succeeded",
      "attempts": 1,
      "responseStatus": 200,
      "durationMs": 143
    }
  ]
}

Wildcards

eventTypes accepts a * in the last segment only.

PatternMatchesDoes not match
invoice.*invoice.paid, invoice.voidedinvoice.line.added
invoice.line.*invoice.line.addedinvoice.paid
*every event type—

A subscription may list up to 25 patterns. Beyond that, create a second subscription pointing at the same URL.

Local development

Kestrel cannot reach localhost, so use a tunnel (ngrok, cloudflared, localtunnel or Tailscale Funnel works) and point the subscription at the public URL it gives you. Delete the subscription when you are done — disabled subscriptions still count against your plan's subscription limit.

Next: Handling failures.