Integrations

Webhooks

Webhooks are in beta: event coverage and payload fields may still change. A webhook sends a signed HTTPS request to your server when something happens in a repository or organization, such as a push, a new issue or a merged pull request.

Add a webhook

Repository admins open Settings → Webhooks in the repository; organization owners and admins open Webhooks in the organization's settings.

  1. Choose Add webhook.
  2. Enter your receiver's HTTPS URL and select events. All events subscribes to every supported event. To test a new receiver first, select only webhook.ping.
  3. Save, then copy the signing secret into your receiver. It is shown only once.
  4. Choose Manage, then Send signed ping, and check Delivery history to confirm your receiver accepted it.
  5. Edit the webhook to add the events you need.

A repository or organization can have up to ten webhooks.

From the terminal, pass an organization slug or owner/repo as the target:

sh
1cafe webhook create acme/project --url https://hooks.example.com/gitcafe \
2 --event issue.created --event pull.merged
3cafe webhook ping acme/project <webhook-id> --request-id first-ping --expected-version <version>

cafe webhook capabilities lists the supported events, and cafe webhook readiness checks whether a webhook is ready to send.

Events

EventsSent when
git.pushBranches or tags change by push, merge or sync
git.ref_created, git.ref_deletedBranches or tags are created or deleted
repo.default_branch_changedThe default branch changes
issue.created, issue.updated, issue.closed, issue.reopenedAn issue is created, edited, closed or reopened
issue.locked, issue.unlocked, issue.pinned, issue.unpinnedAn issue is locked, unlocked, pinned or unpinned
issue.assignees_updated, issue.labels_updated, issue.milestone_updatedAn issue's assignees, labels or milestone change
issue.linked, issue.unlinkedA pull request is linked to or unlinked from it
issue.comment_created, issue.comment_updated, issue.comment_deletedAn issue comment changes
issue.reaction_added, issue.reaction_removedA reaction is added or removed
pull.created, pull.updated, pull.closed, pull.reopenedA pull request is opened, edited, closed or reopened
pull.synchronizedA pull request's source branch gets new commits
pull.mergedA pull request merges in GitCafe
pull.drafted, pull.ready, pull.locked, pull.unlockedDraft or lock state changes
pull.reviewers_updated, pull.assignees_updatedReviewers or assignees change
pull.labels_updated, pull.milestone_updatedLabels or milestone change
pull.linked, pull.unlinkedAn issue is linked or unlinked
pull.review_submitted, pull.review_dismissedA review is submitted or dismissed
pull.comment_created, pull.comment_updated, pull.comment_deletedA pull request comment changes
pull.comment_hidden, pull.comment_unhiddenA comment is hidden or shown
pull.comment_resolved, pull.comment_unresolvedA review thread is resolved or reopened
pull.reaction_added, pull.reaction_removedA reaction is added or removed
label.created, label.updated, label.deletedA repository label changes
milestone.created, milestone.updated, milestone.deletedA milestone changes
ci.run_updatedA CI run's state changes
webhook.pingYou send a test ping

Events describe changes made in GitCafe. Issues and pull requests imported from GitHub do not send issue.* or pull.* events, and past activity is not sent when you add a webhook.

The request

Each delivery is an HTTPS POST with a JSON body. The body has an event id, a type, a timestamp, the repository and organization IDs, the actor who made the change, and a snapshot of the resource after the change. Edit events include the fields that changed. Text bodies longer than 65,536 characters are cut and flagged as truncated.

HeaderContains
X-GitCafe-EventThe event type, same as the body's type
X-GitCafe-DeliveryThe delivery ID, the same across retries
X-GitCafe-TimestampWhen this attempt was signed, in Unix seconds
X-GitCafe-Key-VersionWhich signing secret was used
X-GitCafe-Signaturesha256= followed by the hex HMAC

The full payload schemas are in the webhooks section of the OpenAPI description.

Verify the signature

Before you trust a request:

  1. Read X-GitCafe-Timestamp and reject it if it is too old for your liking.
  2. Compute HMAC-SHA256 with your signing secret over the timestamp, a literal ., and the raw request body bytes.
  3. Compare sha256=<lowercase hex digest> with X-GitCafe-Signature using a constant-time comparison.
js
1import { createHmac, timingSafeEqual } from "node:crypto";
2
3function verify(secret, timestamp, body, signature) {
4 const expected = `sha256=${createHmac("sha256", secret)
5 .update(`${timestamp}.`)
6 .update(body)
7 .digest("hex")}`;
8 return (
9 expected.length === signature.length &&
10 timingSafeEqual(Buffer.from(expected), Buffer.from(signature))
11 );
12}

Respond and handle retries

Return any 2xx status once you have stored the event. GitCafe retries on network errors, timeouts (10 seconds), 408, 425, 429 and 5xx, honouring Retry-After up to an hour, for up to eight attempts within 24 hours. Other statuses and redirects end the delivery.

Deliveries can arrive more than once and in any order. Deduplicate by the body's event id.

Inspect and redeliver

Under Manage, Delivery history shows each delivery's state, attempts and HTTP status; View attempts and View payload show the details. For a delivery that finally failed, fix your receiver, then choose Request redelivery to send the same event again. Each event can be redelivered twice, within 30 days.

sh
1cafe webhook deliveries acme/project <webhook-id> --state failed
2cafe webhook redeliver acme/project <webhook-id> <delivery-id> \
3 --request-id retry-1 --expected-version <version> --event-created-at <timestamp>

Delivery history is kept for 30 days.

Rotate the signing secret

Choose Rotate signing secret under More actions, or run cafe webhook rotate-secret <target> <webhook-id> --yes. The new secret is shown once. From then on every attempt, including retries of earlier events, is signed with the new secret, so update your receiver straight away. X-GitCafe-Key-Version tells you which secret signed a request.

Stop a webhook

Disable it to pause deliveries, or delete it under More actions. Both stop pending deliveries. Changing a repository's visibility or removing the person who created a webhook does not remove it; webhooks can carry private repository data, so review them when access changes.

Read as MarkdownGitCafe documentation
Documentation