Skip to content

Webhooks

View as Markdown

StoryShelf posts outbound webhooks per project — e.g. build started, approved, rejected, failed — so you can notify Slack, Linear, or a custom service without polling.

In Settings → Webhooks or via API:

Terminal window
curl -X POST $SHELF/api/v1/projects/my-app/webhooks \
-H "Authorization: Bearer $STORYSHELF_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "url": "https://hooks.example.com/shelf", "events": ["build.approved", "build.failed"], "secret": "whsec_..." }'
  • url — HTTPS endpoint (must be reachable from the server).
  • events — JSON array filter or null for all events. Build events are build:created, build:reviewing, build:approved, build:rejected, build:pending (a verdict sent a build back to pending, for example when a rejecting reviewer rewrites to an approval and too few approvals remain) and build:cancelled (a user cancelled the build, see Builds; the payload is { buildId, status: "cancelled" }). Review adds review:requested, review:comment and review:verdict (see Review).
  • secret — HMAC secret; stored AES-256-GCM encrypted with server SECRET.

Manage via GET /api/v1/projects/:slug/webhooks and DELETE. See POST /api/v1/projects/:slug/webhooks in the OpenAPI.

  • Payload is JSON { event, project: { slug }, build: { id, gitSha, gitBranch, status } }.
  • Header X-StoryShelf-Signature: sha256=<hmac> — verify with the shared secret (HMAC-SHA256 of the raw body).
  • Retries: transient 5xx / network errors are retried with backoff; 4xx is not retried. Delivery logs are not yet exposed beyond capture logs — track separately if you need audit.
  • Use label filters in your receiver (pr/mr labels on the build) to route PR webhooks to the right channel.
  • For local dev, expose a tunnel (e.g. ngrok) and point the webhook URL at it.
  • Webhooks respect auth — creating them requires project admin.