# 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.tramsangtao.com`; for other white-label tenants it will differ.

## 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 | 2k, 4k | fast, slow | 15–70 |

### 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 | vip1 | 480p, 720p | 5s, 8s, 10s, 15s | 16:9, 9:16, 4:3, 3:4, 1:1, 21:9 | Yes | Yes | varies |
| `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 |
| `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 |

### 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`.

> **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).

### 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"`
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 `audio_id` + `image_url` + `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`.

### 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](endpoints/seedance.md) — dedicated endpoint, multi-image I2V
  - [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)
