---
title: Webhooks
description: "Trigger builds automatically from GitHub push and pull request events, with signature verification."
---

# Webhooks

Syntext receives webhooks from your git provider to trigger builds automatically — production builds on pushes to your configured branch, and preview builds for pull requests.

<Note>
If you installed the **Syntext GitHub App**, webhooks are configured automatically and you can skip this page. Manual setup is only needed for repos connected by URL.
</Note>

## Endpoints

| Endpoint | Purpose |
|----------|---------|
| `POST /v1/webhooks/github` | Per-repo webhook (manual setup) |
| `POST /v1/webhooks/github-app` | GitHub App central webhook (automatic) |

## Manual GitHub Setup

<Steps>
<Step title="Add the webhook in GitHub">
In your repo: **Settings → Webhooks → Add webhook**

- **Payload URL**: `https://api.syntext.dev/v1/webhooks/github`
- **Content type**: `application/json`
- **Secret**: a shared secret (also configured on your Syntext project)
- **Events**: `push` and `pull_request`
</Step>
<Step title="Push a commit">
Every push to your configured branch triggers a production build. Pushes to other branches trigger preview builds.
</Step>
</Steps>

## Event Handling

### Push events

- Pushes to the project's configured branch (default `main`) → **production build**
- Pushes to other branches → **preview build**
- Changed file paths from the commits are recorded on the build for incremental processing

### Pull request events

PRs with action `opened`, `synchronize`, or `reopened` trigger a **preview build** of the PR's head commit. Other PR actions are ignored.

### Response

```json
{
  "data": {
    "builds": ["bld_abc123"],
    "preview": true
  }
}
```

If no Syntext project is connected to the repository, `builds` is an empty array.

## Signature Verification

Syntext verifies the `X-Hub-Signature-256` header on every delivery using HMAC-SHA256 with your webhook secret. Requests with a missing or invalid signature are rejected with `401`:

```json
{
  "error": { "code": "unauthorized", "message": "Invalid signature" }
}
```

Comparison is timing-safe. There is nothing to configure client-side — GitHub signs deliveries automatically once the secret is set.

## Debugging Deliveries

Recent webhook deliveries and their outcomes are visible per project:

```
GET /v1/projects/{projectId}/webhook-test/deliveries
```

Requires [authentication](/api-reference/authentication). Also check GitHub's own **Recent Deliveries** tab under the webhook settings for request/response pairs.

<Warning>
A `401 Invalid signature` response almost always means the secret configured in GitHub doesn't match the one on the Syntext project.
</Warning>

## GitLab

For GitLab, trigger builds from CI instead of webhooks — see [GitLab CI](/deployment/gitlab-ci).
