Field notes
How GitHub behaves, and where it bites
Good headers, a delivery id, and a redelivery button that only reaches back so far.
How GitHub sends
GitHub POSTs JSON with the event in X-GitHub-Event (push, pull_request, issues), a unique X-GitHub-Delivery, and an HMAC in X-Hub-Signature-256 prefixed sha256=. A new hook gets a ping first.
Where it bites
- The delivery log is not an archive. GitHub shows recent deliveries per hook. Older ones age out, and with them the ability to redeliver.
- Hooks multiply. Repository, organisation and app-level hooks all fire, and tracing which one delivered what means opening each in turn.
- The event name is in a header, not the body. Anything that logs only the JSON loses the event type, which is the first thing you want when searching.
The vault under it
Point a WebhookVault endpoint at GitHub and every delivery is stored in full: headers verbatim, bodies byte-for-byte, labelled with its event name and searchable. Forward it onward to your own handler if you want the relay pattern, replay any delivery once the bug is fixed, and let a Watchdog notice the day it stops arriving.
Create an endpoint
Name it github-ci. Turn on forwarding to your own handler if you want the vault in front of it rather than beside it.
Register the capture URL
Repository or organisation Settings → Webhooks → Add webhook. Content type application/json, paste the capture URL, set a secret.
Keep everything
Every delivery from here on is on the shelf: searchable, replayable, and watched for the day it goes quiet.
Verify from the record, not just at the door
GitHub signs the raw body with your webhook secret and sends the digest as lowercase hex behind a sha256= prefix. The vault strips the prefix and verifies every capture.
The vault stores the signature headers verbatim with every request, so a delivery from last month can still be checked today. Verdicts are part of Solo and up. How verification works →
# headers, stored verbatim "X-GitHub-Event": "pull_request" "X-GitHub-Delivery": "4a2f8c10-b3d1-…" "X-Hub-Signature-256": "sha256=8f3a2c41d9e6…" { "action": "opened", "number": 142, "pull_request": { "title": "Cap compute array items", "user": { "login": "hannibalza" } } }
Event catalogue
GitHub webhook events you'll see
A few of the events GitHub sends, not the full list: GitHub's own documentation has every one. Each arrives in the vault labelled with its event name.
| Event | What it tells you |
|---|---|
| ping | Sent once when the hook is created, to confirm the URL answers. |
| push | Commits or tags were pushed. |
| pull_request | A pull request was opened, closed, given new commits or otherwise changed; action says which. |
| issues | An issue was opened, edited, closed or labelled. |
| release | A release was published, edited or deleted. |
| workflow_run | A GitHub Actions workflow run was requested, started or completed. |
Questions
GitHub webhook questions, answered
The three that come up most when GitHub is wired to a new endpoint.
Does GitHub retry failed webhook deliveries?
No. GitHub makes one attempt, expects a response within ten seconds, and records the result. A failed delivery can be redelivered by hand from the hook's Recent Deliveries, or through the REST API, but only for the past three days. With a WebhookVault capture URL in front, every delivery is stored as it lands and can be replayed to your handler at any point in your retention window.
How do I verify X-Hub-Signature-256?
Compute HMAC-SHA256 over the raw body with the webhook secret, hex-encode it, prefix it with sha256= and compare it with the header in constant time. The older X-Hub-Signature header carries a SHA-1 version kept for compatibility. On Solo and up the vault does this at capture and puts the verdict on every row.
What is the ping event?
GitHub sends ping once when a webhook is created, carrying the hook's id and a line of zen, to check that the URL answers. It is an ordinary delivery: the vault stores it like any other, which makes it the quickest proof that a new hook reaches the endpoint.
Keep the deliveries GitHub forgets.
Free tier, no card. A capture URL in a few minutes.
Sign up with GitHub, Google or email. Two-factor authentication is required on every account, Free included, for account security.