# RevidAPI API

Base URL: `https://ai.revidapi.com/v1`

## Authentication

All requests require a Bearer token:

```
Authorization: Bearer <YOUR_API_KEY>
```

Get your API key at [app.revidapi.com/docs](https://app.revidapi.com/docs) or [app.revidapi.com/developers/keys](https://app.revidapi.com/developers/keys).

### API Key Types

| Type | Credit Source | Created By |
|------|-------------|-----------|
| **Shared** | User account balance | User |
| **Budgeted** | Own quota (deducted from user on creation) | User |
| **Standalone** | Own pool (admin topup) | Admin |

## Quickstart

### Generate an image

```bash
curl -X POST https://ai.revidapi.com/v1/image/generate \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"prompt": "A futuristic city at sunset", "model": "nano-banana-pro"}'
```

Response:
```json
{
  "job_id": "abc-123",
  "status": "pending",
  "cost": 30,
  "balance_remaining": 970
}
```

### Poll for result

```bash
curl https://ai.revidapi.com/v1/jobs/abc-123 \
  -H "Authorization: Bearer YOUR_KEY"
```

Response (when completed):
```json
{
  "status": "completed",
  "result": "https://cdn.your-domain.com/.../image.jpg",
  "progress": 100
}
```

> **Note:** The CDN domain in `result` URLs is tenant-specific. For `app.revidapi.com` tenants it will be `cdn.revidapi.com`; for other white-label tenants it will differ.

## MCP Server

Connect AI agents (Claude Code, Cursor, Claude Desktop, VS Code, Windsurf...) directly to this API via the remote MCP server — no code required:

- Endpoint: `https://mcp.revidapi.com/mcp` (Streamable HTTP)
- Auth: the same API key, as header `Authorization: Bearer sk_live_...`
- Clients that can't set headers (claude.ai connectors, ChatGPT): embed the key in the URL — `https://mcp.revidapi.com/<sk_live_key>/mcp` (treat that URL as a secret)
- 13 tools: `generate_image`, `generate_video`, `generate_motion`, `generate_kol_video`, `get_job`, `wait_for_job`, `get_balance`, `get_limits`, `list_models`, `list_llm_models`, `upload_from_url`, `extract_media`, `llm_chat`

```bash
claude mcp add --transport http --header "Authorization: Bearer sk_live_..." revidapi https://mcp.revidapi.com/mcp
```

## Models & Pricing

All models available via the API. Credits are deducted per generation. When `server_id` is not specified, the system auto-selects the best available server.

> **⚠ Pricing in this doc is a snapshot — `GET /v1/models` is the source of truth.** The tables below are regenerated from the database but can lag behind a live price change by minutes-to-days. For any pricing-sensitive logic (cost estimation, budget checks, billing displays) call `GET /v1/models` at runtime and read the `pricing[]` array on each model. Each row carries `{server, key, credits, resolution, duration, audio, speed}` — pick the row matching your generation params. `credits_min` / `credits_max` are exposed for quick range displays, and `params` per model documents every POST body field the generate endpoint accepts.

> **API Change (2026-03-21):** `GET /models` returns a `"servers"` field (list of available server IDs) instead of `"provider"`. Use `servers` for server selection.

<!-- AUTO-GENERATED:MODELS-START -->
> Auto-generated from `model_server_config` DB. Run `python scripts/generate_api_docs.py` to regenerate. Do NOT edit between the AUTO-GENERATED markers — hand-written notes live below the END marker. **For programmatic use, query `GET /v1/models` instead of parsing this table — the API is the live source of truth.**

### Image Models

| Model | Display Name | Servers | Resolution | Speed | Credits |
|-------|-------------|---------|-----------|-------|---------|
| `flux-2-pro` | Flux 2 Pro | fast, vip1 | 1k, 2k | fast, slow | 10–30 |
| `grok-image` | Grok Image | vip1 | default | fast | 20 |
| `image-4.0` | Imagen 4.0 | fast | default | fast | 4 |
| `image-gpt` | Chat GPT Image | vip1 | default | fast, slow | 8–40 |
| `image-gpt-2` | Chat GPT Image 2 | vip1 | 1k, 2k (landscape/portrait) | fast | varies by quality (low/medium/high) |
| `imagen-4` | Imagen 4 | fast | default | fast | 20 |
| `imagen-4-fast` | Imagen 4 Fast | fast | default | fast | 20 |
| `imagen-4-ultra` | Imagen 4 Ultra | fast | default | fast | 30 |
| `kling-o1-image` | Kling O1 Image | vip1 | 1k, 2k | fast, slow | 12–35 |
| `nano-banana` | Nano Banana | fast, vip1 | default | fast, slow | 1–20 |
| `nano-banana-2` | Nano Banana 2 | fast, vip1 | 1k, 2k, 4k | fast | 20–40 |
| `nano-banana-pro` | Nano Banana PRO | fast, vip1 | 1k, 2k, 4k | fast, slow | 12–70 |
| `nano-banana-pro-cheap` | Nano Banana PRO Cheap | fast | default | fast | 10 |
| `seedream-4.5` | Seedream 4.5 | fast, vip1, vip2 | 2k, 4k (vip2: 2k only) | fast, slow | 12–35 |
| `seedream-5-pro` | Seedream 5 Pro | vip1 | default | fast | 38 |

### Video Models

| Model | Display Name | Servers | Resolution | Duration | Aspect Ratio | Audio | T2V | Credits |
|-------|-------------|---------|-----------|----------|-------------|-------|-----|---------|
| `kling-2.5-turbo` | Kling 2.5 Turbo | fast, vip1, vip2 | 1080p, 720p | 5s, 10s | — | No | Yes | 10–300 |
| `kling-2.6` | Kling 2.6 | fast, vip1, vip2 | 1080p, 720p | 5s, 10s | 16:9, 9:16, 1:1 | Yes (quality-dependent) | Yes | 15–640 |
| `kling-3.0-video` | Kling 3.0 Video | fast, vip1 | 1080p, 720p | 3s, 5s, 10s, 15s | 16:9, 9:16, 1:1 | Yes | Yes | 15–720 |
| `kling-o1-video` | Kling O1 Video | vip2 | 1080p, 720p | 5s, 10s | 16:9, 9:16, 1:1 | No | No | 60–600 |
| `seedance-2.0-fast` | Seedance 2.0 Fast | fast, vip2 | 480p, 720p (vip2: 720p only) | 5s, 8s, 10s, 15s (vip2: 5s, 10s) | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9 | Yes (not on vip2) | Yes | 120–650 · vip2: 200/350 |
| `seedance-2.0` | Seedance 2.0 | vip1 | 480p, 720p | 5s, 8s, 10s, 15s | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9 | Yes | Yes | varies |
| `seedance-2.5` | Seedance 2.5 | vip1, vip2, vip3 | 480p, 720p | any 4–30s | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9 | Yes (not on vip1) | Yes | per second × duration |
| `veo3.1-low` | Veo 3.1 LOW | fast | — | 8s | 16:9, 9:16 | No | Yes | 15 |
| `veo3.1-fast` | Veo 3.1 FAST | fast | — | 8s | 16:9, 9:16 | No | Yes | 10 |
| `veo3.1-high` | Veo 3.1 HIGH | fast | — | 8s | 16:9, 9:16 | No | Yes | 20 |
| `grok-i2v` | Grok Video | default | 480p, 720p | 6s, 10s | 9:16, 16:9, 1:1 | No | Yes | 30–70 |

### Motion Control Models

| Model | Display Name | Servers | Resolution | Credits |
|-------|-------------|---------|-----------|---------|
| `motion-control-2.6` | Motion Control 2.6 | vip2 | 1080p, 720p | 60–90 |
| `motion-control-3.0` | Motion Control 3.0 | vip2 | 1080p, 720p | 12–120 |

### KOL AI Models

| Model | Display Name | Servers | Pricing | Credits |
|-------|-------------|---------|---------|---------|
| `kling-avatar` | Kling Avatars 2.0 | vip1 | per-second | 5–10 |
| `omnihuman-1.5` | OmniHuman 1.5 | — | per-second | 3–5 |

Pass `model` to `POST /kol-ai/generate` to pick the engine (default `kling-avatar`).

### Server Tiers

| Server | Description |
|--------|-------------|
| `vip1` | Premium — fastest, highest priority |
| `vip2` | Standard — reliable, moderate speed |
| `fast` | Economy — lower cost, may be slightly slower |
<!-- AUTO-GENERATED:MODELS-END -->

### Model Notes

> **image-gpt-2** supports a `quality` param (`low`/`medium`/`high`) that controls both output resolution and credit cost. Available on VIP1 only. Cost key format: `{quality}-fast`.

> **grok-image** is available on the VIP1 tier only.

> **Seedance 2.0** is multi-modal: each job accepts up to **5 image refs + 1 video ref + 1 audio ref**, plus an optional `audio` flag to have the model auto-generate audio for the output video. Image + video refs pass through an IP / NSFW eligibility check before dispatch; audio refs skip it. Public API endpoint: `POST /v1/seedance/generate` (separate from the generic `/v1/video/generate` because of the per-ref upload + check pipeline). Cost key format: `{resolution}-{duration}-fast` or `{resolution}-{duration}-standard`.

> **Seedance 2.5** uses the same `POST /v1/seedance/generate` endpoint but bills **per second**: cost key `{resolution}-per-s` (or `{resolution}-audio-per-s` on a tier with the audio toggle) × the billable seconds. Duration is any integer **4–30 s** and an out-of-range value is rejected (`400 invalid_duration`) instead of clamped. Up to **10 image refs**, and image refs are optional — prompt-only text-to-video works. On **vip1** the `audio` flag is forced off (that tier has no generated-audio toggle). On **vip1 and vip3** a **video ref adds its own length to the bill** (output seconds + input-video seconds at the same rate, input capped at 15 s), so the server measures the input video before charging; vip2 does not. All three tiers are served; which ones are live is an admin setting, so read `GET /v1/models` for the current list and prices. Details: [endpoints/seedance.md](endpoints/seedance.md#seedance-25).

> **kling-2.6 audio** is only available for certain quality/resolution settings. The `audio` flag is silently dropped when the quality does not support it (enforced server-side).

> **Kling 3.0 Video** supports both T2V (no image) and I2V (`img_url` optional). When no image is provided, `inputs=[]` is sent through. Accepts `aspect_ratio` param (`16:9`, `9:16`, `1:1`). Duration strings with "s" suffix (e.g. `"5s"`) are accepted and normalized to integers.

> **Grok Video** supports both T2V (prompt only) and I2V (prompt + 1 image). `speed="standard"` only. Generation blocks 20–60s (SSE stream). Cost keys: `{res}-{dur}-standard` (30/45/50/70 credits).

> **Veo 3.1 Omni** (`veo3.1-omni`, `POST /v1/video/generate`) supports 4 modes: `t2v` (text→video); `i2v` frames (`img_url`/`image_urls`, 1 start [+1 end]); `r2v` ingredients (`image_urls` ≤7, send `veo_mode=ingredients`); and **edit** — pass a source `video_url` (public `.mp4`/`.mov`/`.webm`) or `input_video` file (+ ≤5 `image_urls` refs) to remix an existing video (Google `abra_edit`). Optional `video_duration` only aligns the edit frame range — it does **not** affect price (billing is by `duration`). Durations 4/6/8/10s.

> **Kling 3.0 Omni** (`kling-3.0-omni`, `POST /v1/video/generate`) has **no text-only mode** — every job needs media. Two modes, picked by what you send: **A) image→video** — `img_url` or `image_urls` (≤7); **B) video transformation** — a source `video_url` (public `.mp4`/`.mov`/`.webm`, also accepted as `video_urls` / `input_videos` / an `input_video` file) plus ≤4 `image_urls`. Over the caps ⇒ `400 invalid_input` (refs are never silently dropped). More than 1 video ⇒ `400 too_many_videos`. `audio: true` means Native Audio in mode A and "keep the source video's sound" in mode B. Duration is free-form 3–15s and billing is **per second** (`{resolution}-[audio-]per-s` × duration), so a 15s job costs 3× a 5s one.

