# SDKs

> There is no first-party SDK. The API answers in shapes other people's clients already speak.

Section: Guides. Canonical page: https://routehook.ai/docs/sdks

A wrapper around a JSON API this small would be more surface than it saves, so there is none. Instead the routes answer in the shapes the widely-used clients already send: an OpenAI client for chat, completions, embeddings and images, an Anthropic client for messages, and plain HTTP for the queue.

> **Warning: The base URL differs by client**
>
> An OpenAI client appends the route to whatever base URL you give it, so it needs https://api.routehook.ai/v1. An Anthropic client appends /v1/messages itself, so it needs https://api.routehook.ai. Pass it the version prefix as well and the request goes to /v1/v1/messages and 404s.

## OpenAI clients

**cURL**

```bash
curl https://api.routehook.ai/v1/chat/completions \
  -H "Authorization: Bearer $ROUTEHOOK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-5.4-mini",
    "messages": [
      { "role": "user", "content": "Hello" }
    ]
  }'
```

**JavaScript**

```javascript
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://api.routehook.ai/v1",
  apiKey: process.env.ROUTEHOOK_API_KEY,
});

const completion = await client.chat.completions.create({
  model: "openai/gpt-5.4-mini",
  messages: [{ role: "user", content: "Hello" }],
});

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

**Python**

```python
import os
from openai import OpenAI

client = OpenAI(
    base_url="https://api.routehook.ai/v1",
    api_key=os.environ["ROUTEHOOK_API_KEY"],
)

completion = client.chat.completions.create(
    model="openai/gpt-5.4-mini",
    messages=[{"role": "user", "content": "Hello"}],
)

print(completion.choices[0].message.content)
```

## What an OpenAI client can reach

chat.completions, completions, embeddings and images.generate all map onto routes that exist here. Anything else in that SDK (assistants, files, fine-tuning, the batch API) has no route behind it and will 404. The model field takes a slug from GET /v1/models, not an OpenAI model name.

## Anthropic clients

**JavaScript**

```javascript
import Anthropic from "@anthropic-ai/sdk";

const client = new Anthropic({
  baseURL: "https://api.routehook.ai",
  apiKey: process.env.ROUTEHOOK_API_KEY,
});

const message = await client.messages.create({
  model: "anthropic/claude-fable-5",
  max_tokens: 512,
  messages: [{ role: "user", content: "Hello" }],
});

console.log(message.content[0].text);
```

**Python**

```python
import os
from anthropic import Anthropic

client = Anthropic(
    base_url="https://api.routehook.ai",
    api_key=os.environ["ROUTEHOOK_API_KEY"],
)

message = client.messages.create(
    model="anthropic/claude-fable-5",
    max_tokens=512,
    messages=[{"role": "user", "content": "Hello"}],
)

print(message.content[0].text)
```

## The queue

The queue is four routes and no library: submit, poll, fetch, cancel. The submit call below is the whole of the integration a video model needs. See the queue page for the polling loop and the status vocabulary.

## Submitting a job

**cURL**

```bash
curl -X POST https://api.routehook.ai/v1/queue/google/veo-3.1 \
  -H "Authorization: Bearer $ROUTEHOOK_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "drone shot over a harbour at dawn",
    "duration": 5
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.routehook.ai/v1/queue/google/veo-3.1", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.ROUTEHOOK_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    prompt: "drone shot over a harbour at dawn",
    duration: 5,
  }),
});

const job = await res.json();
console.log(job.request_id, job.status);
```

**Python**

```python
import os, requests

res = requests.post(
    "https://api.routehook.ai/v1/queue/google/veo-3.1",
    headers={"Authorization": f"Bearer {os.environ['ROUTEHOOK_API_KEY']}"},
    json={
        "prompt": "drone shot over a harbour at dawn",
        "duration": 5,
    },
)

job = res.json()
print(job["request_id"], job["status"])
```

## Migrating an existing integration

- [From OpenRouter](/docs/migrate-openrouter): The same shapes, under the same field names.
- [From fal.ai](/docs/migrate-fal): The queue, in fal's path shapes, with one difference.
- [MCP](/docs/mcp): Reach the API from an agent runtime as tools.
