# HTTP API

> The base URL, authentication, how slow work answers, pagination, streaming and retries.

Source: https://docs.fous.com/guides/api
Index: https://docs.fous.com/llms.txt

Every endpoint lives under `https://api.fous.com/v1`. Requests and responses are JSON, and every `/v1` endpoint takes your [API key](https://docs.fous.com/authentication.md) as a bearer header. The exact contract is [OpenAPI 3.1](https://api.fous.com/openapi.json); the [API reference](https://docs.fous.com/api-reference.md) is generated from it.

```bash
curl https://api.fous.com/v1/account \
  -H "Authorization: Bearer $FOUS_API_KEY"
```

`GET` reads take query parameters, `POST` does work and takes a JSON body of at most 4 MB, and IDs go in the path. Fields your request doesn't send take their defaults; an unknown body field answers `400 invalid_request` with the reason.

## Slow work

Runs, builds and workflow runs can outlast a single HTTP request, so they answer in one of two ways: `200` when the work ended in time, or `202` with its `id` while it goes on. Work that answers `202` keeps going whether or not you hold on.

- `POST /v1/runs`, `POST /v1/builds` and `POST /v1/workflows/{id}/runs` take `wait` in the body, in seconds from 0 to 60: 30 by default for runs, 0 for builds and workflow runs.
- `GET /v1/runs/{id}`, `GET /v1/builds/{id}`, `GET /v1/connections/{id}`, `GET /v1/methods/{domain}/{name}` and `GET /v1/workflows/{id}/runs/{run_id}` take `?wait=60` (0 to 60 seconds) and hold the answer until the work moves on or the time passes.
- `POST /v1/runs/{id}/cancel`, `POST /v1/builds/{id}/cancel` and `POST /v1/workflows/{id}/runs/{run_id}/cancel` stop the work and answer with the updated resource. A method run stopped midway is free; a workflow run keeps the cost of the steps it had already finished.

Every `POST /v1/runs` is new, charged work unless you send an `Idempotency-Key` ([Retry safely](https://docs.fous.com/guides/runs.md#retry-safely)). Keep `wait` below your HTTP client's timeout, and read a slow run by its `id` instead of sending the request again.

## Pagination

`GET /v1/runs` returns `{ "runs": [...], "has_more": true }`, newest first. `limit` is 1 to 100 (20 by default). For the next page, send the last run's `id` (or an ISO time) as `before`. `GET /v1/builds` and `GET /v1/workflows/{id}/runs` work the same way:

```bash
curl --get https://api.fous.com/v1/runs \
  -H "Authorization: Bearer $FOUS_API_KEY" \
  --data-urlencode 'before=run_01m5m0ere4fzdte37jhhn33ycd'
```

## Streaming

`POST /v1/workflows` and `PATCH /v1/workflows/{id}` send [Server-Sent Events](https://docs.fous.com/guides/workflows/create.md#watch-it-being-written) while the AI writes when you ask with `Accept: text/event-stream`.

## Retries

A failure answers an HTTP status and an `error` object with `retryable` where it applies ([Errors](https://docs.fous.com/guides/errors.md)). On `429 rate_limited` and `503`, wait for the `Retry-After` header (or `error.retry_after`, in seconds) before trying again. A `POST /v1/hooks/{token}` call is safe to repeat with the same `Idempotency-Key`. So is a [run](https://docs.fous.com/guides/runs.md#retry-safely) sent with one; without it, a retry is a new run. Check first when a failure says `may_have_run: true`.

Every response has an `X-Request-Id`; a failure repeats it as `error.request_id`. Quote it to support, along with the `code`, never a key.