Video input is accepted **only** by those two omni models — every other video model returns `400 video_not_supported` before any billing happens.

### TTS Engines (`POST /tts/generate`)

Billed per **100 characters** of input text: `ceil(len(text) / 100) × rate`. `GET /v1/tts/engines` returns the live rate (`cost_per_100_char`, `0` = free) plus availability.

| Engine | Tier | Voices | Notes |
|--------|------|--------|-------|
| `edge` | free | Microsoft Edge curated (vi/en/ja/…) | Default. Max 5000 chars. Supports `rate` / `volume` / `pitch`. Returns audio in the generate response. |
| `capcut` | free | CapCut/TikTok curated | Max 300 chars (upstream hard cap). Returns audio in the generate response. |
| `resona` | premium | Resona public + cloned | Max 10000 chars. Multi-speaker: `voice_ids[]` map to `Speaker 1:` / `Speaker 2:` labels in `text`. Async — poll `GET /tts/jobs/{job_id}`. |

TTS jobs are **not** polled by the background monitor: `GET /v1/tts/jobs/{job_id}` is what advances a Resona job, and TTS never uses `GET /v1/jobs/{job_id}`. No concurrency slot free ⇒ `429` (TTS is never queued).

### Upscale Models

| Model | Endpoint | Server | Pricing | Notes |
|-------|----------|--------|---------|-------|
| `topaz-image-upscale` | `POST /upscale/image` | `vip1` | per image, keyed by scale (`2x` / `4x` / `6x` / `8x`) | No prompt. Source via `img_url`. |
| `topaz-upscale` | `POST /upscale/video` | `vip3` | per second of the SOURCE video (`4k-per-s` × round(seconds)) | Fixed 4K output. Source ≤ 40s. Duration is probed server-side (ffprobe) — a client-sent `duration` is ignored. |

