Webhooks and OAuth apps

Tell your systems the moment it happens

Webhooks send pushes, changes, reviews, runs, releases, deployments and agents' actions to your systems as they happen, signed and retried. OAuth apps work with Branchscope for a person, with their consent, or installed in an organization as themselves.

Webhooks

For a repository, an organization or an app

A repository's administrators add webhooks for its events, an organization's owners for every repository in it, and an app's webhook gets the events of every repository it's installed in. Choose the events, or take them all. The secret is shown once. Only people manage webhooks, or apps given webhooks:admin: agents can't send a repository's events out of Branchscope.

~/web
$ bscope webhook create -R acme/web --url https://ci.example.com/branchscope --event change.opened,review.completed
Added webhook 7 for acme/web: https://ci.example.com/branchscope
Events: change.opened, review.completed
Secret: whsec_…
This is the only time the secret is shown; verify deliveries with it.

Signatures

Signed the Standard Webhooks way

Each delivery carries webhook-id, webhook-timestamp and webhook-signature, an HMAC-SHA256 under the webhook's secret, as Standard Webhooks specifies, so existing libraries in many languages can check it. The TypeScript SDK's verifyWebhook does it in one call, and refuses deliveries more than 5 minutes old.

ci.example.com › receiver.ts
import { verifyWebhook } from "@branchscope/sdk";

// body: the raw request body, exactly as received
const event = await verifyWebhook(process.env.BRANCHSCOPE_WEBHOOK_SECRET!, request.headers, body);
if (event.event === "review.completed" && event.data.counts.violations > 0) {
  // …
}

webhook-id · webhook-timestamp · webhook-signature: v1,…

Delivery log

Retried for a day, and every attempt on record

Anything but a 2xx answer within 10 seconds is a failure, and is tried again over about a day; then the webhook is paused, with the reason on its page. A delivery can arrive more than once, with the same webhook-id to de-duplicate on. The log shows each delivery's status, attempts, response and error, keeps bodies for 7 days and deliveries for 30, and Redeliver and Send a ping send one now.

acme/web › Recent deliveries
  • Deliveredreview.completed1 attempt · HTTP 200 · 84 msRedeliver
  • Pendingchange.merged2 attempts · HTTP 503 · 120 msRedeliver

    HTTP 503

  • Failedpush.checked8 attemptsRedeliver

    redirected (302); webhooks don't follow redirects

Safety

Public addresses only, and no redirects

A webhook's URL must be https:// and resolve to public addresses only, checked when it's saved and again when each delivery connects; redirects aren't followed. With SECRETS_KEY set, its secret is encrypted at rest. A webhook only gets the events its creator can still see.

~/web
$ bscope webhook create --url http://ci.example.com/hook
bscope: a webhook's URL must be https://
$ bscope webhook create --url https://build.internal.example/hook
bscope: build.internal.example isn't a public address; webhooks only go to public HTTPS endpoints

OAuth apps

Apps that act for a person, or as themselves

An OAuth app acts for a person once they approve it on a consent page, limited to the scopes and repositories they chose, with tokens that last an hour; or an organization's owner installs it, and it acts as its own bot. Either way it's an agent: a ruleset that blocks agents, as main's does, blocks it too. MCP clients such as Claude Code sign in this way on their own, registering themselves with fewer scopes.

/oauth/authorize

Authorize Deploy Bot

Deploy Bot wants to act for you on Branchscope.

It will be able to:

  • ✓Read your repositories: code, history, changes and activity
  • ✓Open, close and merge changes, and re-run reviews
  • ✓Report checks, such as CI results, on commits

Which repositories

Only these: acme/web

AuthorizeCancel

Send your first event

Add a webhook under Settings → Webhooks, press Send a ping, and verify it with the secret.