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

# Webhook event reference

> Complete reference for every webhook event Streampixel sends — names, payloads, and the build state that triggers each.

This page is the canonical reference for every webhook event Streampixel sends. For setup (where to enter your URL, how to choose events, retry behavior, handler best practices), see the main [Webhooks](/resources/api-reference/webhooks) page.

## Quick links

<CardGroup cols={2}>
  <Card title="Webhook setup" icon="bell" href="/resources/api-reference/webhooks">
    Configure your URL, choose events, and follow handler best practices.
  </Card>

  <Card title="Upload File API" icon="upload" href="/resources/api-reference/upload-file-api">
    The endpoint that kicks off the build pipeline and the events below.
  </Card>
</CardGroup>

## Pipeline overview

Every uploaded build moves through a fixed sequence of pipeline stages. Each stage transition fires a webhook event (subject to your subscription filters).

```mermaid theme={"dark"}
flowchart TD
  Upload[POST /projects/upload-file] --> P[pending]
  P -->|build.uploaded| DL[Downloading Files]
  DL -->|build.downloading| EX[Extracting & Scanning]
  EX -->|build.extracting| SV[Saving to Repository]
  SV -->|build.saving| DI[Distribute]
  DI -->|build.distributing| AP[Approved]
  DI -.->|build.rejected| RJ[Reject]
  AP -->|build.approved| Done[Ready to stream]
```

The dashed edge to `build.rejected` indicates that a build can be rejected at the distribute stage instead of progressing to `Approved`. Once rejected, no further events fire for that build.

## Common payload fields

Every webhook payload (build events and the test event) shares the same envelope.

| Field       | Type             | Description                                                                |
| ----------- | ---------------- | -------------------------------------------------------------------------- |
| `event`     | `string`         | The event name (e.g., `build.approved`).                                   |
| `projectId` | `string`         | The Streampixel project the event belongs to.                              |
| `uploadId`  | `string \| null` | The build identifier. `null` for events that fire before an upload exists. |
| `fileUrl`   | `string \| null` | The build's source URL. May be `null` for early-pipeline events.           |
| `status`    | `string`         | Raw pipeline status string for the build.                                  |
| `objection` | `string \| null` | Reason for rejection. Only populated on `build.rejected`.                  |
| `timestamp` | `string`         | ISO 8601 timestamp of when the event occurred.                             |

<Info>
  All deliveries are `HTTP POST` with `Content-Type: application/json` and a 10-second timeout. There are no retries — see the [Webhooks](/resources/api-reference/webhooks) page for handler best practices.
</Info>

## Events

### `build.uploaded`

**Triggered by:** A new build has been accepted by `POST /projects/upload-file` and queued for processing. This is the very first event in the pipeline.

**Status at trigger:** `pending`.

```json theme={"dark"}
{
  "event": "build.uploaded",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": null,
  "status": "pending",
  "objection": null,
  "timestamp": "2026-03-29T13:00:00.000Z"
}
```

**Notes:** `fileUrl` may be `null` at this stage because the upload manager has not yet resolved the source. Use `uploadId` as your correlation key going forward.

***

### `build.downloading`

**Triggered by:** The build manager has begun downloading the `.zip` from the URL you submitted.

**Status at trigger:** `Downloading Files`.

```json theme={"dark"}
{
  "event": "build.downloading",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Downloading Files",
  "objection": null,
  "timestamp": "2026-03-29T13:00:12.000Z"
}
```

**Notes:** A long-running `build.downloading` without progressing to `build.extracting` usually means the source URL is slow or unreachable.

***

### `build.extracting`

**Triggered by:** The downloaded archive is being extracted and scanned for required files.

**Status at trigger:** `Extracting & Scanning`.

```json theme={"dark"}
{
  "event": "build.extracting",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Extracting & Scanning",
  "objection": null,
  "timestamp": "2026-03-29T13:01:30.000Z"
}
```

**Notes:** If the archive is malformed or missing the expected Unreal binary, the build skips to `build.rejected` with an `objection` describing the failure.

***

### `build.saving`

**Triggered by:** The validated build is being persisted to the project repository.

**Status at trigger:** `Saving to Repository`.

```json theme={"dark"}
{
  "event": "build.saving",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Saving to Repository",
  "objection": null,
  "timestamp": "2026-03-29T13:03:00.000Z"
}
```

