Webhooks
GitHub Webhooks allow developers to receive real-time notifications about events happening within their repository, such as commits, pull requests.
GitHub Webhooks allow developers to receive real-time notifications about events happening within their repository, such as commits, pull requests, and issues. These webhooks enable users to automate tasks, integrate with other services, and build custom workflows.
A webhook is an HTTP POST
When something happens, GitHub sends a POST to a URL you registered, with a JSON body describing the event, a delivery id, and a signature header. That is the whole mechanism: there is no SDK required to receive one.
{
"action": "opened",
"repository": { "full_name": "owner/repo" },
"pull_request": { "number": 412, "title": "Fix login redirect" },
"sender": { "login": "vicky" }
}
Verify the signature, always
The header is X-Hub-Signature-256, an HMAC of the raw body keyed by the secret
you configured. Skipping this check means anyone who learns your URL can forge
any event.
import hashlib, hmac
def verify(body: bytes, header: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, header)
Compute it over the raw request body, before any JSON parsing — re-serialising changes the bytes and the hash will not match.
Respond quickly
GitHub gives you ten seconds. A handler that does real work in the request will time out, and GitHub marks the delivery as failed and retries. Acknowledge first, queue the work:
@app.post("/webhook")
def webhook():
queue.push(request.get_data(), request.headers["X-Hub-Signature-256"])
return "", 202
Retries and the dead letter
Failed deliveries are retried with backoff over roughly a day, then given up on. Keep the delivery id and ignore the ones you have already handled, or a retry will process the same event twice.
Under Settings → Webhooks → Advanced you can see every delivery attempt with its response, and redeliver any of them by hand.
Webhooks versus GitHub Actions
For a repository you control, prefer Actions. on: pull_request is a webhook
that GitHub hosts for you, with retries, logs and no server to run:
on:
pull_request:
types: [opened, synchronize]
See GitHub Actions. Webhooks are the tool when the receiving end is not your repository — an external service that needs to know something happened. See GitHub Apps for the case where you also want to act back on GitHub.
Free Resources
official: