---
title: Events webhooks
description: Signed incoming status events and their delivery contract.
doc_version: 0.1.0-preview
last_updated: 2026-09-14
---

# Events webhooks

Graphon Engine sends status events as signed HTTP POST requests to configured receivers. This page defines those incoming requests and their delivery behavior.

## Subscription and destination

The operator configures webhook destinations on the cluster. Each destination has a unique `name`, unique HTTPS `url`, signing `secret`, and optional `types` filter. Loopback development can use HTTP. The API does not expose webhook management routes.

A configured receiver gets the event types in its filter. Omitting `types` selects all supported types. `/info` exposes the webhook count and supported event types, without revealing URLs or secrets. New receivers begin with new events; they do not replay historical events.

## Request headers

| Header | Type | Contract |
| --- | --- | --- |
| `Content-Type` | string | `application/json`. Verify the original body bytes before parsing. |
| `X-Graphon-Events-Signature` | string | `sha256=` followed by the hex HMAC-SHA256 digest. |
| `X-Graphon-Events-Timestamp` | string containing Unix seconds | The delivery timestamp used in signature verification. |
| `X-Graphon-Events-Delivery` | string | A del_ identifier unique to this attempt at this webhook. |
| `X-Graphon-Events-Webhook` | string | The receiver’s configured name. |

The signature input is the exact UTF-8 bytes of `timestamp + "."`, followed by the original HTTP body bytes. Sign with the receiver’s secret using HMAC-SHA256. Prefix the hex digest with `sha256=`.

## Event body

**POST to your configured receiver · JSON body**

```json
{
  "id": "evt_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "type": "file.status_changed",
  "occurred_at": "2026-10-06T12:01:00Z",
  "cluster": "graphon-engine",
  "namespace": "acme",
  "collection": "incident-logs",
  "job_id": "job_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "file_id": "fil_01J8Z3K4N5P6Q7R8S9T0V1W2X3",
  "data": {
    "status": "ready",
    "previous_status": "indexing"
  }
}
```

| Field | Type | Contract |
| --- | --- | --- |
| `id` | string · required | Stable evt_ ID for this status change. Use it to deduplicate. |
| `type` | string enum · required | job.updated, file.status_changed, or collection.status_changed. |
| `occurred_at` | UTC timestamp string · required | Time the resource status changed. |
| `cluster` | string · required | Cluster name reported by /info. |
| `namespace` | string or null · required | Namespace associated with the resource, or null when none applies. |
| `collection` | string or null · required | Collection associated with the resource, or null when none applies. |
| `job_id` | string or null · required | Related job_ ID, or null when the event has no related job. |
| `file_id` | string or null · required | Related fil_ ID, or null when the event has no related file. |
| `data` | object · required | Status transition payload. |
| `data.status` | string · required | New status for the resource identified by type. |
| `data.previous_status` | string or null · required | Status before the transition. Null on initial job and file creation. |
| `data.job_type` | string enum · optional | Operation type for a job event, such as index_file or apply_access_rule. |

File states are `pending`, `indexing`, `ready`, `failed`, and `deleting`. Job states are `queued`, `running`, `succeeded`, `failed`, and `canceled`. Collection states are `empty`, `indexing`, `ready`, `degraded`, `failed`, and `deleting`. Creating an empty collection does not emit a collection event.

Within a major API version, new event types or status values can be added. Preserve unknown values without treating them as a known success state.

## Responses and delivery

| Your response | Engine action |
| --- | --- |
| 2xx | Delivery succeeds. Engine stops attempts for this event and receiver. |
| 429 or 5xx | Engine retries this receiver. |
| Network error or timeout | Engine retries this receiver. |
| 3xx | Delivery fails. Engine follows no redirect and does not retry. |
| Other 4xx | Delivery fails without a retry. |

Engine allows 10 seconds per attempt and makes at most eight attempts. Delays after failures are 1, 2, 4, 8, 16, 32, and 64 seconds. A delivery ID is unique per attempt and destination.

Verify timestamps within 300 seconds, then deduplicate event IDs. Delivery retries can repeat an event. Engine delivers events sequentially for each receiver. A retry delays later events for that receiver. One receiver’s failures do not block another.

## Recovery

Current resource state remains available through the resource GET endpoints after delivery attempts end. Use [Get job](/engine/reference/get-job), [Get file](/engine/reference/get-file), or [Get collection](/engine/reference/get-collection) to recover after a missed event.

The [jobs and events guide](/engine/guides/jobs-and-events) includes receiver setup, verification code, and an acknowledgement workflow.
## Sitemap

See the full [sitemap](/sitemap.md) for all pages.
