Lifecycle Events
Video upload and encoding events: from slot reservation to ready state.
These events track a video's journey from upload through encoding to the ready state, as well as failures and deletion. For the envelope format, shared headers, and retry policy, see Outbound Webhooks.
Examples reuse the following placeholders throughout this page:
organization_id → 11111111-1111-1111-1111-111111111111,
video id → 00000000-0000-4000-8000-00000000aa01,
provider asset id → c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a.
video.upload.started
When it fires. An upload slot was reserved via the API: a video row exists with
pending_upload status and the TUS upload can proceed.
{
"id": "evt_7b9e4f2a-0c1d-4e8f-9a3b-2d6c8e1f4a5b",
"type": "video.upload.started",
"created_at": "2026-05-09T18:30:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "pending_upload",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | See shared data.video. Dimensions and duration are not yet available. |
video.upload.completed
When it fires. Moviie has accepted the uploaded file from the ingest provider and queued
processing (library created status).
{
"id": "evt_a1b2c3d4-e5f6-4789-a012-3456789abcde",
"type": "video.upload.completed",
"created_at": "2026-05-09T18:31:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "created",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Updated library row. Status is created. |
video.upload.failed
When it fires. The failure confirmer job verified via the provider API that the upload ultimately failed. Transient ingest callbacks alone do not emit this event.
{
"id": "evt_b2c3d4e5-f6a7-4890-b123-456789abcdef",
"type": "video.upload.failed",
"created_at": "2026-05-09T19:00:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "upload_failed",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library row in upload_failed state. Dimensions absent. |
video.encoding.started
When it fires. The provider reports encoding has started (processing). Fires only on
the first transition into that status: duplicate processing callbacks do not re-fire
this event.
{
"id": "evt_c3d4e5f6-a7b8-4901-c234-567890abcdef",
"type": "video.encoding.started",
"created_at": "2026-05-09T18:32:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "processing",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library snapshot in processing state. |
video.encoding.progress
When it fires. On each encoding progress update while the status is processing, and
again with progress: 100 when a resolution finishes.
{
"id": "evt_d4e5f6a7-b8c9-4012-d345-678901bcdef0",
"type": "video.encoding.progress",
"created_at": "2026-05-09T18:33:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "processing",
"title": "My video.mp4",
"duration_ms": 125400,
"width": 1920,
"height": 1080,
"collection_id": "22222222-2222-4222-8222-222222222222"
},
"progress": 42
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library snapshot; dimensions may appear as the provider fills metadata. |
data.progress | number | Encode progress from 0 to 100 (integer). |
video.encoding.completed
When it fires. A resolution completed and the asset is partially ready
(resolution_finished). Full readiness is signalled by video.ready.
{
"id": "evt_e5f6a7b8-c9d0-4123-e456-789012345678",
"type": "video.encoding.completed",
"created_at": "2026-05-09T18:35:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "resolution_finished",
"title": "My video.mp4",
"duration_ms": 125400,
"width": 1920,
"height": 1080,
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library snapshot after partial completion. Status is resolution_finished. |
video.encoding.failed
When it fires. The failure confirmer job verified a terminal encoding failure via the provider API. Transient ingest callbacks alone do not emit this event.
{
"id": "evt_f6a7b8c9-d0e1-4234-f567-890123456789",
"type": "video.encoding.failed",
"created_at": "2026-05-09T20:00:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "encoding_failed",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library row in encoding_failed state. |
video.ready
When it fires. All renditions completed; the video is fully playable (complete).
{
"id": "evt_a7b8c9d0-e1f2-4345-a678-901234567890",
"type": "video.ready",
"created_at": "2026-05-09T18:40:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "complete",
"title": "My video.mp4",
"duration_ms": 125400,
"width": 1920,
"height": 1080,
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library row in complete state with full metadata. |
video.failed
When it fires. The failure confirmer job verified an irrecoverable provider failure
(failed status). Transient ingest callbacks alone do not emit this event.
{
"id": "evt_b8c9d0e1-f2a3-4456-b789-012345678901",
"type": "video.failed",
"created_at": "2026-05-09T20:05:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "failed",
"title": "My video.mp4",
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Library row in terminal failed state. |
video.published
When it fires. The asset first reaches the fully complete state. This fires alongside
video.ready but only when the previous stored status was not already complete: it
is not emitted again if the video is re-processed or touched later.
{
"id": "evt_c9d0e1f2-a3b4-4567-c890-123456789012",
"type": "video.published",
"created_at": "2026-05-09T18:41:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01",
"external_id": "c3d7e9a1-2b4f-4c6d-8e0a-1f3b5d7c9e0a",
"status": "complete",
"title": "My video.mp4",
"duration_ms": 125400,
"width": 1920,
"height": 1080,
"collection_id": "22222222-2222-4222-8222-222222222222"
}
}
}| Path | Type | Description |
|---|---|---|
data.video | object | Same shape as video.ready: full metadata in complete state. |
video.deleted
When it fires. The video was soft-deleted via the API (DELETE /videos/:id). A
video.unpublished event fires at the same time.
{
"id": "evt_d0e1f2a3-b4c5-4678-d901-234567890123",
"type": "video.deleted",
"created_at": "2026-05-09T21:00:00.000Z",
"organization_id": "11111111-1111-1111-1111-111111111111",
"data": {
"video": {
"id": "00000000-0000-4000-8000-00000000aa01"
}
}
}| Path | Type | Description |
|---|---|---|
data.video.id | string | UUID of the deleted video. No other fields are sent. |