Documentation Index
Fetch the complete documentation index at: https://mintlify.com/nayalsaurav/deploy-your-app/llms.txt
Use this file to discover all available pages before exploring further.
The webhook endpoint at POST /webhook/:projectId is called by GitHub whenever code is pushed to a registered repository. It is handled by the standalone Express API service (apps/api) — a separate process from the Next.js web app — running on port 4000 by default. On every valid push event, the service verifies the request signature, creates a PENDING deployment record in the database, and enqueues a job in the deployment-queue for the background worker to pick up.
Endpoint
| Property | Value |
|---|
| Served by | apps/api Express server (not the Next.js app) |
| Default port | 4000 (override with the PORT environment variable) |
| Content-Type | application/json (set by GitHub automatically) |
Automatic Registration
When you import a project via POST /api/v1/projects/import, a GitHub webhook is automatically registered against the repository using the GitHub API. The webhook URL is constructed from the NEXT_PUBLIC_API_URL environment variable:
https://{your-api-domain}/webhook/{projectId}
You do not need to configure the webhook in GitHub manually for standard project imports.
Manual Setup
If you need to register or re-register a webhook yourself — for example, after changing your API domain — create the webhook in your GitHub repository settings with the following configuration:
| Field | Value |
|---|
| Payload URL | https://{your-api-domain}/webhook/{projectId} |
| Content type | application/json |
| Secret | Your GITHUB_WEBHOOK_SECRET value |
| Events | push only |
| Active | ✅ Enabled |
Replace {your-api-domain} with the public hostname of your apps/api server and {projectId} with the CUID of the project (visible in the dashboard URL or returned by the projects API).
Security — HMAC Signature Verification
GitHub signs every webhook payload with HMAC-SHA256 using the secret you configured. The API service verifies this signature on every incoming request before processing the payload.
How it works
-
GitHub computes
HMAC-SHA256(rawRequestBody, GITHUB_WEBHOOK_SECRET) and sends the result in the x-hub-signature-256 header:
x-hub-signature-256: sha256=abc123def456...
-
The API recomputes the HMAC over the raw request body using the same secret.
-
If the signatures match, processing continues. If they do not match — or if the header is absent — the request is rejected with
401.
The GITHUB_WEBHOOK_SECRET defaults to the placeholder string
development-secret when the environment variable is not set. You must
never use this default in a production environment. Generate a strong random
secret (at least 32 characters) and set it identically in:
- Your
apps/api environment (as GITHUB_WEBHOOK_SECRET)
- The GitHub webhook configuration for every project
A mismatch between these two values will cause all webhook deliveries to fail
with 401 Invalid signature.
Supported Events
Only push events are processed. All other GitHub event types (pull requests, issues, releases, etc.) are acknowledged with a 200 response and no further action is taken.
x-github-event value | Behaviour |
|---|
push | Deployment is scheduled |
| anything else | Returns 200 — "Event ignored, not a push event." |
Payload Processing
When a valid push event is received, the webhook handler performs the following steps in order:
- Extracts the branch from
payload.ref by stripping the refs/heads/ prefix (e.g., refs/heads/main → main). Defaults to main if ref is absent.
- Extracts the commit SHA from
payload.after. Returns 400 if this field is missing.
- Looks up the project in the database by
projectId. Returns 404 if not found.
- Decrypts environment variables stored for the project using the
MASTER_ENCRYPTION_KEY. If decryption fails for an individual variable, the raw (encrypted) value is passed through as a fallback.
- Creates a
PENDING deployment record linked to the project, with the extracted branch and commitHash.
- Enqueues a
deployment-event job in the deployment-queue (BullMQ), passing the repository details, credentials, project configuration, and decrypted environment variables to the worker.
Success Response
{
"message": "Deployment scheduled",
"deploymentId": "clxyz123abc456def"
}
| Field | Type | Description |
|---|
message | string | Confirmation string. |
deploymentId | string | CUID of the newly created deployment record. Use this with the Get Deployment and Deployment Logs endpoints to track progress. |
Error Responses
| Status | Condition |
|---|
401 | Missing or invalid HMAC signature (x-hub-signature-256 header absent or digest mismatch). |
400 | No commit hash found in the payload (payload.after is empty or absent). |
400 | No GitHub account or access token found for the project owner. |
404 | Project with the given projectId does not exist in the database. |
200 | Event type is not push — the event is acknowledged but ignored. |
500 | An unexpected internal server error occurred during payload processing. |