# Webhooks

## When to use this

You want a site to deploy when code is pushed. Sites connected to GitHub through pfcloud's GitHub App need no webhook at all (see [Create a site](/developers/create-a-site)). Use the deploy webhook for GitLab, Bitbucket, CI jobs, or GitHub repositories you did not connect through the app.

## The URL

```text
POST https://YOUR-MYFORGE/api/hooks/deploy/WEBHOOK_KEY
```

`WEBHOOK_KEY` is a random 40-character key per site, never the site's id. It is shown on the site page with the secret.

## Turn it on

- Dashboard: site page, Deployments, turn on deploy on push.
- API: `PATCH /sites/{site}` with `{"auto_deploy": true}`. If this created the webhook, the answer includes `deploy_webhook` with the URL and the secret, once.
- Replace it: `POST /sites/{site}/deploy-webhook` with `{"confirm": "your-domain.example.com"}`. The new URL and secret are shown once. The old ones stop working. The answer is not stored for idempotent replays, so save it at once.

Sites with `auto_deploy` off, and unknown keys, answer `404`. The endpoint reveals nothing about them.

## How the request is verified

The secret is checked in one of three ways, depending on the caller:

| Caller | How to send the secret |
| --- | --- |
| GitHub | Set the webhook's **Secret**. GitHub signs the body and sends `X-Hub-Signature-256: sha256=<hmac>`. Content type `application/json`, event "Just the push event". |
| GitLab | Put the secret in **Secret token**. GitLab sends `X-Gitlab-Token`. |
| Anything else (CI, Bitbucket, curl) | Add `?token=SECRET` to the URL. |

A wrong secret answers `403`.

```bash
curl -X POST "https://YOUR-MYFORGE/api/hooks/deploy/WEBHOOK_KEY?token=SECRET"
```

## Which pushes deploy

For GitHub and GitLab only a push to the site's configured branch deploys. Other events and other branches are answered with a message that starts with "Ignored". A GitHub `ping` answers `pong`. For the generic `?token=` call, any request deploys the site's branch.

## Answers

| Status | Meaning |
| --- | --- |
| `202` | Deployment queued. The answer has `message` and the deployment `id`. |
| `200` | Ignored (not a push, or another branch), or `pong`. |
| `403` | Invalid signature or token. |
| `404` | Unknown key, or deploy on push is off. |
| `409` | Not queued: the site cannot be deployed right now, or a deployment is already running. |

The deployment follows the normal rules, including the code scan before any build step. Follow it with `GET /sites/{site}/deployments`.

## Safety

- Treat the URL and the secret as passwords. Anyone with both can trigger deploys of that branch.
- Replace them if they leak.
- pfcloud's own GitHub webhook (`/api/github/webhook`) is separate and is set up by the platform administrator. You do not call it.
