---
sidebar_position: 8
title: API
description: The Lium platform REST API — live OpenAPI 3.1 schema, the single source of truth for every endpoint, payload and response.
---

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

# API

The Lium platform API publishes a live [OpenAPI 3.1](https://spec.openapis.org/oas/v3.1.0) schema. Point any code-generator, agent runtime, or HTTP client at it to discover every endpoint, payload, and response.

| Resource | URL |
|----------|-----|
| Raw JSON spec | [`https://lium.io/api/openapi.json`](https://lium.io/api/openapi.json) |
| Swagger UI | [`https://lium.io/documents`](https://lium.io/documents) |

The schema is generated directly from the FastAPI app at request time, so it always matches the live deployment.

## Fetch the spec

```bash
curl -sSL https://lium.io/api/openapi.json -o lium-openapi.json
```

```python
import httpx

spec = httpx.get("https://lium.io/api/openapi.json").json()
print(spec["info"]["title"], spec["info"]["version"])
```

## Use it from an AI agent

### Ground Claude with the spec

Pass the spec to Claude as cached context, then let the model reason about which endpoint to call. The `cache_control` block keeps you from re-billing input tokens on every request — the spec is large but stable.

```python
import json, httpx, anthropic

spec_text = httpx.get("https://lium.io/api/openapi.json").text
client = anthropic.Anthropic()

resp = client.messages.create(
    model="claude-sonnet-4-5",
    max_tokens=1024,
    system=[
        {"type": "text", "text": "You manage Lium GPU pods. Use the OpenAPI spec to choose the right endpoint."},
        {"type": "text", "text": f"<openapi>\n{spec_text}\n</openapi>", "cache_control": {"type": "ephemeral"}},
    ],
    messages=[{"role": "user", "content": "List my running pods."}],
)
print(resp.content[0].text)
```

For real tool calling (model invokes endpoints directly), walk `spec["paths"]` and emit one Anthropic [tool definition](https://docs.anthropic.com/en/docs/build-with-claude/tool-use) per operation — `name = operationId`, `input_schema = requestBody.content["application/json"].schema`.

### MCP-aware agents

If your agent already speaks [MCP](./mcp), point it at the docs MCP endpoint for prose questions and at this OpenAPI URL for direct API calls. Both are stable and require no extra configuration.

### Code generation

Generate a typed client in any language with the standard OpenAPI tooling:

```bash
# TypeScript / fetch
npx openapi-typescript https://lium.io/api/openapi.json -o lium.d.ts

# Python (httpx)
pip install openapi-python-client
openapi-python-client generate --url https://lium.io/api/openapi.json
```

## Authentication

Authenticated endpoints accept your API key in the **`X-API-Key`** request header. Get a key from **Access → API Keys** ([lium.io/ssh-keys](https://lium.io/ssh-keys), then the **API Keys** tab). See the [Developer Quickstart](./quickstart) for a complete first-call walkthrough and [API Authentication](./authentication) for the full reference: key sources and precedence, how to verify a key, and the error envelope.

```bash
export LIUM_API_KEY=your_api_key_here
curl https://lium.io/api/pods -H "X-API-Key: $LIUM_API_KEY"
```

The spec's `components.securitySchemes` declares `JwtAccessBearer` (`type: http`, `scheme: bearer`) — the session token the lium.io web app uses — and marks account-bound operations with it. API-key requests go in `X-API-Key` regardless of that marker; the two are accepted side by side. Check the document you generate from: if `securitySchemes` lists only `JwtAccessBearer`, add the `X-API-Key` header to the generated client by hand; if it also lists an `apiKey` scheme (`in: header`, `name: X-API-Key`), the generated security handler sends the key for you. Either way, the spec as served today does not tell public operations (`GET /executors`, `GET /templates`, which answer without a key) apart from account-bound ones; lium-platform#214 (not released) marks them as optionally authenticated.

Missing or unknown keys are answered with `401` and the platform's standard error envelope:

```json
{"success": false, "error": "HTTP error", "message": "API key not found", "status_code": 401, "error_id": null, "timestamp": "…", "api_context": null}
```

## Related

- [API Authentication](./authentication) — `X-API-Key`, key sources and precedence, verification, error envelope
- [Developer Quickstart](./quickstart) — first authenticated request in 5 minutes
- [SDK](./sdk) — typed Python client built on top of the same API
- [MCP endpoint](./mcp) — search and read the docs over JSON-RPC
- [llms.txt](./llms-txt) — bulk markdown bundle for LLM context