Both return a `job_id` polled through the normal `GET /v1/jobs/{job_id}`.

### LLM Chat Models (`POST /chat/completions`)

OpenAI-compatible text chat, billed by token. Model list + per-token pricing: `GET /v1/chat/models` (source of truth — model slugs and prices change without a docs release).

Cost = `max(min_charge, ceil(input_tokens/1M × price_in + output_tokens/1M × price_out))`. Insufficient balance for `input + min_charge` ⇒ `402` **before** the upstream model is called.

### Resolving cost & params via `GET /v1/models`

Each model carries everything a tenant needs to call it: priced configurations + accepted POST body fields + supported generation modes.

```bash
curl https://ai.revidapi.com/v1/models -H "Authorization: Bearer YOUR_KEY"
```

```json
{
  "models": [
    {
      "model": "kling-2.6",
      "name": "Kling 2.6",
      "type": "video",
      "modes": ["t2v", "i2v"],
      "servers": ["fast", "vip1", "vip2"],
      "credits_min": 15,
      "credits_max": 640,
      "pricing": [
        { "server": "fast", "key": "720p-5s-fast",        "credits": 15, "resolution": "720p", "duration": "5s" },
        { "server": "fast", "key": "720p-5s-audio-fast",  "credits": 25, "resolution": "720p", "duration": "5s", "audio": true },
        { "server": "vip1", "key": "1080p-10s-slow",      "credits": 320, "resolution": "1080p", "duration": "10s", "speed": "slow" }
      ],
      "params": {
        "prompt":         "string, required",
        "img_url":        "url, optional (set → I2V; omit → T2V)",
        "resolution":     "720p | 1080p",
        "duration":       "5 | 10 (seconds; accepts '5' / '5s')",
        "aspect_ratio":   "16:9 | 9:16 | 1:1 (default 16:9)",
        "audio":          "boolean (default false; silently dropped on unsupported combos)",
        "speed":          "fast | slow (default fast)",
        "server_id":      "fast | vip1 | vip2 (omit for auto-select)"
      },
      "notes": "Audio chỉ valid trên một số combo resolution/quality — server bỏ flag silently nếu sai combo."
    }
  ]
}
```

