# API Reference

> Tarout REST API documentation

# API Reference

Tarout provides a REST API for programmatic access to all platform features. The API is built on tRPC with OpenAPI support.

## Base URL

```
https://tarout.sa/api
```

## Authentication

All API requests require authentication via an API key or session token.

### API Keys

Generate an API key in **AI Gateway → API keys** or **OCR Studio → API keys**.

```bash
curl https://tarout.sa/api/v1/applications \
  -H "Authorization: Bearer YOUR_API_KEY"
```

### Session Tokens

When using the CLI or browser, session tokens are managed automatically.

## Common Endpoints

### Applications

```bash
# List applications
GET /api/v1/applications

# Get application details
GET /api/v1/applications/:id

# Create application
POST /api/v1/applications

# Deploy application
POST /api/v1/applications/:id/deploy

# Delete application
DELETE /api/v1/applications/:id
```

### Databases

```bash
# List databases
GET /api/v1/databases

# Create database
POST /api/v1/databases

# Delete database
DELETE /api/v1/databases/:id
```

### Domains

```bash
# List domains
GET /api/v1/domains

# Add domain
POST /api/v1/domains

# Delete domain
DELETE /api/v1/domains/:id
```

## Response Format

All responses follow this format:

```json
{
  "result": {
    "data": { ... }
  }
}
```

## Error Handling

Errors return appropriate HTTP status codes:

| Code | Description |
|------|-------------|
| `400` | Bad request - invalid parameters |
| `401` | Unauthorized - missing or invalid authentication |
| `403` | Forbidden - insufficient permissions or suspended account |
| `404` | Not found - resource doesn't exist |
| `429` | Rate limited - too many requests |
| `500` | Internal server error |

## Rate Limits

API requests are rate-limited to prevent abuse. If you exceed the limit, you'll receive a `429` response with a `Retry-After` header.

## AI Gateway

The AI Gateway is an OpenAI-compatible API for AI models. Any OpenAI client
works with it once you change the base URL and the key:

```
https://tarout.sa/api/ai/v1
```

Usage is billed in SAR from your organization's prepaid balance: chat by the
token, OCR by the page. Failed requests are free.

### Endpoints

