SDKs
Python
OpenAI-compatible client against Meridian. Base URL https://meridian.getnimbus.net/api/v1.
pip install openaiAuto router (recommended)
Pass model="auto" and Meridian picks the best model per request. Read the router docs for tags + priorities.
from openai import OpenAI
client = OpenAI(
api_key="nim_live_...",
base_url="https://meridian.getnimbus.net/api/v1",
)
# Let Meridian pick the best model per request.
# See /docs/router for tags + priorities.
r = client.chat.completions.create(
model="auto",
messages=[
{"role": "system", "content": "You are a senior engineer."},
{"role": "user", "content": "Refactor this Python class for clarity ..."},
],
)
print(r.choices[0].message.content)Basic chat
from openai import OpenAI
client = OpenAI(
api_key="nim_live_...",
base_url="https://meridian.getnimbus.net/api/v1",
)
r = client.chat.completions.create(
model="azure/gpt-5-mini",
messages=[{"role": "user", "content": "Hello"}],
)
print(r.choices[0].message.content)Streaming
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
with client.chat.completions.stream(
model="azure/gpt-5-mini",
messages=[{"role": "user", "content": "Stream a haiku about code."}],
) as stream:
for event in stream:
if event.type == "token":
print(event.token, end="", flush=True)
print()Embeddings
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
res = client.embeddings.create(
model="azure/text-embedding-3-large",
input=["Hello world", "Goodbye world"],
)
print(len(res.data), len(res.data[0].embedding))Audio · Speech to text
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
with open("speech.mp3", "rb") as f:
resp = client.audio.transcriptions.create(model="whisper-1", file=f)
print(resp.text)Audio · Text to speech
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
resp = client.audio.speech.create(model="tts-1", voice="alloy", input="Hello from Meridian")
resp.stream_to_file("out.mp3")Responses API
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
r = client.responses.create(
model="azure/gpt-5-mini",
input=[
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Write a tagline for a developer SaaS."},
],
modalities=["text"],
)
print(r.output_text)Rerank
# Cohere-compatible rerank shape via Meridian
import requests
headers = {"Authorization": "Bearer nim_live_...", "Content-Type": "application/json"}
body = {
"model": "nimbus/rerank-1",
"query": "best snack for hiking",
"documents": [
"Trail mix with nuts and dried fruit",
"Chocolate cake recipe",
"Electrolyte drink comparison",
],
"top_n": 2,
}
resp = requests.post("https://meridian.getnimbus.net/api/v1/rerank", headers=headers, json=body, timeout=30)
print(resp.json())Files
Upload, fetch, delete. GET/DELETE use a required id query parameter.
# Upload a file
import requests
headers = {"Authorization": "Bearer nim_live_..."}
with open("policy.pdf", "rb") as f:
r = requests.post(
"https://meridian.getnimbus.net/api/v1/files",
headers=headers,
files={"file": ("policy.pdf", f)},
data={"purpose": "assistants"},
timeout=60,
)
print(r.json())# Download a file by id
import requests
headers = {"Authorization": "Bearer nim_live_..."}
fid = "<file_id_or_url>"
r = requests.get(f"https://meridian.getnimbus.net/api/v1/files?id={fid}", headers=headers, timeout=60)
open("download.bin", "wb").write(r.content)# Delete a file by id
import requests
headers = {"Authorization": "Bearer nim_live_..."}
fid = "<file_id_or_url>"
r = requests.delete(f"https://meridian.getnimbus.net/api/v1/files?id={fid}", headers=headers, timeout=30)
print(r.json())Images
See the Images guide for full options. Basic example:
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
img = client.images.generate(
model="azure/gpt-image-1",
prompt="Violet and emerald near-black landing page hero, minimalist",
size="1024x1024",
n=1,
)
import base64
img_b64 = img.data[0].b64_json
open("image.png", "wb").write(base64.b64decode(img_b64))Multi-turn
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
msgs = [
{"role": "system", "content": "You are concise."},
{"role": "user", "content": "Summarize in 10 words: Python generators."},
]
first = client.chat.completions.create(model="azure/gpt-5-mini", messages=msgs)
msgs.append({"role": "assistant", "content": first.choices[0].message.content})
msgs.append({"role": "user", "content": "Now add an example."})
second = client.chat.completions.create(model="azure/gpt-5-mini", messages=msgs)
print(second.choices[0].message.content)Errors and retries
from openai import OpenAI
import time
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
def call_with_retry():
backoff = 0.5
for attempt in range(6):
try:
return client.chat.completions.create(
model="azure/gpt-5-mini",
messages=[{"role": "user", "content": "Hello"}],
)
except Exception as e:
msg = str(e)
if any(code in msg for code in ["429", "503"]):
time.sleep(backoff)
backoff = min(8.0, backoff * 2)
continue
if "401" in msg:
raise RuntimeError("Check API key format nim_live_... and balance")
raise
resp = call_with_retry()
print(resp.choices[0].message.content)Balance check
# raw HTTP balance check
import requests
headers = {"Authorization": "Bearer nim_live_..."}
print(requests.get("https://meridian.getnimbus.net/api/v1/balance", headers=headers, timeout=15).json())Track spend per request
Every response includes the Meridian-priced cost. Read it from the response body or from the X-Meridian-* headers.
# Every chat / embedding response carries Meridian billing fields.
# Two equivalent ways to read them.
from openai import OpenAI
client = OpenAI(api_key="nim_live_...", base_url="https://meridian.getnimbus.net/api/v1")
r = client.chat.completions.create(
model="azure/gpt-5-mini",
messages=[{"role": "user", "content": "Hello"}],
)
# (1) Inline body fields (additive to OpenAI usage block).
raw = r.model_dump()
usage = raw["usage"]
print("user_tokens spent :", usage["user_tokens"])
print("balance after request :", usage["balance_after_user_tokens"])
print("provider tokens :", usage["prompt_tokens"], usage["completion_tokens"])
# (2) Custom response headers (use when you do not want to deserialize the body).
with client.with_raw_response.chat.completions.create(
model="azure/gpt-5-mini",
messages=[{"role": "user", "content": "Hello"}],
) as raw_resp:
print("X-Meridian-Tokens-Used :", raw_resp.headers.get("x-meridian-tokens-used"))
print("X-Meridian-Balance-After :", raw_resp.headers.get("x-meridian-balance-after"))Supported models
Pass any of these as model. Live source of truth: GET /api/v1/models.
Chat / completion:
azure/gpt-5.1azure/gpt-5-codexazure/gpt-4.1azure/gpt-5-miniazure/DeepSeek-V4-Proazure/DeepSeek-V4-Flashazure/grok-4-20-reasoningazure/Llama-4-Maverickazure/Mistral-Large-3azure/Cohere-command-aazure/Kimi-K2-6gpt-oss-120bEmbeddings:
azure/text-embedding-3-smallazure/text-embedding-3-large