Skip to content

Webhooks API

OpenCodeHub supports outbound webhooks for event-driven integrations with external services like Slack, Discord, CI systems, and custom applications.

EventDescription
pushCode pushed to a branch
pull_request.openedPR created
pull_request.closedPR merged or closed
pull_request.reviewedReview submitted on a PR
issues.openedIssue created
issues.closedIssue closed
release.publishedRelease published
merge_queue.mergedPR merged via queue
merge_queue.failedQueue merge failed
repository.createdNew repository created
POST /api/repos/{owner}/{repo}/webhooks

Body:

{
"url": "https://yourapp.com/webhook",
"events": ["push", "pull_request.opened"],
"secret": "your-webhook-secret",
"active": true
}
GET /api/repos/{owner}/{repo}/webhooks
POST /api/repos/{owner}/{repo}/webhooks/{id}/test

All payloads follow this structure:

{
"event": "pull_request.opened",
"repository": {
"id": "repo_123",
"name": "my-repo",
"owner": "alice"
},
"sender": {
"id": "usr_456",
"username": "alice"
},
"timestamp": "2024-01-15T10:30:00Z",
"data": { ... }
}

Webhooks are signed with HMAC-SHA256 using the configured secret.

Node.js:

const crypto = require('crypto');
function verifyWebhook(payload, signature, secret) {
const expected = crypto
.createHmac('sha256', secret)
.update(payload, 'utf8')
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(`sha256=${expected}`)
);
}
  1. Use HTTPS URLs only
  2. Always verify the HMAC signature
  3. Handle duplicate deliveries with idempotency keys
  4. Respond quickly (return 200 immediately)
  5. Never leave the webhook secret empty