---
title: "Answer the questions a drop asked"
method: POST
path: "/v1/engine/runs/{id}/answer"
tags: ["Drops"]
---

# Answer the questions a drop asked

`POST /v1/engine/runs/{id}/answer`

## Request

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

Answer the short questions a drop asked before it can plan, keyed by the question ids it gave. The answers are folded into the brief and the turn continues in the background, so this returns as soon as the drop has taken them rather than holding the request open; read the drop again, or attach to its stream, for what happens next.

## Path parameters

- `id` string, uuid, required

## Request body

- object
  - `revision` integer: Optional. When given it must be the drop's current revision.
  - `answers` object, required: Question id to the answer, as plain strings.

## Response `200`

The answers were taken and the drop is working again.

- 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)
