Skip to main content

Webhooks

Webhooks allow you to build or set up integrations which subscribe to certain events on JJHub. When one of those events is triggered, we’ll send a HTTP POST payload to the webhook’s configured URL. Webhooks can be used to update an external issue tracker, trigger CI builds, update a backup mirror, or even deploy to your production server.

API Endpoints

MethodEndpointDescription
GET/api/repos/{owner}/{repo}/hooksList webhooks
GET/api/repos/{owner}/{repo}/hooks/{id}Get a webhook
POST/api/repos/{owner}/{repo}/hooksCreate a webhook
PATCH/api/repos/{owner}/{repo}/hooks/{id}Update a webhook
DELETE/api/repos/{owner}/{repo}/hooks/{id}Delete a webhook
GET/api/repos/{owner}/{repo}/hooks/{id}/deliveriesList delivery history
POST/api/repos/{owner}/{repo}/hooks/{id}/deliveries/{delivery_id}/replayReplay a delivery

Create a Webhook

To create a webhook, send a POST request to the hooks endpoint:
curl -X POST https://api.jjhub.tech/api/repos/alice/my-project/hooks \
  -H "Authorization: token jjhub_xxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "config": {
      "url": "https://example.com/webhook",
      "content_type": "json",
      "secret": "your-secret-key"
    },
    "events": ["push", "landing_request"],
    "active": true
  }'

Configuration Options

FieldTypeRequiredDescription
config.urlstringYesThe URL to which the payloads will be delivered.
config.content_typestringNoThe media type used to serialize the payloads. Supported: json.
config.secretstringNoIf provided, payloads will be signed with an HMAC-SHA256 signature.
eventsarrayNoA list of events which should trigger the webhook. Default: ["push"]. Use ["*"] for all events.
activebooleanNoDetermines if the webhook is active. Default: true.

Event Types

JJHub currently supports the following event types:
EventDescription
pushCode is pushed to a bookmark.
createA bookmark or tag is created.
deleteA bookmark or tag is deleted.
landing_requestLanding request activity (opened, closed, updated).
issueIssue activity (opened, closed, labeled).
issue_commentComment activity on an issue.
statusCommit status update.
workflow_runWorkflow run completion.
releaseA new release is created or updated.

Payload Format

All webhook payloads are sent as JSON in the request body. Every payload includes information about the repository and the user who triggered the event.

Example: push event

{
  "action": "pushed",
  "ref": "main",
  "before": "abc123def...",
  "after": "def456abc...",
  "repository": {
    "id": 123,
    "name": "my-project",
    "full_name": "alice/my-project",
    "owner": {
      "login": "alice",
      "id": 1
    }
  },
  "sender": {
    "login": "alice",
    "id": 1
  }
}

Security

If a secret is configured, JJHub signs every delivery with an HMAC-SHA256 signature. The signature is sent in the X-JJHub-Signature-256 header.

Verifying Signatures

To verify a signature, compute the HMAC-SHA256 of the request body using your webhook secret as the key. The result should match the value in the header (prefixed with sha256=).
const crypto = require('crypto');

function verifySignature(payload, secret, signature) {
  const hmac = crypto.createHmac('sha256', secret);
  const digest = 'sha256=' + hmac.update(payload).digest('hex');
  return crypto.timingSafeEqual(Buffer.from(digest), Buffer.from(signature));
}

Delivery Headers

JJHub includes several headers in every delivery to help you identify and process the event:
HeaderDescription
X-JJHub-EventThe name of the event type (e.g., push).
X-JJHub-DeliveryA unique ID for the delivery.
X-JJHub-Signature-256The HMAC-SHA256 signature (if secret is set).
User-AgentAlways starts with JJHub-Hookshot/.

Retries

If your server responds with a non-2xx status code, JJHub will attempt to redeliver the payload up to 5 times with exponential backoff. If a webhook fails consistently for several days, it may be automatically disabled. You will receive an email notification if this happens.