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

# Gateway API

> Unified REST API for AI generation at api.varg.ai

The varg Gateway provides a single REST API for AI generation across multiple providers (Fal, ElevenLabs, Higgsfield, Replicate, PiAPI). One API key, server-side caching, and stable output URLs at `s3.varg.ai`.

## Base URL

```
https://api.varg.ai/v1
```

## Authentication

All requests require a varg API key:

```bash theme={null}
Authorization: Bearer varg_xxx
```

Get your API key at [app.varg.ai](https://app.varg.ai) or run `bunx vargai login`. See [Authentication](/authentication) for details.

### Bring Your Own Key (BYOK)

You can also pass your own provider keys to bypass varg billing. See the [BYOK guide](/byok) for a full tutorial.

```bash theme={null}
X-Provider-Key-Fal: fal_xxx
X-Provider-Key-ElevenLabs: el_xxx
```

## Quick Start

Generate a video and poll for the result:

```bash theme={null}
# Create job
curl -X POST https://api.varg.ai/v1/video \
  -H "Authorization: Bearer varg_xxx" \
  -H "Content-Type: application/json" \
  -d '{"model": "kling-v3", "prompt": "cat jumping over a fence"}'

# Response
# {"job_id": "job_a1b2c3d4", "status": "queued", "model": "fal:kling-v2.5", "created_at": "2026-02-13T10:00:00Z"}

# Poll until complete
curl https://api.varg.ai/v1/jobs/job_a1b2c3d4 \
  -H "Authorization: Bearer varg_xxx"

# Response when done
# {"job_id": "job_a1b2c3d4", "status": "completed", "output": {"url": "https://s3.varg.ai/o/job_a1b2c3d4.mp4", "media_type": "video/mp4"}, ...}
```

## TypeScript SDK

The `vargai` package provides a high-level provider for AI SDK integration:

```bash theme={null}
bun add vargai
```

```typescript theme={null}
import { createVarg } from "vargai/ai";

const varg = createVarg({ apiKey: "varg_xxx" });

// Use with AI SDK
const { images } = await generateImage({
  model: varg.imageModel("nano-banana-pro"),
  prompt: "sunset over mountains",
});
```

For low-level REST API access, the `@vargai/gateway` package exposes `VargClient`:

```bash theme={null}
bun add @vargai/gateway
```

```typescript theme={null}
import { VargClient } from "@vargai/gateway";

const client = new VargClient({ apiKey: "varg_xxx" });
```

### Generate video

```typescript theme={null}
// Create job and wait for completion
const job = await client.createVideo({
  model: "kling-v3",
  prompt: "cat jumping over a fence in slow motion",
  duration: 5,
  aspect_ratio: "16:9",
});

const result = await client.waitForJob(job.job_id);
console.log(result.output.url); // https://s3.varg.ai/o/job_xxx.mp4

// Image-to-video
const i2vJob = await client.createVideo({
  model: "kling-v3",
  prompt: "cat turns and looks at camera",
  files: [{ url: "https://example.com/cat.jpg" }],
});
```

### Generate image

```typescript theme={null}
const job = await client.createImage({
  model: "flux-schnell",
  prompt: "sunset over mountains, dramatic lighting",
  aspect_ratio: "16:9",
});

const result = await client.waitForJob(job.job_id);
console.log(result.output.url); // https://s3.varg.ai/o/job_xxx.jpg
```

### Generate speech

```typescript theme={null}
const job = await client.createSpeech({
  model: "eleven_v3",
  text: "Hello everyone! Welcome to my channel.",
  voice: "rachel", // rachel, domi, sarah, antoni, elli, josh, arnold, adam, sam
});

const result = await client.waitForJob(job.job_id);
console.log(result.output.url); // https://s3.varg.ai/o/job_xxx.mp3
```

### Upload a file

```typescript theme={null}
const file = await fs.readFile("./photo.jpg");

const uploaded = await client.uploadFile(file, "image/jpeg");

console.log(uploaded.url); // https://s3.varg.ai/u/user_xxx/abc123.jpg

// Use in generation
const job = await client.createVideo({
  model: "kling-v2.5",
  prompt: "photo comes to life",
  files: [{ url: uploaded.url }],
});
```

## Model resolution

Models can be specified as `provider:model` or just the model name. The gateway resolves the provider automatically.

```json theme={null}
{ "model": "fal:kling-v2.5" }  // explicit
{ "model": "kling-v2.5" }      // auto-resolved to fal
{ "model": "soul" }            // auto-resolved to higgsfield
```

| Model                                                      | Provider   |
| ---------------------------------------------------------- | ---------- |
| `kling-v3`, `kling-v2.6`, `kling-v2.5`                     | Fal        |
| `seedance-2-preview`, `seedance-2-fast-preview`            | PiAPI      |
| `wan-2.5`, `minimax`, `ltx`                                | Fal        |
| `nano-banana-pro`, `flux-schnell`, `flux-pro`              | Fal        |
| `sync-v2`, `sync-v2-pro`, `omnihuman`                      | Fal        |
| `recraft-v3`                                               | Fal        |
| `eleven_v3`, `eleven_multilingual_v2`, `eleven_flash_v2_5` | ElevenLabs |
| `music_v1`                                                 | ElevenLabs |
| `soul`                                                     | Higgsfield |
| `background-remover`                                       | Replicate  |
| `whisper`                                                  | Fal        |

## Caching

All generations are cached. Same parameters return instantly from cache at no cost.

The cache key is computed from: capability, model, prompt, duration/aspect ratio, and file content hashes (not URLs).

**Response headers:**

```http theme={null}
X-Cache: HIT
X-Cache-Key: sha256:abc123...
X-Cache-TTL: 2592000
```

**Bypass cache:**

```http theme={null}
Cache-Control: no-cache   # skip lookup, still store result
Cache-Control: no-store   # skip cache entirely
```

## Billing

**Cache hits are free.** Only cache misses with pooled keys are billed.

**BYOK users pay \$0** varg cost. You're billed directly by the provider.

Key resolution order:

1. `X-Provider-Key-*` header — BYOK, \$0
2. Dashboard-saved key — BYOK, \$0
3. Varg pooled key — metered billing

## Error codes

| Status | Error                      | Description                |
| ------ | -------------------------- | -------------------------- |
| 400    | `ValidationError`          | Invalid request body       |
| 401    | `AuthError`                | Missing or invalid API key |
| 402    | `InsufficientBalanceError` | Account balance too low    |
| 404    | `NotFoundError`            | Job or file not found      |
| 413    | —                          | File too large (max 50MB)  |
| 429    | `RateLimitError`           | Too many requests          |
| 500    | `InternalError`            | Server error               |
| 502    | `ProviderError`            | Upstream provider failed   |

Error responses follow this shape:

```json theme={null}
{
  "error": "ValidationError",
  "message": "prompt is required",
  "field": "prompt",
  "statusCode": 400
}
```

## Rate limits

| Plan       | Requests/minute | Concurrent jobs |
| ---------- | --------------- | --------------- |
| Free       | 10              | 2               |
| Pro        | 100             | 10              |
| Enterprise | Custom          | Custom          |
