# API reference

[Read this page in HTML](https://www.scopedb.io/docs/api-reference)

Use the ScopeDB HTTP API to [run statements](https://www.scopedb.io/docs/api-reference/statements.md), [append rows](https://www.scopedb.io/docs/api-reference/append.md), and [manage Catalog definitions](https://www.scopedb.io/docs/api-reference/catalog.md). This reference covers shared authentication, endpoints, and error handling.

For JavaScript, Go, or Rust applications, an [SDK](https://www.scopedb.io/docs/guides/sdks.md) handles requests, waits for queries, and batches writes. Use the [ScopeDB CLI](https://www.scopedb.io/docs/guides/scopedb-cli.md) for terminal workflows.

## Base URL and authentication

Copy the **ScopeDB API** address from **Home** in ScopeDB Console, then set it with an API key for the same workspace. Follow the [application connection guide](https://www.scopedb.io/docs/guides/connect-to-scopedb.md) for the setup steps.

```bash
export SCOPEDB_ENDPOINT="https://<endpoint>"
export SCOPEDB_API_KEY="<api-key>"
```

Send the key as a bearer token on every request:

```http
Authorization: Bearer <api-key>
```

Keep API keys in server-side environments. Do not ship them in browser or mobile clients.

## Endpoints

| Method                 | Path                                                                      | Task                                                                                                                                             |
| ---------------------- | ------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------ |
| `POST`                 | `/v1/statements`                                                          | [Submit a statement](https://www.scopedb.io/docs/api-reference/statements.md#submit-a-statement).                                                |
| `GET`                  | `/v1/statements/{statement_id}?format=json`                               | [Poll a statement](https://www.scopedb.io/docs/api-reference/statements.md#poll-a-statement) and read its result.                                |
| `POST`                 | `/v1/statements/{statement_id}/cancel?format=json`                        | [Cancel a statement](https://www.scopedb.io/docs/api-reference/statements.md#cancel-a-statement).                                                |
| `POST`                 | `/v1/catalog/databases/{database}/schemas/{schema}/tables/{table}/ingest` | [Append rows](https://www.scopedb.io/docs/api-reference/append.md) that match a table.                                                           |
| `GET`, `PUT`, `DELETE` | `/v1/catalog/...`                                                         | [Read or change Catalog definitions](https://www.scopedb.io/docs/api-reference/catalog.md#resources). The catalog root supports `GET` and `PUT`. |

Names embedded in URL paths must be percent-encoded as individual path segments. URL encoding does not quote identifiers inside a ScopeQL statement.

## Errors and retries

The following error formats and HTTP status guidance apply across statement, Append, and Catalog requests. Retry decisions depend on the operation and its outcome.

Data API failures use a structured error body with a stable `code`, a diagnostic `message`, and optional code-specific `details`. For example:

```json
{
  "code": "invalid_request",
  "message": "max_elapsed_seconds must be positive, finite, and within the supported timestamp range"
}
```

Authentication and gateway failures can instead return an `error` envelope:

```json
{
  "error": {
    "message": "unauthorized"
  },
  "request_id": "6c2bd761-9695-44c7-9723-215f618d1199"
}
```

Accept both shapes when building a client. Preserve `X-Request-ID` when present, or the body's `request_id`, for support reports. Branch on `code` when supplied and allow for unknown codes; message wording can change. A gateway can also return a non-JSON response, so retain the HTTP status when error decoding fails.

Statement execution failures can instead arrive in-band as a `failed` or `cancelled` statement state with an HTTP `2xx` response. Always combine the HTTP status with the statement state:

| Response | Guidance                                                                                                   |
| -------- | ---------------------------------------------------------------------------------------------------------- |
| `400`    | Fix the request body or required headers before retrying.                                                  |
| `401`    | Correct the API key; do not retry unchanged credentials.                                                   |
| `403`    | Check the API address, API key, and intended workspace.                                                    |
| `404`    | Check the path or statement ID. For an ambiguous mutating submission, see below.                           |
| `409`    | Inspect the conflict; Catalog changes may require a new plan or explicit destructive-change opt-in.        |
| `412`    | The Catalog ETag changed. Read the definition and preview a new plan.                                      |
| `413`    | Reduce the request body or ingest batch.                                                                   |
| `415`    | Use supported `Content-Type` and `Content-Encoding` values.                                                |
| `422`    | Fix the input rows or transformation; inspect row diagnostics when supplied.                               |
| `429`    | Back off and honor `Retry-After` when present. Establish whether a write was rejected before replaying it. |
| `5xx`    | Retry reads with backoff. For writes, inspect the operation's outcome before considering a retry.          |

Polling and Catalog `GET` requests can be retried with exponential backoff and jitter, within the application's deadline. An error being temporary does not establish that repeating a write is safe.

After a lost response to a mutating statement, the write may have completed. A caller-selected `statement_id` helps correlate polling and logs, but it is not an idempotency key, and a later `404` does not prove the mutation did not execute. Reconcile the application's data before deciding whether to retry. Use stable business identifiers and application-level deduplication when replays matter.

Append distinguishes [committed, rejected, and unknown outcomes](https://www.scopedb.io/docs/api-reference/append.md#delivery-and-retries). Catalog uses [ETags and commit-outcome errors](https://www.scopedb.io/docs/api-reference/catalog.md#handle-conflicts-and-interrupted-writes). Follow the contract for the operation you are performing.

## Related contents

* [Connect a client](https://www.scopedb.io/docs/guides/connect-to-scopedb.md)

* [SDKs](https://www.scopedb.io/docs/guides/sdks.md)
