SDK Examples
The gateway is wire-compatible with the OpenAI API, so the official openai packages are the recommended SDKs. Point them at https://api.smartapihub.com/v1 with your sk-llm-… key. Nothing else to install.
Setup
bash
export LLM_API_KEY="sk-llm-…"
export LLM_GATEWAY="https://api.smartapihub.com"bash
npm install openaitypescript
import OpenAI from 'openai';
export const client = new OpenAI({
baseURL: 'https://api.smartapihub.com/v1',
apiKey: process.env.LLM_API_KEY,
defaultHeaders: { 'X-Client': 'my-app/1.0' }, // optional
});bash
pip install openaipython
import os
from openai import OpenAI
client = OpenAI(base_url="https://api.smartapihub.com/v1", api_key=os.environ["LLM_API_KEY"])Chat completion
bash
curl "$LLM_GATEWAY/v1/chat/completions" \
-H "Authorization: Bearer $LLM_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"openai/gpt-4o-mini","messages":[{"role":"user","content":"Explain SSE in one sentence."}]}'typescript
const { data: completion, response } = await client.chat.completions
.create({
model: 'openai/gpt-4o-mini',
messages: [{ role: 'user', content: 'Explain SSE in one sentence.' }],
})
.withResponse();
console.log(completion.choices[0].message.content);
console.log('provider', response.headers.get('x-llm-provider'));
console.log('cost µ$', completion.usage?.x_llm_cost_micro); // platform extensionpython
raw = client.chat.completions.with_raw_response.create(
model="openai/gpt-4o-mini",
messages=[{"role": "user", "content": "Explain SSE in one sentence."}],
)
completion = raw.parse()
print(completion.choices[0].message.content)
print("provider", raw.headers.get("x-llm-provider"))
print("cost µ$", completion.usage.model_extra.get("x_llm_cost_micro"))Streaming with the SDK
typescript
const stream = await client.chat.completions.create({
model: 'openai/gpt-4o-mini',
stream: true,
messages: [{ role: 'user', content: 'Write a haiku about routing.' }],
});
for await (const chunk of stream) {
process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
if (chunk.usage) console.log('\ncost µ$', (chunk.usage as { x_llm_cost_micro?: number }).x_llm_cost_micro);
}python
stream = client.chat.completions.create(
model="openai/gpt-4o-mini",
stream=True,
messages=[{"role": "user", "content": "Write a haiku about routing."}],
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="", flush=True)
if chunk.usage: # final usage chunk, always sent
print("\ncost µ$", chunk.usage.model_extra.get("x_llm_cost_micro"))Raw HTTP streaming
Without an SDK, parse the SSE stream yourself. Skip : ping comment lines, stop on [DONE], and check each chunk for an error key.
typescript
const res = await fetch('https://api.smartapihub.com/v1/chat/completions', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.LLM_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ model: 'openai/gpt-4o-mini', stream: true, messages: [{ role: 'user', content: 'Hi' }] }),
});
if (!res.ok) throw new Error(JSON.stringify(await res.json()));
const reader = res.body!.getReader();
const dec = new TextDecoder();
let buf = '';
outer: for (;;) {
const { value, done } = await reader.read();
if (done) break;
buf += dec.decode(value, { stream: true });
let i: number;
while ((i = buf.indexOf('\n\n')) >= 0) {
const evt = buf.slice(0, i);
buf = buf.slice(i + 2);
for (const line of evt.split('\n')) {
if (!line.startsWith('data: ')) continue;
const payload = line.slice(6);
if (payload === '[DONE]') break outer;
const chunk = JSON.parse(payload);
if (chunk.error) throw new Error(`${chunk.error.code}: ${chunk.error.message}`);
process.stdout.write(chunk.choices?.[0]?.delta?.content ?? '');
}
}
}python
import json, os, requests
with requests.post(
"https://api.smartapihub.com/v1/chat/completions",
headers={"Authorization": f"Bearer {os.environ['LLM_API_KEY']}", "Content-Type": "application/json"},
json={"model": "openai/gpt-4o-mini", "stream": True, "messages": [{"role": "user", "content": "Hi"}]},
stream=True,
timeout=(10, 600),
) as res:
if res.status_code != 200:
raise RuntimeError(res.json()["error"])
for line in res.iter_lines(decode_unicode=True):
if not line or not line.startswith("data: "):
continue # blank separators and ": ping" comments
payload = line[6:]
if payload == "[DONE]":
break
chunk = json.loads(payload)
if "error" in chunk:
raise RuntimeError(f"{chunk['error']['code']}: {chunk['error']['message']}")
if chunk.get("usage"):
print("\ncost µ$", chunk["usage"].get("x_llm_cost_micro"))
for choice in chunk.get("choices", []):
print(choice["delta"].get("content") or "", end="", flush=True)Routing override with the SDK
Extra request fields are passed through by both SDKs:
typescript
await client.chat.completions.create({
model: 'meta/llama-3.1-70b-instruct',
messages,
// @ts-expect-error platform extension not in the OpenAI types
routing: { strategy: 'fastest', providers: ['groq'] },
});python
client.chat.completions.create(
model="meta/llama-3.1-70b-instruct",
messages=messages,
extra_body={"routing": {"strategy": "fastest", "providers": ["groq"]}},
)Images with an idempotency key
typescript
const img = await client.images.generate(
{ model: 'openai/dall-e-3', prompt: 'A lighthouse in a storm', size: '1024x1024', response_format: 'url' },
{ headers: { 'Idempotency-Key': orderId } },
);
console.log(img.data[0].url); // signed URL, expires in ~1 hpython
img = client.images.generate(
model="openai/dall-e-3", prompt="A lighthouse in a storm", size="1024x1024", response_format="url",
extra_headers={"Idempotency-Key": order_id},
)
print(img.data[0].url)Async video job (raw HTTP)
The OpenAI SDKs have no video-jobs client, so use plain HTTP:
typescript
const base = 'https://api.smartapihub.com/v1';
const headers = { Authorization: `Bearer ${process.env.LLM_API_KEY}`, 'Content-Type': 'application/json' };
const submit = await fetch(`${base}/video/generations`, {
method: 'POST',
headers: { ...headers, 'Idempotency-Key': crypto.randomUUID() },
body: JSON.stringify({ model: 'vendor/video-model', prompt: 'Ocean waves at dawn', duration_seconds: 5 }),
});
if (submit.status !== 202) throw new Error(JSON.stringify(await submit.json()));
const { id } = await submit.json();
let job;
for (let delay = 2000; ; delay = Math.min(delay * 1.5, 30000)) {
job = await (await fetch(`${base}/video/generations/${id}`, { headers })).json();
if (['succeeded', 'failed', 'canceled', 'expired'].includes(job.status)) break;
await new Promise((r) => setTimeout(r, delay));
}
if (job.status === 'succeeded') console.log(job.artifacts[0].url);
else console.error(job.status, job.error);python
import os, time, uuid, requests
base = "https://api.smartapihub.com/v1"
headers = {"Authorization": f"Bearer {os.environ['LLM_API_KEY']}"}
r = requests.post(f"{base}/video/generations",
headers={**headers, "Idempotency-Key": str(uuid.uuid4())},
json={"model": "vendor/video-model", "prompt": "Ocean waves at dawn", "duration_seconds": 5})
r.raise_for_status() # 202
job_id = r.json()["id"]
delay = 2
while True:
job = requests.get(f"{base}/video/generations/{job_id}", headers=headers).json()
if job["status"] in ("succeeded", "failed", "canceled", "expired"):
break
time.sleep(delay)
delay = min(delay * 1.5, 30)
print(job["artifacts"][0]["url"] if job["status"] == "succeeded" else job["error"])More
- Migrating from OpenAI — the three-line change.
- Errors — SDK error handling patterns.
- OpenAPI — generate a client for any other language from
openapi.yaml.