---
title: API reference
url: https://docs.schemalabs.ai/api-reference
description: REST reference for the Schema API: base URL, authentication, errors, idempotency, async jobs, pagination, identifiers, and every route.
---

# API reference

> REST reference for the Schema API: base URL, authentication, errors, idempotency, async jobs, pagination, identifiers, and every route.

The Schema API is a REST API over JSON. Every route lives under `/v2/`, authenticates with an org-scoped API key, and returns one error envelope on failure. What you create over the API appears in the platform immediately, and both draw one usage meter. One stateless call, the quick run (`POST /v2/run`), and one stateful object, the endpoint (`create`, `serve`, `refresh`, `upgrade`). Every pass emits the full output bundle; outputs are free.

## Basics

- **Base URL**: `https://api.schemalabs.ai`
- **Version**: all routes under `/v2/`. A breaking change mints `/v3`; adding fields to the bundle is non-breaking and announced. Tolerate unknown fields. Base models (`schema-{n}`) and endpoint state are separate version axes.
- **Auth**: `Authorization: Bearer $SCHEMA_API_KEY`. Keys are org-scoped with operation scopes (`read`, `run`, `serve`, `manage`, `delete`). See [Authentication](https://docs.schemalabs.ai/authentication).
- **Content type**: `application/json` in and out. Timestamps are ISO 8601 UTC. Large data enters through datasets and connections, not request bodies.
- **OpenAPI**: every live endpoint publishes its own description at `https://api.schemalabs.ai/v2/openapi/{endpoint_id}`, importable into any tool that reads OpenAPI. See [Endpoint OpenAPI description](https://docs.schemalabs.ai/api-reference/endpoints#endpoint-openapi).
- **Rate limits**: requests per minute and cells per minute, per org and per key. Exceeding returns `429` with `Retry-After`. See [Rate limits](https://docs.schemalabs.ai/billing#rate-limits).
- **Metering**: cells (rows x columns), summed per table. Inputs metered, outputs free. See [Usage and billing](https://docs.schemalabs.ai/billing).

## Errors

Every non-2xx response returns one envelope: `{ "error": { "type", "message", "param", "request_id" } }`. The `type` is one of eight machine-readable strings, `param` points at the offending field when there is one, and `request_id` is what to quote to support. A run, creation, or serve either returns the full bundle or fails as `job_failed`: every success is a complete bundle, and failed jobs bill nothing.

| type | HTTP | When |
|---|---|---|
| `validation_error` | 400 | A field is malformed, or data POSTed to an endpoint does not match its pinned snapshot’s schema (the message names the divergence). |
| `auth_error` | 401 / 403 | Missing or invalid key (401), or the key lacks the route’s scope (403). |
| `not_found` | 404 | Unknown endpoint, dataset, report, job, or key id; or a deleted endpoint’s URL. |
| `conflict` | 409 | An `Idempotency-Key` reused with a different body; a second mutating job on an endpoint that already has one running (the envelope carries `running_job_id`); unpinning or deleting a dataset a live endpoint depends on (the message names the endpoint). |
| `capability_unavailable` | 422 | The request names a retired base: a run, creation, or serve on it. Omit `base` for the latest model, or upgrade the endpoint. |
| `rate_limit` | 429 | Requests per minute or cells per minute exceeded, per org, per key, or per endpoint. `Retry-After` states when to retry. |
| `job_failed` | 500 | An async job could not complete. The job object carries the error message. Nothing is billed. |
| `internal` | 5xx | Something on our side. Retry with backoff and quote the `request_id` if it persists. |

### Handling errors

Branch on `error.type`, not on the message. Retry `rate_limit` after `Retry-After` and `internal` with exponential backoff; retried POSTs are safe when you send an `Idempotency-Key`. Treat `conflict` on refresh or upgrade as "wait for `running_job_id`". Surface `validation_error.param` to whoever owns the request payload.

## Idempotency

`POST /v2/run`, `POST /v2/endpoints`, `refresh`, `upgrade`, and `POST /v2/data/generate` accept an `Idempotency-Key` header: any string unique per logical request (a UUID is the usual choice), reused on every retry of that request. A retried POST with the same key and body returns the original result or job; the same key with a different body is `409 conflict`. Send one on every expensive submit, especially from CI and retrying clients.

## Async jobs

Endpoint creation, refresh, upgrade, synthetic generation, and large or batch quick runs return `202` with a `job_id`. Poll `GET /v2/jobs/:id`, or rely on the platform notification and email on completion. Status flow: `queued` -> `running` -> `done` | `failed` | `cancelled` | `expired`.

- The endpoint id is assigned at submit, so `GET /v2/endpoints` lists it immediately as `creating`; it flips to `live` when the job completes.
- A job either completes with its full result or fails as `job_failed`. Failed and cancelled jobs bill nothing; a batch job that misses its completion window expires unbilled.
- `POST /v2/jobs/:id/cancel` stops a queued or running job. A cancelled creation stops the creation, and the endpoint can be deleted or created again; a cancelled refresh or upgrade leaves the endpoint serving its previous state.

## Pagination

Large arrays (`unified_rows.rows`, `prediction.results`, `imputation.filled`) return a first page inline (`sample_shown`) plus a cursor; `total` is always the full count. Full retrieval is cursor pagination (`?cursor=...&limit=...`) over the endpoint or report resource, or `options.out` on a large quick run to write the bundle to a file or warehouse table. Lists return the resource array (`endpoints`, `datasets`, `reports`, `jobs`), `next_cursor`, and `total`; `GET /v2/keys` returns the full list.

Data POSTed to an endpoint is validated against the schema of its pinned snapshots; a mismatch is a `400 validation_error` naming the divergence.

## Identifiers

One canonical scheme: the endpoint ID is the one unprefixed id; every other resource carries a prefix. Immutable ids never change on rename, refresh, or upgrade; an endpoint name is a mutable alias, and routes accept either. Surfaces truncate the endpoint ID to its first 8 characters for display; the full ID is the identifier. Snapshots, reports, and ids are immutable once minted.

| Resource | Formulation | Mutable | Example |
|---|---|---|---|
| Endpoint | opaque unique ID, assigned at creation | immutable | `{endpoint_id}` |
| Endpoint name | lowercase slug, user-chosen | mutable (rename) | `churn` |
| Base | `schema-{n}`; abbreviated `s{n}` in report names | n/a | `schema-2, s2` |
| Report id | `r_{hex}` | immutable | `r_8f3a` |
| Report name | `{endpoint}.{base}.{op}.{YYYY-MM-DD}` | reflects the name at mint | `churn.s2.upgrade.2026-08-14` |
| Quick run | `run_{id}` | immutable | `run_9f2a4c` |
| Job | `job_{id}` | immutable | `job_9a5b01d4` |
| Connection | `conn_{id}` plus a scheme ref | immutable | `conn_3f9a, snowflake://…` |
| Dataset | `ds_{id}` | immutable | `ds_crm01` |
| Dataset snapshot | `dsv_{id}`, minted per ingest or sync | immutable | `dsv_91f2` |
| API key id | `key_{id}` | immutable | `key_77ab` |
| API key secret | `sk_live_{rand}` | shown once | `sk_live_…` |
| System prompt fragment | `sp_{id}` (body versioned) | immutable id | `sp_12` |
| Request | `req_{id}` in every error envelope and log | n/a | `req_e7f04a` |

## All routes

| Method | Path | Does | Scope | Reference |
|---|---|---|---|---|
| `POST` | `/v2/run` | Create a quick run | `run` | [Quick run](https://docs.schemalabs.ai/api-reference/run#create-run) |
| `POST` | `/v2/data/connect` | Connect a source | `manage` | [Data](https://docs.schemalabs.ai/api-reference/data#connect-data) |
| `GET` | `/v2/data` | List data | `read` | [Data](https://docs.schemalabs.ai/api-reference/data#list-data) |
| `GET` | `/v2/data/:id` | Retrieve data | `read` | [Data](https://docs.schemalabs.ai/api-reference/data#retrieve-data) |
| `POST` | `/v2/data/:id/sync` | Sync a connection | `manage` | [Data](https://docs.schemalabs.ai/api-reference/data#sync-data) |
| `POST` | `/v2/data/:id/pin` | Pin a dataset | `manage` | [Data](https://docs.schemalabs.ai/api-reference/data#pin-data) |
| `POST` | `/v2/data/:id/unpin` | Unpin a dataset | `manage` | [Data](https://docs.schemalabs.ai/api-reference/data#unpin-data) |
| `POST` | `/v2/data/generate` | Generate synthetic data | `manage` | [Data](https://docs.schemalabs.ai/api-reference/data#generate-data) |
| `DELETE` | `/v2/data/:id` | Delete data | `delete` | [Data](https://docs.schemalabs.ai/api-reference/data#delete-data) |
| `POST` | `/v2/endpoints` | Create an endpoint | `manage` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#create-endpoint) |
| `GET` | `/v2/endpoints` | List endpoints | `read` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#list-endpoints) |
| `GET` | `/v2/endpoints/:id` | Retrieve an endpoint | `read` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#retrieve-endpoint) |
| `POST` | `/v2/serve/:id` | Serve an endpoint | `serve` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#serve-endpoint) |
| `POST` | `/v2/endpoints/:id/refresh` | Refresh an endpoint | `manage` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#refresh-endpoint) |
| `POST` | `/v2/endpoints/:id/upgrade` | Upgrade an endpoint | `manage` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#upgrade-endpoint) |
| `GET` | `/v2/endpoints/:id/logs` | Endpoint logs | `read` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#endpoint-logs) |
| `GET` | `/v2/openapi/:id` | Endpoint OpenAPI description | `read` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#endpoint-openapi) |
| `DELETE` | `/v2/endpoints/:id` | Delete an endpoint | `delete` | [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints#delete-endpoint) |
| `GET` | `/v2/reports` | List reports | `read` | [Reports](https://docs.schemalabs.ai/api-reference/reports#list-reports) |
| `GET` | `/v2/reports/:id` | Retrieve a report | `read` | [Reports](https://docs.schemalabs.ai/api-reference/reports#retrieve-report) |
| `GET` | `/v2/jobs` | List jobs | `read` | [Jobs](https://docs.schemalabs.ai/api-reference/jobs#list-jobs) |
| `GET` | `/v2/jobs/:id` | Retrieve a job | `read` | [Jobs](https://docs.schemalabs.ai/api-reference/jobs#retrieve-job) |
| `POST` | `/v2/jobs/:id/cancel` | Cancel a job | `manage` | [Jobs](https://docs.schemalabs.ai/api-reference/jobs#cancel-job) |
| `GET` | `/v2/models` | List models | `read` | [Models](https://docs.schemalabs.ai/api-reference/models#list-models) |
| `GET` | `/v2/usage` | Retrieve usage | `read` | [Usage](https://docs.schemalabs.ai/api-reference/usage#retrieve-usage) |
| `GET` | `/v2/keys` | List keys | `read` | [API keys](https://docs.schemalabs.ai/api-reference/keys#list-keys) |
| `POST` | `/v2/keys` | Create a key | `manage` | [API keys](https://docs.schemalabs.ai/api-reference/keys#create-key) |
| `POST` | `/v2/keys/:id/rotate` | Rotate a key | `manage` | [API keys](https://docs.schemalabs.ai/api-reference/keys#rotate-key) |
| `DELETE` | `/v2/keys/:id` | Revoke a key | `delete` | [API keys](https://docs.schemalabs.ai/api-reference/keys#revoke-key) |

## Resources

- [Quick run](https://docs.schemalabs.ai/api-reference/run.md): Run Schema over the tables in one request: a stateless pass that returns the full output bundle, the same call the platform's Quick run page makes.
- [Data](https://docs.schemalabs.ai/api-reference/data.md): Register connections and datasets under /v2/data, sync snapshots, pin data for the cached rate, generate synthetic tables, and delete what you no longer need.
- [Endpoints](https://docs.schemalabs.ai/api-reference/endpoints.md): Create, serve, refresh, upgrade, and delete endpoints: a base plus pinned data, a configuration, system prompts, and a held-out report at a stable URL.
- [Reports](https://docs.schemalabs.ai/api-reference/reports.md): List and retrieve held-out reports: the immutable trust artifact minted by every endpoint create, refresh, and upgrade, with its split, baseline, and snapshot.
- [Jobs](https://docs.schemalabs.ai/api-reference/jobs.md): List, poll, and cancel the async jobs behind endpoint creation, refresh, upgrade, synthetic data generation, and batch quick runs.
- [Models](https://docs.schemalabs.ai/api-reference/models.md): List the Schema models available to your organization, which one is the default, and any Enterprise fine-tune you own.
- [Usage](https://docs.schemalabs.ai/api-reference/usage.md): Read your organization's usage meter: cells drawn per surface and per operation, percent of the weekly allowance used, and add-usage settings.
- [API keys](https://docs.schemalabs.ai/api-reference/keys.md): List, create, rotate, and revoke org-scoped API keys carrying the read, run, serve, manage, and delete scopes.
