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

# Asynchronous operations

> How long-running work returns 202 + an execution, and how to track it.

Some operations call external providers (a transcriber, an LLM, the YouTube API)
and can take seconds to minutes. Instead of blocking, these endpoints **accept
the work and return immediately** with HTTP `202` and an **execution** you track
to completion.

## Which endpoints are async

| Endpoint                                      | Returns                       |
| --------------------------------------------- | ----------------------------- |
| `POST /v1/items/{id}/transcript`              | `202 { execution }`           |
| `POST /v1/reporters/{id}/process`             | `202 { execution }`           |
| `POST /v1/reporters/{id}/process-collection`  | `202 { execution }`           |
| `POST /v1/reporters/{id}/schedules/{sid}/run` | `202 { status, schedule_id }` |

Everything else (reads, CRUD on collections/reporters/workflows/schedules) is
synchronous — it returns the final result directly.

## The execution lifecycle

```
pending ──▶ running ──▶ done
                   └──▶ error
```

The `202` body gives you an `execution` with an `execution_id` and an initial
`status`:

```json theme={null}
{ "execution": { "execution_id": "exc_…", "status": "pending" } }
```

## Tracking to completion (polling)

Poll the execution until it leaves `pending`/`running`:

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.clipping.cc/v1/executions/exc_123 \
    -H "Authorization: Bearer ck_live_…"
  ```

  ```python Python theme={null}
  import time, requests

  H = {"Authorization": "Bearer ck_live_…"}

  def wait(execution_id, every=2.0, timeout=300):
      deadline = time.time() + timeout
      while time.time() < deadline:
          r = requests.get(
              f"https://api.clipping.cc/v1/executions/{execution_id}", headers=H
          ).json()
          status = r["execution"]["status"]
          if status in ("done", "error"):
              return r
          time.sleep(every)
      raise TimeoutError(execution_id)
  ```
</CodeGroup>

The detail response includes the `execution`, the `workflow` that ran, per-step
`summaries` (LLM input/output), and `step_inputs` for steps not yet run.

<Tip>
  To see everything currently in flight, call
  `GET /v1/executions/me?active=1` — it returns only `pending`/`running`
  executions. Handy for a dashboard or a "still working" indicator.
</Tip>

## Realtime (app only)

The web app doesn't poll — it subscribes to the realtime WebSocket
(`wss://api.clipping.cc/v1/realtime?token=<jwt>`) and receives `event` messages
as executions progress.

<Warning>
  The WebSocket authenticates with a **session JWT only** (in the `token` query
  param) — an API key cannot open it. If you're integrating with an API key,
  **poll** `GET /v1/executions/{id}` as shown above.
</Warning>

## Cost

The `202` itself draws the route's flat fee (e.g. `0.01 coin` for running a
transcript). The **real provider cost** is drawn as pass-through from the
resource owner while the job runs — so a job can still end in `402` if the owner
runs out of balance mid-flight.
