# Report progress

> The stage, the shot list as it stands, notes and the repair being run. Also the heartbeat: send one at least every 60 seconds. A remake with no progress for 15 minutes fails with `cli_stopped` and releases its project. 409 `canceled` means stop.

### POST /v1/remakes/{id}/progress

**Report progress**

The stage, the shot list as it stands, notes and the repair being run. Also the heartbeat: send one at least every 60 seconds. A remake with no progress for 15 minutes fails with `cli_stopped` and releases its project. 409 `canceled` means stop.

Auth: `Authorization: Bearer rl_live_...` with the `remake` scope.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | uuid | yes | The remake id. |

Request body (application/json):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `stage` | enum | yes | One of: `studying`, `building`, `polishing`, `needs_repair`. |
| `shots` | object[] | no |  |
| `shots[].index` | integer | yes |  |
| `shots[].startMs` | number | yes |  |
| `shots[].durationMs` | number | yes |  |
| `shots[].state` | enum | yes | One of: `skeleton`, `building`, `built`, `failed`. |
| `notes` | string[] | no |  |
| `repair` | object \| null | no |  |
| `repair.requested` | boolean | yes |  |
| `repair.uncovered` | object[] | yes |  |
| `repair.uncovered[].segmentId` | string | yes |  |
| `repair.uncovered[].firstMs` | number | yes |  |
| `repair.uncovered[].lastMs` | number | yes |  |
| `repair.uncovered[].box` | object | yes |  |
| `repair.uncovered[].box.x` | number | yes |  |
| `repair.uncovered[].box.y` | number | yes |  |
| `repair.uncovered[].box.w` | number | yes |  |
| `repair.uncovered[].box.h` | number | yes |  |
| `repair.uncovered[].samples` | integer | yes |  |

Responses:

| Status | Meaning |
| --- | --- |
| 200 | The remake. |
| 400 | Invalid request. |
| 401 | Missing, invalid or revoked key. |
| 403 | The key lacks the scope, or the key's owner has view-only access to the workspace (code `forbidden`). |
| 404 | Not found. |
| 409 | The remake was canceled (code `canceled`) or already ended (code `stage`). |
| 429 | Rate limited, or a monthly cap reached. |

Response body (200):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `remake` | object | yes |  |
| `remake.id` | uuid | yes |  |
| `remake.status` | enum | yes | The furthest stage reached: studying (the study runs on your machine), building (shots land in the project as they are built; overlaps studying), polishing (the film-wide pass), needs_repair (the CLI is running the repair session), then done, failed or canceled. New values may be added; treat unknown ones as opaque. One of: `studying`, `building`, `polishing`, `needs_repair`, `done`, `failed`, `canceled`. |
| `remake.projectId` | uuid \| null | yes |  |
| `remake.projectUrl` | url \| null | yes |  |
| `remake.shots` | object[] | yes |  |
| `remake.shots[].index` | integer | yes |  |
| `remake.shots[].startMs` | number | yes |  |
| `remake.shots[].durationMs` | number | yes |  |
| `remake.shots[].state` | enum | yes | One of: `skeleton`, `building`, `built`, `failed`. |
| `remake.repair` | object \| null | yes |  |
| `remake.repair.requested` | boolean | yes |  |
| `remake.repair.uncovered` | object[] | yes |  |
| `remake.repair.uncovered[].segmentId` | string | yes |  |
| `remake.repair.uncovered[].firstMs` | number | yes |  |
| `remake.repair.uncovered[].lastMs` | number | yes |  |
| `remake.repair.uncovered[].box` | object | yes |  |
| `remake.repair.uncovered[].box.x` | number | yes |  |
| `remake.repair.uncovered[].box.y` | number | yes |  |
| `remake.repair.uncovered[].box.w` | number | yes |  |
| `remake.repair.uncovered[].box.h` | number | yes |  |
| `remake.repair.uncovered[].samples` | integer | yes |  |
| `remake.report` | object \| null | yes |  |
| `remake.report.glitches` | any[] | yes |  |
| `remake.report.gaps` | any[] | yes |  |
| `remake.report.notes` | string[] | yes |  |
| `remake.error` | string \| null | yes |  |
| `remake.errorCode` | enum \| null | yes | One of: `cli_stopped`, `tab_lost`, `study_error`, `build_error`. |
| `remake.libraryEligible` | boolean | yes | Whether this remake (the video, the study and the plan applied) may feed Raylight's motion library. False once the owner or the workspace turns data sharing off (Settings, Improve Raylight); that switch is the only opt-out. |
| `remake.source` | object | yes |  |
| `remake.source.fileName` | string | yes |  |
| `remake.source.durationMs` | integer | yes |  |
| `remake.source.width` | integer | yes |  |
| `remake.source.height` | integer | yes |  |
| `remake.source.fps` | number | yes |  |
| `remake.agent` | enum | yes | One of: `claude`, `codex`. |
| `remake.builder` | object | yes |  |
| `remake.builder.attached` | boolean | yes |  |
| `remake.builder.lastSeenAt` | string \| null | yes |  |
| `remake.createdAt` | string | yes |  |
| `remake.updatedAt` | string | yes |  |

Example (curl):

```bash
curl -X POST https://api.raylight.app/v1/remakes/$ID/progress \
  -H "Authorization: Bearer $RAYLIGHT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "stage": "studying"
}'
```

## More

- Previous: [Generate one backdrop](https://www.raylight.app/docs/reference/post-v1-remakes-id-backdrops.md)
- Next: [Sign the library uploads](https://www.raylight.app/docs/reference/post-v1-remakes-id-outputs.md)
- All docs: https://www.raylight.app/llms.txt
- Everything in one file: https://www.raylight.app/llms-full.txt
- OpenAPI: https://api.raylight.app/v1/openapi.json
