# API keys

> Create a key under Settings → Developers, call Orbital's API from your own code, and see what each switch, limit and error means and how to revoke a key.

Source: https://orbitalaip.com/docs/workspace-and-account/api-keys

## What an API key is

An API key lets a script, a notebook or a service call Orbital without signing in.

A key belongs to one [workspace](https://orbitalaip.com/docs/glossary#workspace). It acts as you, the member who created it, so every request runs with your role. The switches you set on the key narrow that further.

A key made on **Developers** does not expire.

These keys are for calling Orbital. Keys for model providers such as OpenAI or Anthropic go under **AI Models**: see [AI models](https://orbitalaip.com/docs/workspace-and-account/ai-models).

## Who can manage keys

Only workspace owners and admins can create, see or revoke keys. Only they see **Developers**, in the account menu and in Settings. Anyone else who reaches the page sees **Admins only**: "API keys are workspace credentials. Ask a workspace admin to create or revoke them."

## Create a key

1. **Open Developers**
   
   Click your avatar at the bottom of the sidebar and choose **Developers**. Settings opens on that page, at [https://app.orbitalaip.com/settings/workspace/developers](https://app.orbitalaip.com/settings/workspace/developers).

2. **Click Create key**
   
   The **New API key** form opens: "A key calls the API as you, with only the access you give it here."

3. **Name the key**
   
   Under **Name**, name it after what will hold it, such as a script or a notebook. A name can be up to 120 characters.

4. **Set the switches**
   
   Under **What the key may do**, set **Read**, **Write** and **Run**. **Read** starts on; **Write** and **Run** start off.

5. **Click Create key**
   
   The key appears once, under **Your new key**.

6. **Copy the key and click Done**
   
   Click **Copy** and store the key somewhere safe. The page says "Copy it now": Orbital never shows the key again.

Every key starts with `orbk_`. Orbital keeps only a fingerprint of it, and the list shows just its last four characters.

> [!TIP] Keep keys out of shared code
> Anyone holding a key can use the API as you, within its switches, until you revoke it. Load it from an environment variable or a secrets manager, never from a file you share or commit.

You cannot rename a key or change its switches later.

## What each switch allows

| Switch | The form says | What it covers |
| --- | --- | --- |
| Read | See workflows, dashboards, watchlists, and results. | Every request that only reads, across workflows, automations, agents, agent tasks and channels, dashboards, watchlists, notes, alert history, notifications, prices, symbol search, and Backtesting's strategies, runs and trades. |
| Write | Create and edit those things. Billing, members, and other keys stay out of reach no matter what. | Creating, changing and deleting workflows, automations, agents, agent tasks and channels, dashboards, watchlists and notes. Also marking your notifications read, archiving or deleting them, and changing where each kind is sent. |
| Run | Start workflow and agent runs. Runs spend credits, so this is its own switch. | Starting a workflow run, a batch of workflow runs or an agent run. |

A key without **Read** cannot read anything, even what it may change.

Watchlists and notes answer only in a project where the Watchlists app is on, and Backtesting only where Backtesting is on.

> [!WARNING] Write can start paid work too
> **Run** covers the calls that start a workflow or agent run outright. A key with **Write** can still set off runs that spend [credits](https://orbitalaip.com/docs/glossary#credits). For example, it can message an agent or a channel, give an agent a task, or switch on an automation. Give **Write** only to code you trust with your credits.
> 
> **Write** also covers deleting for good. A key can move a workflow, agent, dashboard, watchlist or note to **Trash** and then erase it.

## What a key cannot do

These areas refuse keys, whatever the switches say:

- Chat and the Library.

- Billing, members, workspace settings and AI model settings.

- API keys themselves, so a key cannot create or revoke keys.

- Plugins, Trade, and installing apps or switching them on.

- Your profile and sign-in.

Some actions in the other areas stay with people signed in to the app. A key cannot:

- save a workflow version, make a version [main](https://orbitalaip.com/docs/glossary#main) or clone one;

- approve or deny what an agent asks for, or change an agent's permissions;

- run or cancel a backtest, or start a forward test.

Backtesting's own calls only read. A strategy is also a workflow, though, so a key with **Write** can change or delete it through the workflow calls.

To build and backtest strategies from outside the app, connect Claude instead. See [Connect Claude to Orbital](https://orbitalaip.com/docs/claude-and-chatgpt/connecting).

## Workspace and project

A key works only in the workspace it was created in, so you never send a workspace id. A request that names another workspace answers 404.

Most requests work in one [project](https://orbitalaip.com/docs/glossary#project) of that workspace. To choose it, send the project's id in the `x-project-id` header. The app does not show project ids. Each workflow and agent the API returns carries its `projectId`, so read it from a response such as `GET /api/workflows`. Without the header, the request uses the project Orbital would open for you: the one you used last.

Keys made on **Developers** are not tied to one project. Each one can reach every project you can open.

> [!NOTE] If you use more than one workspace
> While another workspace is the one you last opened in Orbital, a request without `x-project-id` answers 404. Open the key's workspace in Orbital again, or send the header.

## Call the API

The API lives at `https://api.orbitalaip.com/api`. Send the key in the `Authorization` header as a bearer token. Requests and responses are JSON.

```bash title="List workflows (needs Read)"
curl https://api.orbitalaip.com/api/workflows \
  -H "Authorization: Bearer $ORBITAL_API_KEY"
```

This returns the project's workflows, 50 at a time. Use the `limit` (up to 100) and `offset` query parameters to page through them.

```bash title="Start a workflow run (needs Run)"
curl -X POST https://api.orbitalaip.com/api/workflows/WORKFLOW_ID/run \
  -H "Authorization: Bearer $ORBITAL_API_KEY"
```

This works for a workflow that asks for no inputs when it runs. One that does refuses a request without them, with 400 or 412. `GET /api/workflows/WORKFLOW_ID/run-form` lists the fields it needs and the `contractHash` to send with them.

A workflow's id is the last part of its address in the editor, after `/workflows/`. A run started with a key runs the workflow's main version, or its canvas if it has none. A key cannot save a version. Once a workflow has a main version, a key's edits to its canvas do not reach the runs it starts. See [Runs and versions](https://orbitalaip.com/docs/workflows/runs-and-versions).

To start an agent run, send `POST /api/agents/AGENT_ID/run`, with any input as a JSON object in `input`. `GET /api/agents` lists the project's agents with their ids, leaving out archived agents and any still in their setup interview.

## Limits

| Limit | What it counts | Size |
| --- | --- | --- |
| Per key | Every request made with one key | 300 a minute |
| Per IP address | Every request to the API from one address, the app's own included | 600 a minute |
| Plan requests | Each workflow run and agent run, and each chat reply in the app, from one allowance for the whole workspace | Your plan's, shown on Billing |
| Active keys | Keys in the workspace that are not revoked | Your plan's, named in the error below |

Other API calls do not count toward your plan's requests, but the runs a key starts do. The **Billing** page shows your plan's numbers per minute and per day. Look under **What your plan allows**, in **Rate limits & model availability**. The daily count resets at midnight UTC. See [Credits and billing](https://orbitalaip.com/docs/workspace-and-account/credits-and-billing).

When the workspace holds as many active keys as its plan allows, creating another fails: "Your plan allows _n_ active API keys. Revoke one or upgrade to create more." With a cap of one, it says "1 active API key".

## Errors

| Status | Code | What it means | What to do |
| --- | --- | --- | --- |
| 401 | API_KEY_INVALID | "This API key is invalid, revoked, or expired." | Check that the header carries the whole key. If the key was revoked, create a new one. |
| 403 | API_KEY_NOT_ALLOWED or SESSION_REQUIRED (a few calls send another code or none) | Keys are refused here, or may only read here. | Do it in the app while signed in. |
| 403 | API_KEY_SCOPE_MISSING | The key lacks the switch this request needs. | Create a key with that switch on. |
| 404 | none | The item, project or workspace is outside what the key can reach, or the app is off in that project. | Check the id, the project, the workspace and the project's apps. |
| 429 | API_KEY_RATE_LIMITED | The key sent more than 300 requests in a minute. | Wait for the seconds in the Retry-After header, then retry. |
| 429 | none | More than 600 requests in a minute came from your address. | Slow down, then retry. |
| 429 | REQUEST_LIMIT_REACHED | The workspace used its plan's requests for the minute or the day. | Wait, or change plan. Adding credits does not lift it. |
| 402 | INSUFFICIENT_CREDITS_FOR_RUN | The workflow run would cost more credits than remain. | Add credits, then start it again. |

## Revoke a key

Revoke a key you no longer use, and revoke at once any key that may have leaked. Each key on **Developers** shows its name, **Active** or **Revoked**, its last four characters, its switches, **Last used** and **Created**.

1. **Click Revoke**
   
   It sits at the end of the key's row, on active keys only.

2. **Confirm**
   
   The dialog asks "Revoke _name_?" and warns: "Anything using this key stops working immediately." Click **Revoke**.

Orbital confirms: "Requests with this key stop immediately." From then on the key gets API_KEY_INVALID. It stays in the list as **Revoked**, and it cannot be switched back on.

To replace a key without a gap:

1. **Create the new key**
   
   Give it the switches your code needs.

2. **Move your code to it**
   
   Check that its requests succeed.

3. **Revoke the old key**
   
   

Keys can also end without a click. Deleting your account deletes the keys that act as you, and deleting a workspace deletes its keys. One Google sign-in case revokes them too: see the note in [Sign up and sign in](https://orbitalaip.com/docs/getting-started/sign-up). Changing your password leaves them working.

When the member a key acts as leaves the workspace, the key's requests answer 404, except prices and symbol search. **Developers** still shows it as **Active**, so revoke it.

## Claude connections are separate

Connecting Claude does not use an API key. When you approve on the **Connect to Orbital** page, Claude gets tokens of its own. They are bound to the workspace and project you chose.

Those tokens work only with the **Orbital AI** connector, and an API key does not work there. Connections are not listed on **Developers**, and revoking a key leaves them connected. To end one, remove the connector in Claude: see [Connect Claude to Orbital](https://orbitalaip.com/docs/claude-and-chatgpt/connecting).
