Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/paramveer-cyber/Deployaar/llms.txt

Use this file to discover all available pages before exploring further.

When you install the Deployaar GitHub App on a repository, Deployaar registers a webhook URL with your GitHub App. Whenever GitHub sends an event — such as a pull request being opened or a new commit pushed to an open PR — GitHub delivers a signed HTTP POST to POST /api/github/webhook. Deployaar verifies the payload’s HMAC-SHA256 signature, deduplicates the delivery using the x-github-delivery GUID, and dispatches the event to the appropriate internal handler. Routable events are forwarded to Inngest to trigger the full automated PR review workflow.

Endpoint

POST /api/github/webhook
The route uses express.raw({ type: 'application/json' }) so the raw request bytes are preserved exactly as GitHub sent them. This is required for signature verification — any middleware that parses the body before this route will corrupt the HMAC check.

Required Headers

HeaderDescription
x-hub-signature-256HMAC-SHA256 signature of the raw request body, prefixed with sha256=. Computed by GitHub using your GITHUB_WEBHOOK_SECRET.
x-github-eventThe GitHub event name (e.g. pull_request, issues).
x-github-deliveryA unique UUID identifying this delivery. Deployaar stores this to prevent duplicate processing.
Content-TypeMust be application/json.
If any of x-hub-signature-256, x-github-event, or x-github-delivery are absent, the request is rejected immediately with a 401.

Signature Verification

Deployaar calls app.webhooks.verify(rawBody, signature) via the Octokit GitHub App SDK. Under the hood this computes:
HMAC-SHA256(key=GITHUB_WEBHOOK_SECRET, message=<raw request body>)
The resulting hex digest is compared to the value in the x-hub-signature-256 header (after stripping the sha256= prefix). If the signatures do not match, a 401 {"error": "Invalid signature"} is returned immediately and no further processing occurs. The environment variable GITHUB_WEBHOOK_SECRET must exactly match the secret configured in your GitHub App settings.

Handled Events

Deployaar checks each delivery for idempotency before acting on it. The x-github-delivery GUID is looked up in the github_webhook_deliveries table; duplicate deliveries are silently acknowledged without re-processing.
EventActionsBehavior
pull_requestopened, synchronize, reopenedMatched against a known project repository. If matched, sends the github/pull-request.received event to Inngest, which triggers the automated AI PR review workflow.
issuesopened, editedMatched against a known project repository. If matched, sends the github/issue.received event to Inngest.
Any other eventAcknowledged with 200 {"received": true}. No workflow is triggered.
Deployaar silently ignores events for repositories that are not linked to any project. The pull_request and issues events are cross-referenced against the project_repositories table using the repository.full_name field in the webhook payload. Unrecognised repos are dropped without an error response.
When a pull_request event with a routable action is dispatched, the following data is extracted from the payload and forwarded to Inngest:
{
  "name": "github/pull-request.received",
  "data": {
    "projectId": "<matched project UUID>",
    "repoFullName": "owner/repo",
    "installationId": 12345678,
    "action": "opened",
    "prNumber": 42,
    "prTitle": "feat: add dark mode toggle",
    "prBody": "Closes #17",
    "headSha": "a1b2c3d4...",
    "headBranch": "feat/dark-mode",
    "baseBranch": "main"
  }
}

Response Codes

StatusBodyMeaning
200{"received": true}Event received and processed (or acknowledged with no action).
401{"error": "Missing required headers"}One or more of x-hub-signature-256, x-github-event, or x-github-delivery are absent.
401{"error": "Invalid signature"}HMAC-SHA256 verification failed. The payload may have been tampered with, or GITHUB_WEBHOOK_SECRET is misconfigured.
Errors that occur after successful signature verification (e.g. a transient database error during Inngest dispatch) are swallowed and still return 200 {"received": true}. This prevents GitHub from retrying deliveries for non-recoverable server-side failures.

Setting Up

1

Deploy the Deployaar API

Ensure the Deployaar API is publicly accessible. The webhook endpoint must be reachable from GitHub’s servers. The deployed URL will look like https://your-api.onrender.com (or your own domain).
2

Set the Webhook URL in your GitHub App

In your GitHub App settings (Settings → Developer settings → GitHub Apps → your app → General), locate the Webhook section and set the Webhook URL to:
https://{api-url}/api/github/webhook
3

Configure the webhook secret

Generate a strong random secret (at least 32 characters). Paste it into the Webhook secret field in your GitHub App settings. Then set the same value as the GITHUB_WEBHOOK_SECRET environment variable in your API deployment.
# Example: generate a secret with openssl
openssl rand -hex 32
4

Enable the required events

Under Permissions & events → Subscribe to events, enable at minimum:
  • Pull requests — triggers the AI PR review workflow on opened, synchronize, and reopened actions.
  • Issues — triggers the issue intake workflow on opened and edited actions.
Save your changes. GitHub will immediately attempt a ping delivery to verify the URL is reachable.

Local Testing

GitHub cannot deliver webhooks to localhost. During local development, use a tunnelling tool to forward webhook traffic to your local API server:
  • smee.io — free, browser-based webhook proxy. Run npx smee-client --url https://smee.io/your-channel --target http://localhost:8000/api/github/webhook.
  • ngrokngrok http 8000 gives you a public HTTPS URL to paste into your GitHub App’s webhook settings.
Remember to update the Webhook URL in your GitHub App settings to your tunnel URL each time you start a new tunnel session.
You can simulate a webhook delivery with curl to confirm your local server is handling the signature check correctly. Replace <secret> with your GITHUB_WEBHOOK_SECRET and re-compute the signature each time you change the payload body:
# 1. Build the payload
PAYLOAD='{"action":"opened","repository":{"full_name":"owner/repo"}}'

# 2. Compute the HMAC-SHA256 signature
SECRET="your-github-webhook-secret"
SIGNATURE="sha256=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$SECRET" | awk '{print $2}')"

# 3. Send the mock webhook
curl -X POST http://localhost:8000/api/github/webhook \
  -H "Content-Type: application/json" \
  -H "x-hub-signature-256: $SIGNATURE" \
  -H "x-github-event: pull_request" \
  -H "x-github-delivery: test-delivery-$(date +%s)" \
  -d "$PAYLOAD"
A correctly signed request returns 200 {"received":true}. An incorrect secret or tampered body returns 401 {"error":"Invalid signature"}.

Build docs developers (and LLMs) love