OpenAI SDK
UberLLM implémente l'API OpenAI Chat Completions. Tout code qui utilise le SDK officiel openai (ou un client compatible) fonctionne en configurant deux éléments :
base_url/baseURL→https://api.uberllm.dev/v1api_key/apiKey→ votre cléull_
Tout le reste — messages, tools, response_format, stream, max_tokens, temperature — est inchangé.
Python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.uberllm.dev/v1",
api_key=os.environ["UBERLLM_API_KEY"],
)
# Non-streaming
resp = client.chat.completions.create(
model="deepseek/deepseek-v4-flash",
messages=[{"role": "user", "content": "Explain rope embeddings briefly."}],
)
print(resp.choices[0].message.content)
print(resp.usage) # prompt_tokens / completion_tokens are returned per request
# Streaming
stream = client.chat.completions.create(
model="deepseek/deepseek-v4-flash",
messages=[{"role": "user", "content": "Count to five."}],
stream=True,
)
for chunk in stream:
print(chunk.choices[0].delta.content or "", end="", flush=True)
TypeScript / JavaScript
import OpenAI from "openai";
const client = new OpenAI({
baseURL: "https://api.uberllm.dev/v1",
apiKey: process.env.UBERLLM_API_KEY,
});
const resp = await client.chat.completions.create({
model: "deepseek/deepseek-v4-flash",
messages: [{ role: "user", content: "Explain rope embeddings briefly." }],
});
console.log(resp.choices[0].message.content);
Appel d'outil
L'appel d'outil/fonction est transmis tel quel. Utilisez les modèles qui annoncent la prise en charge des outils (voir Modèles et routage; le catalogue marque supports_tools).
resp = client.chat.completions.create(
model="deepseek/deepseek-v4-flash",
messages=[{"role": "user", "content": "What is the weather in Paris?"}],
tools=[{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get the current weather for a city",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
}],
)
print(resp.choices[0].message.tool_calls)
Une réponse qui appelle un outil se termine toujours par finish_reason: "tool_calls" (stop_reason: "tool_use" sur /v1/messages), en streaming ou non, quel que soit le fournisseur qui l'a servie. Renvoyez chaque appel d'outil tel que vous l'avez reçu : certains comportent un champ extra_content (signature de pensée de Gemini) dont le modèle a besoin au tour suivant.
Forme de la réponse
Chaque réponse a les mêmes champs, quel que soit le fournisseur qui l’a servie : les champs de chat completion d’OpenAI (id, object, created, model, choices, usage) et notre usage.cost_usd. Les champs qu’un fournisseur ajoute de son côté (x_groq, service_tier, system_fingerprint, usage.queue_time et similaires) sont supprimés.
Les modèles de raisonnement envoient leur raisonnement à la fois dans reasoning et reasoning_content, avec le même texte, dans message (ou delta en streaming), donc un client qui lit l’un ou l’autre l’obtient. Quand un fournisseur envoie des reasoning_details de style OpenRouter, ils passent tels quels. Une réponse sans raisonnement n’a aucun des deux champs.
Les champs de requête qu’un fournisseur refuse mais qui ne font qu’ajuster la réponse (reasoning, thinking, verbosity, top_k et similaires) sont supprimés pour ce fournisseur, et reasoning: {"effort": "low"} est envoyé comme reasoning_effort quand c’est ce qu’il faut. Le contenu d’un message envoyé sous forme de liste de parties de texte est transmis comme une seule chaîne à un fournisseur qui n’accepte que des chaînes. Une image, un audio ou un fichier envoyés à un modèle qui ne lit que du texte sont refusés avec un 400 simple qui le dit : vérifiez d’abord input_modalities dans GET /v1/models.
Lister les modèles
curl https://api.uberllm.dev/v1/models \
-H "Authorization: Bearer $UBERLLM_API_KEY"
Renvoie la structure de liste OpenAI ({"object":"list","data":[{"id": "...", ...}]})
avec les modèles de chat que vous pouvez utiliser dès maintenant ; ?type=all ajoute les modèles d'image, de vidéo, de musique et
de parole. Chaque modèle de chat inclut context_length, max_output_tokens,
input_modalities, supports_tools, supports_reasoning, supports_vision et
supported_parameters (voir Modèles et routage).
Le catalogue public (sans auth) est également disponible à GET /api/v1/public/models avec
une tarification par endpoint.
Utilisation du streaming
Pour les requêtes de streaming, UberLLM demande automatiquement l'utilisation des tokens (stream_options.include_usage), ainsi le dernier chunk contient un objet usage avec cost_usd, ce pour quoi l'appel est facturé en dollars US. Une réponse qui n'est pas en streaming contient également usage.cost_usd, et l'en-tête X-UberLLM-Cost-USD (sauf pour une réponse lente qui a déjà commencé avec des espaces de keepalive : alors seulement le champ body). Votre facture correspond au coût que le marketplace rapporte pour cet appel. La réponse n'attend pas ce rapport : lorsqu'il n'est pas encore disponible, cost_usd est notre estimation, et votre solde et Tableau de bord → Activité affichent le montant exact un instant plus tard. Si l'utilisation est manquante, UberLLM se rabat sur une estimation du tokenizer — ces lignes sont signalées dans Tableau de bord → Activité.
API de Réponses
client.responses.create et client.responses.stream fonctionnent aussi, sur chaque modèle de chat : texte, appels d'outils (function_call → function_call_output), sortie structurée et streaming. UberLLM ne stocke rien, donc envoyez toute la conversation dans input à chaque appel au lieu de previous_response_id. Détails :
API de Réponses.
r = client.responses.create(
model="deepseek/deepseek-v4.1-flash",
instructions="Answer in one short sentence.",
input="What is the capital of France?",
)
print(r.output_text)
Notes
- Le
/v1final est requis dans l'URL de base. - Chaque requête est envoyée à un fournisseur tiers disponible pour le modèle et est facturée au prix facturé par le fournisseur, sans frais UberLLM. Voir Tarification.
- Pour les tentatives automatiques et les options de routage acceptées par UberLLM, voir Modèles et routage.