Open app
Docs
API

HTTP API

Call OXYGEN over HTTPS from your own code or agent. Covers authentication, the response envelope, errors, approvals and rate limits.

The web app, the CLI and the MCP server all run on one HTTP contract under https://oxygenrep.com/api/cli/. Anything they can do, your backend, script or agent framework can do by calling the same endpoints with an API key.

The API is in beta. The endpoints are the ones the product itself calls, so they work and stay current. Paths and fields can still change between releases, and the CLI and MCP server absorb those changes for you. If your client can use MCP or the CLI, use them. Call HTTP directly when neither fits.

Find an endpoint

  • The API reference has a page for every endpoint an API key can call: its parameters, request examples in cURL, JavaScript, Python and other languages, the response, and a button to send a test request with your key. It is generated from the API on each release.
  • /openapi.json is the same reference as an OpenAPI 3.1 document, for Postman, client generators or an agent's tool loader.
  • x-oxygen-schema-source says how far to trust each request schema. contract means it is the exact schema the route validates against. inferred lists the fields the route reads, with types taken from the matching MCP tool where one exists.
  • Every endpoint names the MCP tool that wraps it (x-oxygen-mcp-tools), plus the CLI command (x-oxygen-cli-command) when one maps directly. The MCP reference and oxygen commands get "<command>" --json describe the inputs in more detail.

An agent that is unsure which primitive owns a goal should start with oxygen capabilities search "<goal>" --json (MCP: oxygen_capabilities_search), then call the endpoints behind the tools it returns.

Authenticate

Create an API key in Settings → CLI and MCP, or from the CLI:

oxygen api-keys create --name "backend" --json
oxygen api-keys create --name "reporting" --read-only --json

The token starts with oxy_live_ and is shown once. A key belongs to one workspace and acts with the role of the person who created it. A --read-only key can read but never change the workspace. Keep keys in your secret store, never in prompts or source code.

Send these headers:

HeaderRequiredValue
AuthorizationYesBearer <your key>
X-Oxygen-Client-VersionYes, with a keyA version at or above meta.minimum_cli_version. A missing or older value is refused with HTTP 426 cli_update_required.
Content-TypeWith a bodyapplication/json. A few upload endpoints take multipart/form-data, and the reference marks them.
X-Oxygen-OrganizationNoA key is already bound to its workspace. A different workspace here is refused with 403.

The minimum version rises over time. Every response carries the current value in meta.minimum_cli_version, and a 426 carries it in error.details.minimum_cli_version, so keep your header at or above it. The X-Oxygen-Client-Version parameter in /openapi.json shows the value in force when the site was built.

curl https://oxygenrep.com/api/cli/whoami \
  -H "Authorization: Bearer $OXYGEN_API_KEY" \
  -H "X-Oxygen-Client-Version: $OXYGEN_CLIENT_VERSION"

Response envelope

Every endpoint returns the same JSON envelope. A success:

{
  "ok": true,
  "data": { "...": "the endpoint's result" },
  "meta": { "command": "tables list", "version": "1.1025.0", "minimum_cli_version": "1.1011.469" }
}

A refusal or failure:

{
  "ok": false,
  "error": {
    "code": "rate_limit_exceeded",
    "message": "A sentence you can show a person.",
    "details": { "retry_after_seconds": 12 }
  },
  "meta": { "command": "tables query", "version": "1.1025.0", "minimum_cli_version": "1.1011.469" }
}

Check ok, then branch on error.code, never on message. Write responses carry effect_outcome (applied, partial, no_change, no_data, pending or failed) and a changed boolean. A 200 means the request was accepted, not necessarily that the workspace changed. They also carry a link to the result in the web app.

Errors and recovery

Code or statusWhat to do
unauthorized (401)The key is missing, invalid, expired or revoked.
cli_update_required (426)Raise X-Oxygen-Client-Version to error.details.minimum_cli_version.
invalid_request (400)Fix the input. The message names the field.
rate_limit_exceeded (429)Wait the seconds in Retry-After (also error.details.retry_after_seconds), then retry.
approval_required, max_credits_requiredFollow error.details.next_step. See approvals below.
insufficient_creditsTop up credits or change plan. Retrying will not help.
5xx with a retryable codeRetry with backoff. A write may already have taken effect, so read before you repeat it.

Approvals, previews and spend

Actions that spend credits or write to the outside world (sending, publishing, paid enrichment) are preview-first. Call without approval to get a preview, its price and a plan reference. Then repeat the call with the approval fields the preview names, usually approved: true, the returned plan, and a max_credits ceiling. Each endpoint's schema shows its exact fields; the reference marks these endpoints paid. The full rules are in approvals and caps.

Large reads

List and query endpoints return a bounded page plus a continuation field (nextCursor, next_cursor or next_offset). Pass it back with the same filters for the next page. A page that hit its size window says so with truncated: true. For bulk work, run a durable table run or workflow rather than looping over single-row calls.

Rate limits

Every call counts against a per-key and a per-workspace limit a minute, scaled by plan. The limits for each plan are in the pricing reference.

On this page