> ## Documentation Index
> Fetch the complete documentation index at: https://docs.tryflowy.ai/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> Flowy is a node-based AI creative platform: you generate images, video, audio, 3D and vector on an infinite Canvas, refine on the Studio timeline, and export or publish from the same project.
> Prefer the Flowy MCP server (https://mcp.tryflowy.ai/mcp) or the REST API at https://apis.tryflowy.ai/v1 for programmatic work. Install with `flowy mcp install` from the @flowy/cli package.
> Credits are workspace-scoped. Generations reserve credits on start and only deduct on success, so failed runs refund automatically.

# Errors

> How the Flowy API reports errors, and what each status code means.

The Flowy API uses conventional **HTTP status codes** to indicate the success or failure of a request. The status code is the machine-readable signal; every error also returns a human-readable `error` message in the body:

```json theme={"theme":{"light":"github-light","dark":"vesper"}}
{
  "error": "this API key lacks the runs:write scope"
}
```

In general: `2xx` means success, `4xx` means the request was rejected and usually tells you how to fix it, and `5xx` means something went wrong on Flowy's side.

## Status codes

<AccordionGroup>
  <Accordion title="200 / 202: Success">
    **Problem:** None: the request succeeded. `202 Accepted` is returned when a run is accepted for processing; `200 OK` for everything else.

    **Solution:** For a `202`, poll [Get a run](/api/get-run) until its `status` is `completed` or `failed`.
  </Accordion>

  <Accordion title="400: Bad request">
    **Problem:** The request was malformed, or a `params` entry (see [Get a flow](/api/get-app)'s `params[]`) doesn't satisfy its schema. An unrecognized or missing `inputs` entry does **not** land here. See the note below.

    **Solution:** Check the request body against the flow's schema. `inputs` must be an array of entries, each with a `node_id` (an input's `name`) and a value `asset_url` for media inputs or `prompt` for text inputs. `params` must be an object keyed by a param's `name`, each value matching its `kind`. Two codes cover it, both with a `details: { field, expected, received }` alongside `error`:

    * `invalid_body`: the body isn't valid JSON, or `inputs` / `params` has the wrong shape (`inputs` must be an array or an object, `params` an object).
    * `unknown_param`: the key isn't any of the flow's published param names; `error` lists the valid ones.
    * `invalid_param`: the value doesn't satisfy the param's `kind` (wrong type, out of `min`/`max`, off the `step`, or not one of `enumValues`).

    ```json theme={"theme":{"light":"github-light","dark":"vesper"}}
    {
      "error": "unknown param \"hero-video-duration\"; expected one of: hero-video-resolution",
      "code": "unknown_param",
      "details": { "field": "hero-video-duration", "expected": "one of: hero-video-resolution", "received": "hero-video-duration" }
    }
    ```
  </Accordion>

  <Accordion title="Not an error: unrecognized or missing inputs">
    **Problem:** An `inputs` entry names a `node_id` the flow doesn't have, or a required content input was left out.

    **Solution:** Nothing to fix necessarily: this never fails the request. The `202` response carries a `warnings` array instead (`code: "unknown_input"` or `"missing_input"`, plus `field` and `message`), and the run starts anyway using the flow's published content for anything missing. Read `warnings` if you want to catch a typo'd `node_id` early.
  </Accordion>

  <Accordion title="401, Unauthorized">
    **Problem:** The API key is missing, malformed, revoked, or expired.

    **Solution:** Send the key in the `Authorization: Bearer flowy_…` header and confirm it's still active under **Settings → API keys**.
  </Accordion>

  <Accordion title="402: Payment required">
    **Problem:** The key hit its **daily spend cap**, or the workspace is out of credits.

    **Solution:** Raise the key's cap, top up the workspace's credits, or wait for the next UTC day. The available balance is the hard backstop. When it reaches zero, runs stop regardless of any cap.
  </Accordion>

  <Accordion title="403: Forbidden">
    **Problem:** The request is authenticated but not allowed. Common causes: the key lacks the required [scope](/api/permissions); the flow is private and not in the key's workspace; the run belongs to another workspace; or a publishable key was used from a domain that isn't allowlisted.

    **Solution:** Grant the key the needed scope, use a key from the flow's own workspace, or call from an allowed domain.
  </Accordion>

  <Accordion title="404, Not found">
    **Problem:** No flow or run matches the `appId` / `runId` in the path.

    **Solution:** Double-check the id. List flows with [List flows](/api/list-apps), and use the `runId` returned by [Start a run](/api/start-run).
  </Accordion>

  <Accordion title="429: Too many requests">
    **Problem:** You exceeded the key's per-minute request limit or its concurrent-run limit.

    **Solution:** Back off and retry after the `Retry-After` interval. Watch the `X-RateLimit-Remaining` header and keep in-flight runs under the limit. See [Rate limits](/api/rate-limits).
  </Accordion>

  <Accordion title="500: Internal server error">
    **Problem:** Something went wrong on Flowy's side.

    **Solution:** Retry after a short delay. If it persists, [contact support](mailto:contact@tryflowy.ai) with the time of the request.
  </Accordion>
</AccordionGroup>

## Handling failed runs

A run can also fail **after** it starts: for example, an upstream generation error. In that case the run reaches `status: "failed"` with a human-readable `error` field; poll [Get a run](/api/get-run) to read it. Credits for a failed generation are refunded to the workspace automatically.

```json theme={"theme":{"light":"github-light","dark":"vesper"}}
{
  "data": {
    "runId": "64c3f2a1e8b9c0d1f2e3a4b5",
    "status": "failed",
    "error": "the upstream model rejected the input image"
  }
}
```