**Notes:** This stage is typically short. After `build.saving`, the build moves to `Distribute` (and, if `autoRelease` is `true` in the upload, on to `build.distributing` automatically).

***

### `build.distributing`

**Triggered by:** The build is being copied to streaming servers and made ready to serve traffic. Fires when `autoRelease` was `true` on upload, or when [Distribute File API](/resources/api-reference/distribute-file-api) was called manually.

**Status at trigger:** `Distribute`.

```json theme={"dark"}
{
  "event": "build.distributing",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Distribute",
  "objection": null,
  "timestamp": "2026-03-29T13:05:00.000Z"
}
```

**Notes:** Subscribe to this event if you want to know when streaming servers are warming up — the build is almost ready, but not yet live.

***

### `build.approved`

**Triggered by:** Distribution finished successfully and the build is now the live build for the project. This is the event most CI/CD pipelines key off of.

**Status at trigger:** `Approved`.

```json theme={"dark"}
{
  "event": "build.approved",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Approved",
  "objection": null,
  "timestamp": "2026-03-29T13:08:00.000Z"
}
```

**Notes:** Treat this as the "go-live" signal — kick off downstream deploys, smoke tests, or release announcements here.

***

### `build.rejected`

**Triggered by:** The build failed validation at any stage of the pipeline. Once rejected, no further events fire for this `uploadId`.

**Status at trigger:** `Reject`.

```json theme={"dark"}
{
  "event": "build.rejected",
  "projectId": "664f1a2b3c4d5e6f7a8b9c0d",
  "uploadId": "665a2b3c4d5e6f7a8b9c0e1f",
  "fileUrl": "https://your-bucket.s3.amazonaws.com/builds/v1.2.0.zip",
  "status": "Reject",
  "objection": "Build contains unsupported file formats.",
  "timestamp": "2026-03-29T13:04:30.000Z"
}
```

**Notes:** Always read `objection` to learn why the build was rejected. Surface it in your team's CI logs or chat so the developer who pushed the build can act on it.

***

### `webhook.test`

**Triggered by:** Manually clicking the **Test** button in **Project Settings**. Never fired during real build operations.

**Status at trigger:** `test`.

```json theme={"dark"}
{
  "event": "webhook.test",
  "projectId": "test_project_id",
  "uploadId": "test_upload_id",
  "fileUrl": "https://example.com/test-build.zip",
  "status": "test",
  "objection": null,
  "timestamp": "2026-03-29T14:30:00.000Z"
}
```

**Notes:** All ID fields are placeholder strings — they do not correspond to real records. Your handler should detect this event and short-circuit any state-machine logic that would otherwise act on it.

## Event timing summary

| Event                | Fires when             | Typical delay from upload        |
| -------------------- | ---------------------- | -------------------------------- |
| `build.uploaded`     | API accepts the upload | Immediate                        |
| `build.downloading`  | Download begins        | Seconds                          |
| `build.extracting`   | Extraction begins      | Tens of seconds                  |
| `build.saving`       | Persist begins         | A minute or two                  |
| `build.distributing` | Distribution begins    | A minute or two after `saving`   |
| `build.approved`     | Build is live          | Variable — depends on build size |
| `build.rejected`     | Validation fails       | Any time during the pipeline     |
| `webhook.test`       | Manual or API trigger  | Immediate                        |

<Info>
  Times above are typical, not guaranteed. Larger builds, busy regions, and slow source URLs can all extend pipeline duration significantly.
</Info>

## Handling events safely

A few rules that apply across every event:

* **Use `uploadId` + `event` as your idempotency key.** In rare cases the same event may arrive more than once; deduplicate on your side.
* **Acknowledge fast.** Return `200 OK` within 10 seconds, then process in the background. Streampixel does not retry failed deliveries — see the [Webhooks](/resources/api-reference/webhooks) page for full guidance.
* **Tolerate unknown events.** New events may be added in the future; your handler should treat unfamiliar `event` strings as a no-op rather than crashing.
* **Validate the project.** Confirm `projectId` matches a project you expect — never act on a webhook for an unknown project.

## Next steps

<CardGroup cols={2}>
  <Card title="Webhook setup" icon="bell" href="/resources/api-reference/webhooks">
    Configure URLs, choose events, and follow handler best practices.
  </Card>

  <Card title="Upload File API" icon="upload" href="/resources/api-reference/upload-file-api">
    The endpoint that triggers the build pipeline events documented above.
  </Card>
</CardGroup>
