Managing webhooks
Create, list, update, and delete repository webhooks.
client.webhooks provides full CRUD over a repository’s webhooks — create, list, get, update,
and delete. Requested events are gated against capabilities.webhookEvents, so an unsupported event
throws unsupported before any request is made.
Normalized events
repo-sdk normalizes webhook events to three types. Not every provider supports all three — the SDK maps
each to the provider’s native trigger:
| Event | Meaning | GitHub | GitLab | Bitbucket | Azure DevOps | Gitea |
|---|---|---|---|---|---|---|
push |
Commits pushed to a branch | ✓ | ✓ | ✓ | ✓ | ✓ |
tag_push |
A tag is created or deleted | ✓ | ✓ | ✓ | ✓ | ✓ |
release |
A release is published | ✓ | ✓ | ✗ | ✗ | ✓ |
Creating a webhook
const hook = await client.webhooks.create({
repo: 'capawesome-team/repo-sdk',
url: 'https://example.com/hooks/repo',
secret: process.env.WEBHOOK_SECRET,
events: ['push', 'tag_push', 'release'],
});
repo?string
The repository, in the provider path form.
stringurl?string
The endpoint the provider will POST events to.
stringevents?WebhookEventType[]
Events to subscribe to — 'push' | 'tag_push' | 'release'.
WebhookEventType[]secret?string
Signing/verification secret. Store it — you need the same value to verify incoming deliveries.
stringactive?boolean
Whether the hook is active. Defaults to true.
booleanListing, reading, updating, deleting
const { data: hooks } = await client.webhooks.list({ repo: 'capawesome-team/repo-sdk' });
const hook = await client.webhooks.get({ repo: 'capawesome-team/repo-sdk', id: hooks[0].id });
await client.webhooks.update({ repo: 'capawesome-team/repo-sdk', id: hook.id, active: false });
await client.webhooks.delete({ repo: 'capawesome-team/repo-sdk', id: hook.id });
A normalized Webhook is { id, url, events, active, raw }. On update, omitted fields are preserved:
the SDK reads the existing hook and merges, so you can change just active or just events without
wiping the URL or stored secret.
Secret handling
The secret is write-only. Providers never return it on read, so:
- Store the secret yourself when you create the hook — you need the same value to verify incoming deliveries.
- On
update, omitsecretto keep the stored one; pass it again only to rotate it.
Per-provider caveats
Next: Receiving webhooks
Verify signatures and parse incoming events.