Event reference
The envelope and per-event payload schemas for every Cheetah event, with a complete example payload for each.
Every event Cheetah dispatches shares one envelope and carries an event-specific data object. Delivery and retries: webhooks. When each event fires: program lifecycle events.
The envelope#
| Field | Type | Notes |
|---|---|---|
schema_version |
integer | Payload schema generation. Currently 3. |
event_name |
string | One of ProgramStarted, ProgramCompleted, ProgramFailed, ProgramCancelled. Matches the X-Cheetah-Event header. |
event_id |
string (UUID) | Unique per delivery. Matches the X-Cheetah-Event-Id header. Deduplicate on this. |
timestamp |
integer | When the event was dispatched, epoch milliseconds. |
delivery_attempt |
integer | 1-based. Increments on each retry of the same event_id. |
kiosk_serial_number |
string | null | Serial number of the Cheetah unit that emitted the event, as set in system config. null until the unit is commissioned — the key is always present, so branch on null rather than on absence. Not to be confused with data.serial_number, which is the serial of the part being inspected. |
service_version |
string | The cheetah-service build that emitted the event, e.g. "1.6.0" — the same string GET /system/version returns. Reads "unknown" only outside a published image. |
data |
object | Event-specific payload. Shapes below. |
Both kiosk_serial_number and service_version identify the sender, not the run, so they appear on every event — including WebhookTest. Use them to attribute events when several Cheetah units post to one endpoint.
schema_version#
All events currently ship at schema_version: 3. The schema is versioned independently of the HTTP API and of the transport — see the versioning policy. Two rules for consumers:
- Ignore unknown fields. New fields may be added without bumping
schema_version— to the envelope as well as to adataobject. A field you don't recognize is not an error. - Pin to a version you've tested. A breaking change ships under a higher
schema_version; existing subscribers keep receiving the prior shape during an announced transition window.
3 replaced the internal canonical_units flag on each QC check with a receiver-facing unit, added nominal, and added unit_system to ProgramCompleted data. That was a breaking per-check change from 2; see ProgramCompleted.
Common data fields#
These fields appear in the data object of all four lifecycle events:
| Field | Type | Notes |
|---|---|---|
run_id |
string (UUID) | The program run this event is about. Stable across the program run's events — use as an idempotency key. |
program_id |
string (UUID) | The program that was run. |
program_name |
string | null | The program's name at dispatch time — the label an operator sees. null if the program was deleted before the event fired. Added in v1.5.12 without a schema_version bump. |
robot_id |
string | null | The robot that executed the program run — a short operator-chosen id from the cell's configuration, not a UUID. A program driving several robots reports the first; null if the program has no robot or was deleted before dispatch. |
serial_number |
string | null | The part's serial number, if one was captured. |
revision |
integer | Inspection revision of this serial_number — auto-increments each time the same part is re-inspected. |
started_at |
string (ISO 8601) | When the program run started. |
completed_at |
string (ISO 8601) | null | When the program run ended. null for ProgramStarted. |
The sections below document only the fields each event adds to these, but each example payload is complete.
ProgramStarted#
Fires when a program run begins executing on a part. Adds no fields beyond the common set; completed_at is null.
{
"schema_version": 3,
"event_name": "ProgramStarted",
"event_id": "8f3a1c20-2b7e-4f1a-9c44-6d0b1e2f3a45",
"timestamp": 1714291200000,
"delivery_attempt": 1,
"kiosk_serial_number": "CHEETAH-KIOSK-0042",
"service_version": "1.6.0",
"data": {
"run_id": "1f5b9d8e-7a32-4c11-8e90-2a4b6c8d0e12",
"program_id": "a2c4e6f8-1234-5678-9abc-def012345678",
"program_name": "Bracket QC",
"robot_id": "arm-1",
"serial_number": "SN-4471",
"revision": 2,
"started_at": "2026-04-28T13:00:00+00:00",
"completed_at": null
}
}
ProgramCompleted#
Fires when a program run finishes and the QC outcome has been computed. This is the event that carries the inspection result.
| Field | Type | Notes |
|---|---|---|
passed |
boolean | The overall QC outcome for the program run. |
qc_checks |
array | One entry per check evaluated. Shape below. |
unit_system |
string | "metric" or "imperial" — the display-units preference the numbers in qc_checks were converted to before delivery. Set in system config; changing it takes effect on the next delivery. |
files |
array | Files produced by this run. Same shape as GET /runs/{run_id}/files. href values are relative — join with the cell's base URL. Empty for runs predating the run-files feature. |
defects |
array | Informational findings — dents, scratches, and the like — with no pass/fail criteria. A defect never changes passed; a run can pass with defects listed. Same shape as GET /runs/{run_id}/defects. Empty when none were found. |
Each entry in qc_checks:
| Field | Type | Notes |
|---|---|---|
name |
string | The check's name. |
status |
string | "pass" or "fail". |
value |
number | The measured value, expressed in unit. |
nominal |
number | The target value the check was measured against, expressed in unit. |
threshold |
number | The tolerance value was compared against, expressed in unit. |
delta |
number | Signed difference between value and nominal, expressed in unit. |
unit |
string | null | The unit the numeric fields above are in — "mm", "in", or null. Length checks report "mm" or "in" per the run's unit_system; unitless checks (counts, ratios) report null. |
Changed in
schema_version: 3. Checks previously carriedcanonical_units("mm"|"unspecified"), an internal flag, and values were always mm. They now carryunit, and length values are converted to inches whenunit_systemis"imperial". Readunit— never assume mm.
Each entry in files (FileMetadata):
| Field | Type | Notes |
|---|---|---|
name |
string | Unique file name within the run. |
type |
string | File category — one of pointcloud, image, array, measurement, report. |
content_type |
string | MIME type. |
size_in_bytes |
integer | null | File size at upload time. null when size is unknown. |
description |
string | null | Human-readable label, if set. |
href |
string | Relative download URL — join with the cell's base URL. |
step_index |
integer | null | Program step (1-indexed) that produced this file, if applicable. |
frame_id |
string (UUID) | null | Sensor frame this file belongs to, if applicable. |
created_at |
string (ISO 8601) | When the file was stored. |
updated_at |
string (ISO 8601) | Last modification time. |
deleted_at |
string (ISO 8601) | null | Set when the file's bytes were removed by a retention policy. null for live files. |
The files array is an additive field — it was added without a schema_version bump. See Pull run files for full details on the consolidated file-access endpoints.
{
"schema_version": 3,
"event_name": "ProgramCompleted",
"event_id": "7d2e9a14-3c5b-4a82-b1f6-90c3e5a7b9d1",
"timestamp": 1714291242000,
"delivery_attempt": 1,
"kiosk_serial_number": "CHEETAH-KIOSK-0042",
"service_version": "1.6.0",
"data": {
"run_id": "1f5b9d8e-7a32-4c11-8e90-2a4b6c8d0e12",
"program_id": "a2c4e6f8-1234-5678-9abc-def012345678",
"program_name": "Bracket QC",
"robot_id": "arm-1",
"serial_number": "SN-4471",
"revision": 2,
"started_at": "2026-04-28T13:00:00+00:00",
"completed_at": "2026-04-28T13:00:42+00:00",
"passed": true,
"qc_checks": [
{
"name": "flatness",
"status": "pass",
"value": 0.04,
"nominal": 0.0,
"threshold": 0.10,
"delta": 0.04,
"unit": "mm"
},
{
"name": "weld_seam_continuity",
"status": "pass",
"value": 1.0,
"nominal": 1.0,
"threshold": 0.95,
"delta": 0.05,
"unit": null
}
],
"files": [
{
"name": "cl_sweep_step_1.csv",
"type": "measurement",
"content_type": "text/csv",
"size_in_bytes": 14832,
"description": null,
"href": "/runs/1f5b9d8e-7a32-4c11-8e90-2a4b6c8d0e12/files/cl_sweep_step_1.csv",
"step_index": 1,
"frame_id": null,
"created_at": "2026-04-28T13:00:40+00:00",
"updated_at": "2026-04-28T13:00:40+00:00",
"deleted_at": null
}
],
"defects": [],
"unit_system": "metric"
}
}
ProgramFailed#
Fires when a program run stops on a step error before producing an outcome.
| Field | Type | Notes |
|---|---|---|
error_message |
string | Human-readable description of the failure. |
error_step_index |
integer | Zero-based index of the step that failed. |
{
"schema_version": 3,
"event_name": "ProgramFailed",
"event_id": "b4f1a6c8-5d20-4e3a-9f12-7c8e0a2b4d6f",
"timestamp": 1714291230000,
"delivery_attempt": 1,
"kiosk_serial_number": "CHEETAH-KIOSK-0042",
"service_version": "1.6.0",
"data": {
"run_id": "1f5b9d8e-7a32-4c11-8e90-2a4b6c8d0e12",
"program_id": "a2c4e6f8-1234-5678-9abc-def012345678",
"program_name": "Bracket QC",
"robot_id": "arm-1",
"serial_number": "SN-4471",
"revision": 2,
"started_at": "2026-04-28T13:00:00+00:00",
"completed_at": "2026-04-28T13:00:18+00:00",
"error_message": "scanner returned no point cloud for step 3",
"error_step_index": 3
}
}
ProgramCancelled#
Fires when an operator cancels a program run. No outcome is produced.
| Field | Type | Notes |
|---|---|---|
error_message |
string | null | Reason for cancellation, if one was recorded. |
{
"schema_version": 3,
"event_name": "ProgramCancelled",
"event_id": "e2a7c4b9-6f31-4d8a-a0e5-3b9d1f7c2e84",
"timestamp": 1714291215000,
"delivery_attempt": 1,
"kiosk_serial_number": "CHEETAH-KIOSK-0042",
"service_version": "1.6.0",
"data": {
"run_id": "1f5b9d8e-7a32-4c11-8e90-2a4b6c8d0e12",
"program_id": "a2c4e6f8-1234-5678-9abc-def012345678",
"program_name": "Bracket QC",
"robot_id": "arm-1",
"serial_number": "SN-4471",
"revision": 2,
"started_at": "2026-04-28T13:00:00+00:00",
"completed_at": "2026-04-28T13:00:09+00:00",
"error_message": "cancelled by operator"
}
}
WebhookTest#
Not a lifecycle event. The Test action on a webhook in cheetah-ui sends this synthetic event so you can confirm an endpoint receives, verifies, and acknowledges a delivery before any real program run depends on it. It has no associated program run, and its data is a fixed message.
{
"schema_version": 3,
"event_name": "WebhookTest",
"event_id": "0a1b2c3d-4e5f-6a7b-8c9d-0e1f2a3b4c5d",
"timestamp": 1714291200000,
"delivery_attempt": 1,
"kiosk_serial_number": "CHEETAH-KIOSK-0042",
"service_version": "1.6.0",
"data": {
"message": "This is a test event from cheetah-service."
}
}
A receiver written against the real events should treat WebhookTest as a no-op — return 2xx and don't try to write it to your system of record.