| Method | Path | What it does |
|--------|------|--------------|
| `POST` | `/chat/completions` | Chat with a model. See [Chat completions](https://tarout.sa/docs/api/chat). |
| `GET` | `/models` | List the models you can call right now. |
| `GET` | `/models/{id}` | Look up one model by ID or alias. |
| `POST` | `/ocr` | Read PDFs, scans and photos into text and tables. See [OCR](https://tarout.sa/docs/api/ocr). |

More AI services are being added to the gateway. Each one gets its own page in
the API Reference section when it opens, and `GET /models` lists its models
from that day.

### Regions

Every model runs in one region, named by the `region` field of its
`GET /models` entry:

| Region | Where processed |
|--------|-----------------|
| **Global** (`global`) | Processed outside Saudi Arabia. |
| **Local** (`local`) | Processed in Saudi Arabia. Your data never leaves the Kingdom. |

Every chat model on this page is Global. OCR offers both regions: see
[OCR](https://tarout.sa/docs/api/ocr).

### One key for every model

A gateway key (`sk_tarout_...`) is not tied to a model. The same key calls any
model in the catalog, and each request chooses one with the `model` field. A key
has a name, an optional monthly credit limit in SAR, and an optional expiry
date. Keys created before this change work with every model too; there is
nothing to migrate.

Create a key in the [dashboard](https://tarout.sa/dashboard/ai-models/keys), or
from the CLI (`--monthly-cap` is the monthly credit limit in SAR):

```sh
tarout ai keys create --name production --monthly-cap 50
```

### Call a model with the Tarout SDK

```sh
npm install @tarout/ai
```

```ts
import Tarout from "@tarout/ai";

// Reads TAROUT_API_KEY from the environment and defaults to the
// gateway base URL above.
const client = new Tarout();

const res = await client.chat.completions.create({
  model: "glm",
  messages: [{ role: "user", content: "Hello!" }],
});

console.log(res.choices[0]?.message.content);
```

To switch models, change the `model` string. The key and everything else stay
the same:

```ts
await client.chat.completions.create({
  model: "deepseek-v4-pro",
  messages: [{ role: "user", content: "Hello!" }],
});
```

### List available models

```bash
curl https://tarout.sa/api/ai/v1/models \
  -H "Authorization: Bearer $TAROUT_API_KEY"
```

The response lists every model you can call right now. Each entry carries its
`kind` (`chat` for every model on this page) and its `region` (`global` or
`local`). Any OpenAI-compatible client's `models.list()` calls the same
endpoint, and `tarout ai models` shows the catalog from the CLI.

To look up one model, use its ID or alias. An alias returns the model it points
at, and a model that is not live right now returns `404` with `error.code`
`model_not_found` (this is what `models.retrieve()` calls):

```bash
curl https://tarout.sa/api/ai/v1/models/glm \
  -H "Authorization: Bearer $TAROUT_API_KEY"
```

### Models

Set `model` to a model's stable alias or to its full ID. Both work.

**Global**: five open-weight flagships, one per lab. Processed outside Saudi
Arabia.

| Model | Alias | ID |
|-------|-------|----|
| GLM 5.3 | `glm` | `z-ai/glm-5.3` |
| DeepSeek V4 Pro 0813 | `deepseek-v4-pro` | `deepseek/deepseek-v4-pro-0813` |
| Kimi K3 | `kimi-k3` | `moonshotai/kimi-k3` |
| MiniMax M3 | `minimax-m3` | `minimax/minimax-m3` |
| Qwen 3.8 2.4T A95B | `qwen3` | `qwen/qwen3.8-2.4t-a95b` |

**Global, fast route**: smaller open-weight models on a route tuned for fast
inference. Processed outside Saudi Arabia. The `-fast` suffix marks them. They
can be temporarily unavailable, so check `GET /api/ai/v1/models` for what is
live now.

| Model | Alias | ID |
|-------|-------|----|
| GPT-OSS 120B | `gpt-oss-fast` | `groq/openai/gpt-oss-120b` |
| GPT-OSS 20B | `gpt-oss-20b-fast` | `groq/openai/gpt-oss-20b` |
| Qwen 3.8 27B | `qwen3.8-fast` | `groq/qwen/qwen3.8-27b` |
| Qwen 3.6 27B | `qwen3.6-fast` | `groq/qwen/qwen3.6-27b` |

The older fast-route alias names still work and point at the same models, so
existing code keeps running; `GET /models` lists them with `deprecated: true`.
Use the `-fast` aliases above in new code.

### Errors

Every error uses the OpenAI envelope
`{"error": {"message": "...", "type": "...", "code": "..."}}`. For gateway
errors `type` and `code` carry the same value, for example `PAYMENT_REQUIRED`
(the wallet cannot cover the request), `BUDGET_EXCEEDED` (the key's monthly
credit limit is reached) or `RATE_LIMIT_EXCEEDED`. A `429` also sends a
`Retry-After` header with the number of seconds to wait. A streaming request
that fails after the stream has started ends with one `data:` event carrying the
same `error` object, followed by `data: [DONE]`. When one request field is at
fault, `error.param` names it.

| Status | `code` | Meaning |
|--------|--------|---------|
| `400` | `VALIDATION_ERROR` | The body is invalid, or it has a field the endpoint does not take. |
| `400` | `UNSUPPORTED_PARAMETER` | The model does not take this field, for example `response_format` on a model without structured outputs. |
| `401` | `AUTHENTICATION_ERROR` | The key is missing or invalid. |
| `402` | `PAYMENT_REQUIRED` | The prepaid balance cannot cover the request. Top it up in the dashboard. |
| `402` | `BUDGET_EXCEEDED` | The key reached its monthly credit limit. |
| `403` | `KEY_SCOPE_FORBIDDEN` | The key does not have the scope this endpoint needs: AI Gateway for chat and models, OCR for OCR. Edit the key in **AI Gateway, API keys** or **OCR Studio, API keys**. |
| `404` | `MODEL_NOT_FOUND` | The model is unknown or was removed (see below). |
| `404` | `MODEL_UNAVAILABLE` | The model is in the catalog but cannot be called right now. |
| `429` | `RATE_LIMIT_EXCEEDED` | Too many requests. Wait the `Retry-After` seconds. |
| `502`, `503` | `PROVIDER_ERROR` | The model is temporarily unavailable. Retry shortly; a failed request is free. |

A request for a model that is unknown or has been removed from the catalog
returns HTTP `404` with `error.type` set to `MODEL_NOT_FOUND` and this message:

```text
Model <id> is not offered. Available models: <comma-separated ids>
```

Set `model` to one of the listed IDs, or pick one from `GET /api/ai/v1/models`.
Removed models are rejected. They are never redirected to a different model.
These were removed from the Global catalog:

```text
glm-flash            z-ai/glm-5.3-flash
deepseek-v4-flash    deepseek/deepseek-v4-flash-0731
kimi-code            moonshotai/kimi-k2.7-code
qwen-flash           qwen/qwen3.8-flash
nemotron             nvidia/nemotron-3-ultra-550b-a55b
```

## Learn More

- [Authentication](https://tarout.sa/docs/api/authentication) - Detailed auth guide.
- [Chat completions](https://tarout.sa/docs/api/chat) - Every chat field, streaming and examples.
- [OCR](https://tarout.sa/docs/api/ocr) - Read documents with Tarout OCR.
- [CLI](https://tarout.sa/docs/cli) - Use the CLI for common operations.

---

## Every Tarout agent guide

- [Start Here (Agents)](https://tarout.sa/docs/for-ai/start.md)
- [Overview](https://tarout.sa/docs/for-ai.md)
- [Deploying an app](https://tarout.sa/docs/for-ai/deploy.md)
- [Databases](https://tarout.sa/docs/for-ai/database.md)
- [Object storage](https://tarout.sa/docs/for-ai/storage.md)
- [Custom domains](https://tarout.sa/docs/for-ai/domains.md)
- [Plans and upgrades](https://tarout.sa/docs/for-ai/billing.md)
- [Troubleshooting](https://tarout.sa/docs/for-ai/troubleshoot.md)
- [Agent Onboarding](https://tarout.sa/docs/for-ai/onboarding.md)
- [CLI Reference](https://tarout.sa/docs/for-ai/cli-reference.md)
- [CLI JSON Schema](https://tarout.sa/docs/for-ai/cli-json-schema.md)

Whole corpus in one file: https://tarout.sa/llms-full.txt · index: https://tarout.sa/llms.txt
Any docs page is raw markdown at the same URL + `.md`. Short link to the entry point: https://tarout.sa/deploy.md
