> ## Documentation Index
> Fetch the complete documentation index at: https://docs.buildpixel.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhooks

> Push-style event delivery. BuildPixel POSTs to your endpoint when builds complete.

For event-driven integrations — Slack notifications, downstream pipelines, status dashboards — webhooks are the right tool.

## Configuring a webhook

In **Settings → Webhooks**:

* **URL** — your endpoint
* **Events** — which events fire (build complete, build failed, etc.)
* **Active** — enable / disable without deleting

You can register multiple webhooks per org. Each fires independently.

## What gets sent

Webhooks POST a JSON envelope to your URL:

```json theme={null}
{
  "type": "build.complete",
  "createdAt": "...",
  "organizationId": "...",
  "data": {
    "build": {
      "id": "...",
      "status": "complete",
      "platform": "Win64",
      "buildType": "Development",
      "branch": "main",
      "commit": "...",
      "durationMs": 763000,
      "artifactUrl": "https://..."
    },
    "project": { "id": "...", "name": "MyGame" }
  }
}
```

The `type` field tells you which event fired. Common ones:

| Event              | When                                   |
| ------------------ | -------------------------------------- |
| `build.created`    | A new build is dispatched              |
| `build.running`    | The build picks up and starts running  |
| `build.complete`   | Build succeeded; artifact is available |
| `build.failed`     | Build failed                           |
| `build.superseded` | Replaced by a newer build              |

## Verifying signatures

The request includes an `X-BuildPixel-Signature` header — an HMAC of the body using your webhook signing secret. Verify before trusting:

```js theme={null}
import crypto from "node:crypto";

function verifySignature(req, secret) {
  const sig = req.headers["x-buildpixel-signature"];
  if (!sig?.startsWith("sha256=")) return false;
  const expected = "sha256=" + crypto
    .createHmac("sha256", secret)
    .update(req.rawBody)
    .digest("hex");
  return crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected));
}
```

The signing secret is generated when you create the webhook and shown in the Settings UI.

## Retries

If your endpoint returns non-2xx, BuildPixel retries with exponential backoff for a few attempts before giving up. Failed deliveries are visible in the dashboard's webhook delivery log.

## Common patterns

<CodeGroup>
  ```js Slack notification theme={null}
  app.post("/webhooks/buildpixel", async (req, res) => {
    if (!verifySignature(req, SECRET)) return res.sendStatus(401);
    const event = JSON.parse(req.body);

    if (event.type === "build.complete") {
      const { build, project } = event.data;
      await fetch(SLACK_WEBHOOK_URL, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          text: `:rocket: ${project.name} ${build.platform} ${build.buildType} build complete`,
        }),
      });
    }
    res.sendStatus(204);
  });
  ```

  ```js Trigger a downstream job theme={null}
  if (event.type === "build.complete" && event.data.build.buildType === "Shipping") {
    await fetch(DOWNSTREAM_URL, {
      method: "POST",
      body: JSON.stringify({ buildId: event.data.build.id })
    });
  }
  ```
</CodeGroup>