**Selection rule**: pick the `pricing[]` row whose `key` matches your params (`{resolution}-{duration}[-audio]-{speed}`). That row's `credits` is the cost. Omit `server_id` at submit time to let the backend auto-select the cheapest available server — display `credits_min` to the user in that case.

**Param contract**: `params` lists every POST body field the corresponding generate endpoint reads. Tenant just needs to send a JSON body using those field names. Values shown after `|` are the enum/format. Unknown fields are silently ignored by the backend.

**Backward-compat**: `pricing[].config_key` is kept as an alias of `pricing[].key` for one release window. New code should use `key`.

A flat cross-model query is also available: `GET /v1/models/pricing?model={id}&server_id={tier}` (same row shape, filterable).

## Workflows

### Text-to-Image (T2I)

1. `POST /image/generate` with `prompt` + `model` -> get `job_id`
2. `GET /jobs/{job_id}` -> poll until `status: "completed"` -> get `result` URL

### Image-to-Image (I2I)

1. `POST /image/generate` with `prompt` + `model` + `input_image` (file) or `img_url` -> get `job_id`
2. `GET /jobs/{job_id}` -> poll until completed

### Text-to-Video (T2V)

1. `POST /video/generate` with `prompt` + `model` + `duration` -> get `job_id`
2. `GET /jobs/{job_id}` -> poll until completed (~30-120s)

