---
title: "Apply commands"
method: POST
path: "/projects/{id}/commands"
tags: ["Projects"]
---

# Apply commands

`POST /projects/{id}/commands`

## Request

- Base URL: `https://api.vidmoat.com/v1`
- URL: `https://api.vidmoat.com/v1/projects/{id}/commands`
- Auth: HTTP bearer

Apply an ordered list of edit commands. This is the only way to change a timeline, and it is the same reducer the editor calls: anything you can do by hand you can do here.

Each command succeeds or fails on its own, and the batch is saved when at least one succeeds: check `ok` and `results[].ok`, not only the HTTP status. A plan-gated op (scripting without a paid plan) is dropped and listed in `blocked` while the rest applies. The call is not idempotent: a retried batch appends the clips again.

## Path parameters

- `id` string, required

## Request body

- object
  - `commands` object[], required: One to 200 commands, applied in order. Each is an object with a string `op` and that op's parameters, exactly as listed by `GET /v1/schema/commands`.
  - `dryRun` boolean: Run the batch without saving and return what would happen.

## Response `200`

Apply commands

- object
  - `projectId` string: The project.
  - `ok` boolean: `true` only when every command succeeded.
  - `dryRun` boolean: Whether anything was saved.
  - `results` unknown[]: One entry per command: `{ op, ok, error?, data? }`. A failed command is reported here, not as an HTTP error.
    - unknown
  - `verification` object: What happened: `accepted` (count), `failed` (`[{ op, error }]`), `blocked`, `layout` warnings, and `outcome` (`executed`, `needs-repair` or `blocked`).
  - `blocked` string[]: Plan-gated features that were dropped.
  - `lint` unknown[]: Layout warnings: `{ severity: "warn" | "note", time, message }`.
    - unknown
  - `suggestedPreviewTimes` number[]: Timestamps worth looking at with the preview endpoint before you render.
  - `timeline` object: `{ clipCount, durationSec }` after the batch.
  - `hint` string: What to check next.

## Other responses

- `400`: `invalid_request`: `commands` is missing, empty, longer than 200, or an entry has no string `op`.
- `404`: `not_found`: No such project, or it is not yours. The two are indistinguishable on purpose.
- `409`: `invalid_request`: The project changed while the batch ran (`conflictCode: "stale_rev"`, with `rev`) or is locked by an expert handoff (`help_handoff_locked`). Re-read the project and retry.

---

[API](https://skmtc.dev/vidmoat/apis/vidmoat-api.md) · [All operations](https://skmtc.dev/vidmoat/apis/vidmoat-api/llms.txt) · [OpenAPI document](https://skmtc.dev/vidmoat/apis/vidmoat-api/revisions/23e24e25c756?raw)
