Webhook Payloads
GitHub and Stripe webhook events that Scrubby receives — what they trigger, what payload fields are read, and what the responses look like.
Scrubby receives webhooks from two sources: GitHub (for the GitHub App and PR review flow) and Stripe (for billing). This page documents what events are handled and what each one triggers, so you can debug webhook-related issues from your side.
You don’t configure these webhooks — the GitHub App registration and Stripe integration set them up automatically. This page is reference material in case something looks off in your event logs.
GitHub webhooks
Endpoint: POST https://scrubby.ai/webhooks/github
Signature header: X-Hub-Signature-256 — verified via HMAC SHA-256 against the GitHub App’s webhook secret. Requests with invalid signatures are rejected with 401 Unauthorized before any handler runs.
pull_request
Triggered on PRs against repos where the GitHub App is installed.
Actions handled: opened, synchronize, reopened. Other actions (closed, edited, etc.) are ignored.
Triggers: Enqueues a AnalyzePrJob with:
installation_id(frominstallation.id)repo_full_name(fromrepository.full_name)pr_number(frompull_request.number)head_sha(frompull_request.head.sha)
The job creates a GitHub Check Run, fetches changed files, runs analysis, and posts findings. See Reviewing a Pull Request.
installation
Triggered when the GitHub App is installed, uninstalled, suspended, or unsuspended.
Actions handled:
| Action | Effect |
|---|---|
created | Creates GithubAppInstallation records for each repo in the install |
deleted | Marks all installation records removed |
suspend | Marks all installation records suspended |
unsuspend | Marks all installation records active |
installation_repositories
Triggered when repositories are added to or removed from an existing installation.
Effect:
repositories_added— creates aGithubAppInstallationrecord for each new repo (statusactive).repositories_removed— marks the existing recordremoved.
Stripe webhooks
Endpoint: POST https://scrubby.ai/webhooks/stripe
Signature header: Stripe-Signature — verified using the Stripe SDK’s Webhook.construct_event. Invalid signatures return 400 Bad Request.
Scrubby handles four event types:
| Event | Effect |
|---|---|
checkout.session.completed | Links a Stripe customer to the user’s Subscription, sets the plan and current period end, marks the user’s trial as used. |
customer.subscription.updated | Syncs plan, status, seat count, period end, and cancel-at-period-end flags from Stripe to the Subscription record. |
customer.subscription.deleted | Marks the Subscription canceled. |
invoice.payment_failed | Marks the Subscription past_due. |
Other Stripe events are silently ignored.
Failure modes
| Symptom | Likely cause |
|---|---|
| GitHub webhook returns 401 | Signature verification failed. Check that the GitHub App’s webhook secret matches the deployment. |
pull_request event received but no analysis runs | Action wasn’t one of opened, synchronize, reopened. Or the repo isn’t indexed yet. |
| Stripe webhook returns 400 | Invalid signature, malformed JSON, or wrong webhook secret. |
| Subscription doesn’t update after a Stripe event | The Stripe customer ID may not be linked to a Subscription yet. Try checkout.session.completed first. |
For per-symptom debugging, see PR Review Didn’t Run.
Last updated