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

# Call the Ornn API with an API key

> Create, use, rotate, and revoke organization API keys for the Ornn REST API.

Call Ornn directly over HTTPS with JSON requests and an API key. You do not need to install the Ornn CLI or run `ornn login`. Create a key once in the console, then use it from your application, scripts, or CI.

The [API reference](/api-reference/overview) documents every operation a key can call, with schemas and examples. [Download the OpenAPI specification](/openapi.yaml) for Postman, Swagger tools, or a client generator.

| Setting | Value |
| - | - |
| Base URL | `https://api.ornn.com` |
| Authentication | `Authorization: Bearer <your-api-key>` |
| Request body | JSON, with `Content-Type: application/json` |
| Organization | Bound to the key; no organization header required |
| Contract | [`https://docs.ornn.com/openapi.yaml`](/openapi.yaml) |

For a complete cluster integration, start with [Provision and manage Kubernetes through REST](/guides/kubernetes-access#provision-and-manage-through-rest).

## What a key can and cannot do

An API key acts as you in one organization: the organization that was active in the console when you created it. It has the access you have there and nothing more. It never carries Ornn staff access.

A key does not bypass organization approval, reservation ownership, payment, or node eligibility. Compute, cluster, storage, and SSH-key operations require an approved organization and return `403` with `not_approved` otherwise.

| With an API key you can | Sign in to the console instead to |
| - | - |
| Check which account and organization the key resolves to | Create, list, or revoke API keys |
| Read reservations and their GPU nodes | Edit your profile, preferences, or organization details |
| Launch machines and clusters on capacity you hold, read their access details, and tear them down | View members, invite teammates, change roles, or remove members |
| Add, assign, and revoke organization SSH keys | Change notification preferences |
| Call the other operations in the [API reference](/api-reference/overview) | |

Account, team, and key-management routes reject API keys with `403` and `detail.code` `api_key_requires_session`. API keys also cannot sign in the CLI or connect an MCP client. Use `ornn login` for the CLI and the [MCP setup](/mcp-server) for agents.

Keys don't expire. A key stops working as soon as anyone in the organization revokes it, or when its creator leaves the organization.

## Create a key

**1. Open the Developer tab**

Open **Account Settings** and select **Developer** (`/account?tab=developer`). The tab is
available once your organization is approved. Check that the organization you want the key to
use is active. Suppliers can use the **API** tab in the supplier portal instead.

**2. Create the key**

Click **Create key**, enter a name of up to 100 characters such as `CI deploys`, and confirm.

**3. Copy the key**

Copy the key, which starts with `ornn_sk_`, and store it in your secrets manager. Ornn shows it
only once and keeps only a hash, so a lost key cannot be recovered. Create a new one instead.

> [!WARNING]
>
> Treat an API key like a password. Anyone who has it can act as you in that organization until the
> key is revoked.

Create keys for long-running automation from an account that will stay in the organization. If the key's creator leaves, the key is deleted and the automation stops.

## Use a key

Send the key in the `Authorization` header as a bearer token. The key already belongs to its organization, so you don't need to name the organization in the request. Start by checking which account and organization the key resolves to.

```bash curl theme={null}
export ORNN_API_KEY="ornn_sk_example..."

curl --fail-with-body https://api.ornn.com/v1/auth/session \
  -H "Authorization: Bearer $ORNN_API_KEY"
```

```python Python theme={null}
import os

import requests

response = requests.get(
    "https://api.ornn.com/v1/auth/session",
    headers={"Authorization": f"Bearer {os.environ['ORNN_API_KEY']}"},
    timeout=30,
)
response.raise_for_status()
session = response.json()
organization_id = session["organizations"][0]["id"]
print(session["email"], organization_id)
```

A working key returns `200` with your account and exactly one entry in `organizations`: the organization you created the key in. Save that `id`; routes such as [List organization SSH keys](/api-reference/ssh-keys/list) take it in the path. Check `approved` before calling operations that need an approved organization.

A `401` means the key was revoked, mistyped, or its creator is no longer a member of that organization. See [Check API authentication](/api-reference/session) for the full response.

Suppliers: see [Use the supplier API](/supplier/api) for node, telemetry, enrollment, and listing routes.

### Import the OpenAPI contract

The contract at [`https://docs.ornn.com/openapi.yaml`](/openapi.yaml) is OpenAPI 3.1. Its server is `https://api.ornn.com` and its security scheme is a bearer token.

**Postman**

1. Choose **Import** and paste `https://docs.ornn.com/openapi.yaml`. Postman creates a collection with one request per operation.
2. Store your key in a secret environment or vault variable, for example `ornnApiKey`.
3. On the collection's **Authorization** tab, choose **Bearer Token** and set the token to `{{ornnApiKey}}`. Requests set to inherit authorization use it.
4. Send **Check API authentication** first to confirm the key and organization.

**Swagger UI**

Open the contract in Swagger UI or Swagger Editor with the same URL, then use **Authorize** to enter the key as a bearer token. Use these tools to browse schemas and generate client code.

Browsers block requests to `api.ornn.com` from pages on other sites, so **Try it out** in a hosted Swagger page fails. Send requests from Postman's desktop app, `curl`, or your own server code.

**Client generators**

Generate a client with a tool that supports OpenAPI 3.1, such as OpenAPI Generator. Configure the generated client with base URL `https://api.ornn.com` and bearer authentication, and read the key from your secret store at runtime.

Re-download the contract when you upgrade; `info.version` identifies the revision you generated against.

Keep keys out of browser code, mobile apps, and public repositories. Call the API from a server, job runner, or CI system that reads the key from a secret store.

## Rotate a key

Keys don't expire, so rotate them on your own schedule, when someone with access to the key leaves, or immediately if a key may be exposed.

**1. Create the replacement**

Create a new key in **Account Settings** → **Developer** with a name that identifies it, such as
`CI deploys 2026-10`.

**2. Deploy and verify it**

Store the new key in your secrets manager and roll it out. Confirm it returns `200` from `GET
        /v1/auth/session` with the expected organization.

**3. Revoke the old key**

Revoke the old key after every system has switched. Requests that still use it start failing
with `401`.

Both keys work during the rollout, so you can switch without downtime.

## Revoke a key

**1. Find the key**

Open **Account Settings** → **Developer**. The list shows every key in your organization, its
name, whether you or a teammate created it, and when.

**2. Revoke it**

Click **Revoke** on the key and confirm. Anything using the key stops working immediately. This
can't be undone.

Any member of the organization can revoke any of its keys. When a member leaves the organization, their keys are removed automatically.

## CLI sign-in and API keys

The Ornn CLI and the REST API use different credentials. The CLI does not read an API key from a flag or environment variable; it always uses the session `ornn login` stores.

| | `ornn login` session | API key |
| - | - | - |
| Used by | The `ornn` CLI | Your code, scripts, and CI over HTTPS |
| How you get it | Approve the browser device sign-in | **Create key** in **Account Settings** → **Developer** |
| Organizations | Every organization you belong to; switch with `ornn context` | Exactly one |
| Ends when | You run `ornn logout`, or after 14 days without use | Anyone in the organization revokes it, or you leave the organization |
| Where it is stored | `auth.json` in `~/.config/ornn`, readable only by you | Your secrets manager |

Use the CLI for interactive work and the API for unattended integrations. See [CLI and REST equivalents](/cli#cli-and-rest-equivalents) to translate a CLI command into an API request.

## Reservation REST reference

These routes read reservations visible to your key's organization: reservations it holds and sales against listings it supplies. Visibility of a sale does not grant the supplier the buyer's cluster-launch rights. Cluster creation uses existing eligible reserved capacity; it does not buy GPUs or bypass approval, payment, or reservation dates.

* [List reservations](/api-reference/reservations/list): `GET /commerce/reservations` returns `reservations` and `nextCursor`.
* [Get a reservation](/api-reference/reservations/get): `GET /commerce/reservations/{reservationId}` returns one reservation.
* [List reserved GPU nodes](/api-reference/nodes/list): `GET /v1/orchestrator/nodes?reservation_id={reservation_id}` returns the `nodes` of a reservation you hold.

```bash theme={null}
curl --fail-with-body 'https://api.ornn.com/commerce/reservations?limit=100' \
  -H "Authorization: Bearer $ORNN_API_KEY"
```

Each reservation includes `reservationId`, `status`, `startsAt`, `endsAt`, `reservedNodeCount`, and `reservedGpuCount`. Use `reservationId`, not a listing ID, in the cluster launch request. When `nextCursor` is nonempty, send it unchanged as the URL-encoded `cursor` query parameter on the next request. Continue until it is absent, null, or empty. Reservation fields use camelCase; cluster request fields use snake\_case.

See [Create a cluster](/api-reference/clusters/create) for the request and response schema, or follow the complete [Kubernetes REST walkthrough](/guides/kubernetes-access#provision-and-manage-through-rest).

## Errors and safe retries

* `401`: check that the bearer key is correct, not revoked, and its creator still belongs to the organization. Repeated requests with a rejected key from one address are throttled with `429`.
* `403`: the key does not grant the required access. Most operations require an approved organization; creating a key does not grant approval. `api_key_requires_session` means the operation needs a signed-in console session.
* `404`: verify resource ownership and IDs. Cluster credentials can also return `404` while they are not ready.
* `400` or `422`: check request fields, UUIDs, and supported values.
* `409`: resolve the reported state or capacity conflict before retrying.
* `429` or `5xx`: back off before retrying reads; honor `Retry-After` when provided.

Customer errors normally include `detail.code` and `detail.message`. Some routes return a string `detail`, a top-level `code` or `error`, or no JSON body. Always check the HTTP status before decoding success fields; preserve the sanitized response when contacting support.

A successful launch or worker-add response means the operation was accepted, not that GPUs are ready. Poll status and verify readiness. After a timeout on a write, read current state before retrying: do not assume the write failed. Only some routes accept an `Idempotency-Key`; see [Retries and idempotency](/api-reference/overview#retries-and-idempotency). Never log API keys or cluster credentials.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.