# API overview

> The base URL, how jobs work, versioning, idempotency and where to find each endpoint. Everything the web tool does, over HTTP.

Page: https://scribiz.com/docs/api

The API turns a link or an uploaded file into a Context. The web tool uses these same routes.

```text
https://scribiz.com/api
```

Every path in these docs is relative to that base: `POST /v1/context` is `POST https://scribiz.com/api/v1/context`. The website and your own scripts use this one address, so a browser session stays on one origin. Sign-in sits under the same base, at `https://scribiz.com/api/auth/...`. The remote MCP server is a path of its own: `https://scribiz.com/mcp`.

## How it works

Processing a video takes seconds to minutes, so the API is asynchronous:

1. `POST /v1/context` with a link or an upload. It checks the request, quotes the cost, and answers `202` at once with a `job_id`. If it cannot accept the job, it answers with an error before anything is queued.
2. Follow the job. `GET /v1/jobs/:id` always tells you where it stands, and when it is done, it holds the Context in `result`.
3. Optionally, `GET /v1/jobs/:id/events` streams progress as it happens.

The job is the source of truth. The event stream is a convenience. If you lose a connection, nothing is lost: ask for the job again.

A cached result still goes through a job. The quote says `cached: true`, the charge is 0, and the job finishes in under a second.

## Conventions

- **JSON.** Requests and responses are JSON, in UTF-8, with `Content-Type: application/json`. Uploads are the exception.
- **Names.** The fields of the job API are `snake_case`: `job_id`, `events_url`, `minutes_charged`. The Context, the progress events and the job's `error` are the engine's own, in `camelCase`.
- **Times.** In the Context, times are seconds, as numbers rounded to milliseconds. Timestamps of the job and of the account, such as `created_at` and `expires_at`, are milliseconds since the Unix epoch.
- **Ids.** A job id looks like `job_` and 22 letters and digits. An upload id starts with `upl_`. A key id starts with `key_`.
- **Speakers** have stable ids across a Context: `S1`, `S2`, and so on.
- **Authentication** is a bearer API key. See [Authentication](https://scribiz.com/docs/api/authentication.md).
- **Idempotency.** Send an `Idempotency-Key` header with `POST /v1/context`. If the request is repeated with the same key and the same body, you get the same job back, with the header `Idempotent-Replayed: true` and `"idempotent_replay": true` in the body, not a second job and not a second charge. The same key with a different body is `422` with `idempotency_key_reused`. A key is 1 to 200 letters, digits, `_`, `.`, `:` or `-`. Use a new random value per logical request, such as a UUID.
- **Usage** is counted in minutes. See [Minutes and billing](https://scribiz.com/docs/minutes-and-billing.md).
- **Errors** have one shape, described on [Errors and limits](https://scribiz.com/docs/api/errors.md).

## Versioning

The version is in the path: `/v1`. Within a version, changes are additive: new fields and new values can appear, and existing fields keep their meaning. Ignore fields you do not know.

The Context also carries its own version in `schema`. It is `1` today. Anything that would break a reader, such as removing a field, bumps it.

## The routes

| Route | What it does |
| --- | --- |
| `POST /v1/context` | Create a job from a link or an upload |
| `GET /v1/jobs/:id` | Job status and, when done, the Context |
| `GET /v1/jobs/:id/events` | Server-sent events for a job |
| `DELETE /v1/jobs/:id` | Cancel a running job, or delete a finished result |
| `PUT /v1/uploads` | Upload a file to use in a job |
| `POST /v1/transcribe` | Upload a file and create a job in one call |
| `POST /v1/ask` | Ask a question about a finished job's Context |
| `GET /v1/me` | Your account, plan and minutes |
| `GET /v1/keys` | List API keys. Creating and revoking keys needs a signed-in session. |
| `GET /v1/status` | Queue length, and how each source is doing |
| `GET /v1/openapi.json` | The OpenAPI description |
| `/mcp` | The remote MCP server. See [MCP](https://scribiz.com/docs/mcp.md) |
| `GET /health` | Returns `{"ok":true}` |

Each route is described on [Endpoints](https://scribiz.com/docs/api/endpoints.md). The shape of `result` is on [The Context object](https://scribiz.com/docs/api/context-object.md). Failures and limits are on [Errors and limits](https://scribiz.com/docs/api/errors.md).

## OpenAPI

`GET /v1/openapi.json` returns an OpenAPI 3.1 description you can feed to a code generator or an API client. If it and these pages ever disagree, the OpenAPI document describes what the server does today.

## Not here yet

Webhooks, for example a call to your server when a job finishes, are not available. Poll the job or follow its events.

---

Checked against the Scribiz build on 2026-10-05.
