---
title: "Rename a drop or change its credit ceiling"
method: PATCH
path: "/v1/engine/runs/{id}"
tags: ["Drops"]
---

# Rename a drop or change its credit ceiling

`PATCH /v1/engine/runs/{id}`

## Request

- Base URL: `https://aicontentdrop.com`
- URL: `https://aicontentdrop.com/v1/engine/runs/{id}`
- Auth: HTTP bearer

Change a drop's title or its credit ceiling. `revision` is required and must be the one the drop currently carries, so two writers cannot silently overwrite each other. Raising `budget_credits` also puts back the steps the old ceiling was holding: they are priced and judged again against the new number on the next claim, which grants nothing by itself.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `revision` integer, required: The revision this write expects. A stale one is answered 409 REVISION_CONFLICT.
  - `title` string
  - `approval_mode` 'confirm_each'
  - `budget_credits` integer, nullable: Null removes the ceiling.

## Response `200`

The drop after the change.

- DropRunEnvelope: The drop after the write that was asked for.
  - `run` DropRun, required: One drop, as every caller sees it. `phase` is a property of the drop, never a place to navigate to; `revision` is bumped by every write and is what a conditional write is checked against.
    - `id` string, uuid, required
    - `title` string, required
    - `goal` string, required
    - `phase` 'intake' | 'research' | 'concept' | 'plan' | 'produce' | 'assemble' | 'distribute' | 'done', required
    - `status` 'idle' | 'running' | 'waiting_input' | 'waiting_approval' | 'failed' | 'done' | 'cancelled', required
    - `lane` 'cinematic' | 'ugc' | 'marketing' | 'null', nullable: Which recipe this drop follows. Null while the lane is still a question.
    - `approvalMode` 'confirm_each', required: confirm_each is the only mode served: the drop stops before every step that would charge credits.
    - `budgetCredits` integer, nullable, required: The credit ceiling for the whole drop, or null for none. Approving a step cannot lift it.
    - `creditsQuoted` number, required
    - `creditsSpent` number, required: Credits charged so far. Work that failed charges nothing.
    - `revision` integer, required
    - `canvasId` string, nullable, required: The board this drop builds its artifacts on, once it has one.
    - `error` string, nullable
    - `entities` DropEntities, required: Everything a drop has made, keyed by kind and then by id. An artifact enters once and is referenced afterwards, so ids stay stable for the life of the drop. Instructions sent to a producer, internal model ids and job references are not part of this projection and never appear.
      - `brief` object: The settled brief: what is being made, for what, how long, on which recipe.
      - `videos` object
      - `images` object
      - `ads` object
      - `research` object: Competitor rows read for this drop. Each carries `demo` and `analysed` so a sample row is never shown as an observed one.
      - `concepts` object: Angles, each bound to the research ids it rests on.
      - `storyboards` object
      - `boards` object: The board this drop builds on, with its link.
      - `quotes` object
    - `counters` DropCounter[], required
      - `word` 'retrieved' | 'analysed' | 'selected' | 'generated' | 'checked', required
      - `count` integer, required: The number of ids below.
      - `label` string, required: What was counted, in the words a person reads.
      - `coverage` string: How it was measured, when the word alone would overstate it.
      - `bucket` 'brief' | 'videos' | 'images' | 'ads' | 'research' | 'concepts' | 'storyboards' | 'boards' | 'quotes', required: Which bucket of this drop's artifacts the ids live in.
      - `ids` string[], required
    - `shared` boolean, required: Whether this drop currently has a share link. The address itself is returned only to the POST that minted it.
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time, required

## Other responses

- `400`: The body was rejected. `code` names the class of problem and `details` names the fields.
- `401`: Missing, malformed, revoked, or budget-exhausted API key
- `404`: No drop with that id on this account — or the whole surface is absent, which is what an account that is not enabled for drops sees. Drops are available to accounts enabled for them; on those accounts every path below answers `{"error":{"code":"not_found"}}` and nothing else, so an unlisted caller cannot tell an enabled surface from an absent one. On an enabled account, this is a drop id that does not exist or is not yours.
- `409`: The drop is not in a state that allows this. `code` says which: `RUN_BUSY` (it is working on the last message), `RUN_FINISHED`, `REVISION_CONFLICT` (it changed while your request was in flight — read it again and repeat), `TASK_NOT_AWAITING_APPROVAL`, `QUOTE_UNKNOWN` (that step has no priced quote yet), or `QUOTE_EXPIRED` (the price lapsed, so nothing was released).
- `429`: Rate limited. Read Retry-After (header) or error.retry_after_seconds (body) — they carry the same number — and wait that long. Retrying sooner extends the window rather than shortening it.
- `500`: Unexpected failure on our side. Retry once; nothing was charged.

---

[API](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api.md) · [All operations](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api/llms.txt) · [OpenAPI document](https://skmtc.dev/aicontentdrop/apis/ai-content-drop-api/revisions/75a13a8043ae?raw)