### Image-to-Video (I2V) — All models

1. `POST /files/upload/image` with `file` -> get `url`
2. `POST /video/generate` with `prompt` + `model` + `img_url` (from step 1) + `duration` -> get `job_id`
3. `GET /jobs/{job_id}` -> poll until completed

Works with all video models (Kling, Veo, etc.) — backend handles provider-specific re-upload automatically.

> **Note:** Generate endpoints return `status: "pending"` immediately. The job is dispatched in the background. Poll `/jobs/{job_id}` to track progress: `pending` → `processing` → `completed` or `failed`.

### Motion Control

1. `POST /files/upload/image` with character image -> get `url` (character_image_url)
2. `POST /files/upload/video` with motion video -> get `url` (motion_video_url)
3. `POST /motion/generate` with `character_image_url` + `motion_video_url` + `mode` -> get `job_id`
4. `GET /jobs/{job_id}` -> poll until completed

### KOL AI (Avatar Video)

1. `POST /files/upload/audio` with audio file -> returns immediately with `upload_id` + `status: "processing"`
   (add `engine=omnihuman` to skip the Higgsfield round-trip for `omnihuman-1.5` — returns `ready` with `audio_url` + `duration`, no `audio_id`)
2. `GET /files/upload/{upload_id}/status` -> poll until `status: "completed"` -> get `audio_id`, `duration`, `costs`
3. `POST /files/upload/image` with character image -> get `url` (image_url)
4. `POST /kol-ai/generate` with `model` + `audio_url` + `image_url` (+ `audio_id` for `kling-avatar`) + `quality` -> get `job_id`
5. `GET /jobs/{job_id}` -> poll until completed

### Presigned Upload (recommended for large files)

1. `POST /files/upload/presign` with `{"filename": "video.mp4"}` -> get `upload_url` + `upload_id`
2. `PUT {upload_url}` with file body (direct to CDN, no backend proxy)
3. `POST /files/upload/confirm` with `{"upload_id": "up_..."}` -> get `url` with `status: "ready"`
4. `POST /video/generate` with `img_url` or `video_url` from step 3

Faster than standard upload for large files. Avoids timeout. Image & video only (audio uses standard upload).

### Upload from External URL

```bash
curl -X POST https://ai.revidapi.com/v1/files/upload-url \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://example.com/video.mp4", "type": "video"}'
```

Returns `upload_id` with `status: "processing"`. Poll `GET /files/upload/{upload_id}/status` until completed to get the R2 `url`.

### TTS (Text-to-Speech)

Edge / CapCut — one call, audio comes back in the response:

```bash
curl -X POST https://ai.revidapi.com/v1/tts/generate \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"text": "Xin chào, đây là giọng đọc thử.", "engine": "edge", "voice": "vi-VN-HoaiMyNeural"}'
```

```json
{
  "job_id": "b1f2...",
  "status": "completed",
  "engine": "edge",
  "audio_url": "https://cdn.your-domain.com/.../speech.mp3",
  "characters": 31,
  "credits_cost": 0,
  "credits_remaining": 1500
}
```

Resona (multi-speaker) — async:

1. `GET /tts/voices?engine=resona` -> pick voice ids
2. `POST /tts/generate` with `engine=resona`, `voice_ids: ["voice_a", "voice_b"]` and `Speaker 1:` / `Speaker 2:` labels in `text` -> `job_id`
3. `GET /tts/jobs/{job_id}` -> poll until `status: "completed"` -> `audio_url` / `audio_urls[]`

