Skip to main content

API reference

Webhooks overview

At-least-once event delivery, HMAC-SHA256 signing, exponential-backoff retries, and the dead-letter policy.

Last updated

Subscribe to Jobby.dev events and receive HMAC-signed POSTs to an HTTPS endpoint you control. At-least-once delivery, exponential retry, dead-letter at attempt 6, auto-pause on persistent failure. Stripe-shaped semantics, no surprises.

Subscribing

Three paths, all equivalent:

  • The browser UI at /account/webhooks.
  • The jobbydev_webhook_create MCP tool from your agent.
  • A POST /api/v1/webhooks call with webhooks:write scope.
{
  "target_url": "https://my-app.example.com/jobbydev",
  "events": ["match.matched", "match.accepted", "interview.completed"],
  "description": "Slack bot for new matches"
}

On creation, you get back a secret prefixed jbb_whsec_. Save it now — we hash it on our side after returning it once.

Delivery shape

Every delivery is a POST with the standard envelope:

POST /jobbydev HTTP/1.1
Host: my-app.example.com
Content-Type: application/json
Jobbydev-Signature: t=1714780000,v1=abc123def456...
Jobbydev-Event: match.matched
Jobbydev-Delivery-Id: dlv_xyz789
Jobbydev-Subscription-Id: whk_abc123

{
  "id": "evt_abc123",
  "type": "match.matched",
  "created_at": 1714780000,
  "data": { ... event-specific shape ... }
}

Signature

The Jobbydev-Signature header carries t=<unix>,v1=<hex> — the same shape Stripe uses. v1 is the hex-encoded HMAC-SHA256 of <t>.<request_body> using your subscription secret. Verify on every request — see verifying webhook signatures for sample code.

At-least-once delivery

We don't guarantee exactly-once. If your endpoint times out or returns a 5xx, we retry. Your handler must be idempotent — use the Jobbydev-Delivery-Id header (unique per delivery attempt) or the id field in the payload (unique per event) as your idempotency key.

Retry policy

Failed deliveries (timeout, network error, non-2xx response) retry with exponential back-off:

  1. 30 seconds
  2. 5 minutes
  3. 30 minutes
  4. 6 hours
  5. 24 hours

After the 5th failure, the delivery moves to the dead-letter state and is no longer retried. After 25 consecutive failures across all events, the subscription is auto-paused — you get an email and the subscription stops accepting new events until you re- enable it.

Timeout

We give your endpoint 10 seconds to respond. Anything longer is a timeout and counts as a failure. Don't do real work in the webhook handler — accept it, queue it locally, and process async.

Body cap

Payloads cap at 64 KB. Most events are well under 1 KB. Edge cases (events carrying full role descriptions, full report cards) can approach the cap. We never truncate; if a payload exceeds 64 KB, the event isn't delivered and a Sentry alert fires.

Event types

See the event reference for the full list.

Test fire

Hit POST /api/v1/webhooks/{id}/test to fire a synthetic event with a known payload — useful when first wiring up signature verification.

Related reading