Webhooks
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.
Configure
Section titled “Configure”In Settings → Webhooks or via API:
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 ornullfor all events. Build events arebuild: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) andbuild:cancelled(a user cancelled the build, see Builds; the payload is{ buildId, status: "cancelled" }). Review addsreview:requested,review:commentandreview:verdict(see Review).secret— HMAC secret; stored AES-256-GCM encrypted with serverSECRET.
Manage via GET /api/v1/projects/:slug/webhooks and DELETE. See POST /api/v1/projects/:slug/webhooks in the OpenAPI.
Delivery
Section titled “Delivery”- Payload is JSON
{ event, project: { slug }, build: { id, gitSha, gitBranch, status } }. - Header
X-StoryShelf-Signature: sha256=<hmac>— verify with the sharedsecret(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/mrlabels 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.
Related
Section titled “Related”- Project settings — where webhooks are managed
- Builds & snapshots — statuses that trigger events
- REST API — endpoint walkthrough