### Upscale (Image)

1. `POST /files/upload/image` (or any public URL) -> image url
2. `POST /upscale/image` with `img_url` + `scale` (`2`/`4`/`6`/`8`) -> `job_id`
3. `GET /jobs/{job_id}` -> poll until completed

```bash
curl -X POST https://ai.revidapi.com/v1/upscale/image \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"img_url": "https://cdn.your-domain.com/inputs/photo.jpg", "scale": 4}'
```

### Upscale (Video 4K)

1. `POST /files/upload/video` (or any public URL) -> video url (≤ 40s)
2. `POST /upscale/video` with `video_url` -> `job_id` (response echoes `source_duration` + `billed_seconds`)
3. `GET /jobs/{job_id}` -> poll until completed

```bash
curl -X POST https://ai.revidapi.com/v1/upscale/video \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"video_url": "https://cdn.your-domain.com/inputs/clip.mp4"}'
```

### LLM Chat (OpenAI-compatible)

Point any OpenAI SDK at the base URL and use your `sk_live_` key:

```python
from openai import OpenAI

client = OpenAI(api_key="YOUR_KEY", base_url="https://ai.revidapi.com/v1")
res = client.chat.completions.create(
    model="gemini-3.1-flash-lite",
    messages=[{"role": "user", "content": "Viết 3 headline cho landing page."}],
)
print(res.choices[0].message.content)
```

Non-standard response extras: `x_credits_charged`, `x_remaining_balance`, `x_conversation_id`. Pass a previous `x_conversation_id` back as request `conversation_id` to continue that thread server-side (only the newest user message is sent upstream, so it bills less than re-sending history). `stream: true` emits OpenAI-shaped `chat.completion.chunk` events.

### Download / Extract (Free)

```bash
curl -X POST https://ai.revidapi.com/v1/download/extract \
  -H "Authorization: Bearer YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://tiktok.com/..."}'
```

No credits charged. Supported: TikTok, Douyin, YouTube, Facebook, Instagram, X/Twitter.

## Rate Limits

| Resource | Limit |
|----------|-------|
| Total concurrent jobs | 5 |
| Image concurrent | 3 |
| Video concurrent | 3 |
| Queue slots | 3 |

Limits vary by subscription plan. Check your limits: `GET /limits`.

## Content Format

All endpoints accept both `application/json` and `multipart/form-data`.
Use `multipart/form-data` when uploading files.

## Dashboard

View your usage stats and job history at `/key-dashboard` or via API:

- `GET /dashboard/me` — Key info, balance
- `GET /dashboard/jobs` — Job list (paginated, filterable)
- `GET /dashboard/stats` — Usage by model, by day
- `GET /dashboard/stats/export` — CSV export
- `GET /dashboard/credits` — Credit transaction log

### Tenant Dashboard (tenant owner keys only)

- `GET /dashboard/tenant/users` — Users registered under your tenant
- `GET /dashboard/tenant/subs` — Active subscribers (unlimited + credit plan)
- `GET /dashboard/tenant/revenue` — Revenue summary

See [Account & Dashboard docs](endpoints/account.md) for details.

## Docs

- [Errors](errors.md) — Error codes and troubleshooting
- Endpoints:
  - [Image Generation](endpoints/image.md)
  - [Video Generation](endpoints/video.md)
  - [Seedance 2.0 + 2.5](endpoints/seedance.md) — dedicated endpoint, multi-image I2V, 2.5 per-second billing
  - [TTS (Text-to-Speech)](endpoints/tts.md) — Edge / CapCut / Resona
  - [Upscale](endpoints/upscale.md) — image 2×–8×, video 4K
  - [LLM Chat](endpoints/chat.md) — OpenAI-compatible, billed by token
  - [Motion Control](endpoints/motion.md)
  - [KOL AI](endpoints/kol-ai.md)
  - [Jobs](endpoints/jobs.md)
  - [Files](endpoints/files.md)
  - [Account & Dashboard](endpoints/account.md)
  - [Download](endpoints/download.md)
