Documentation
BreignHUB parle le protocole OpenAI. Pointez n’importe quel client vers l’URL de base ci-dessous, utilisez une clé BreignHUB comme clé API, et le reste de votre code ne bouge pas.
URL de base et authentification
La clé se transmet dans l’en-tête Authorization, en bearer token. Les clés se créent dans le tableau de bord et ne s’affichent qu’une fois — BreignHUB ne stocke pas le secret et ne peut pas vous le remontrer.
- URL de base
- https://api.hub.breign.eu/v1
- Clé API
- Une clé du tableau de bord, qui commence par otoapk_
À appeler depuis votre serveur, pas depuis un navigateur
La passerelle ne répond aux navigateurs que depuis l’origine de ce site, pour la console de test du tableau de bord. C’est voulu : une clé BreignHUB dans du code front-end est une clé publiée. Gardez-la sur votre serveur, ou derrière un proxy que vous contrôlez.
Votre premier appel
Les identifiants de modèles sont des noms simples, exactement tels que GET /models les liste : sans préfixe de provider. Lisez-les là, ou dans le catalogue.
curl https://api.hub.breign.eu/v1/chat/completions \ -H "Authorization: Bearer $BREIGNHUB_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "<model>", "messages": [{ "role": "user", "content": "Say hello." }] }'
Depuis le SDK OpenAI
Seule l’URL de base change. Le streaming fonctionne à l’identique.
from openai import OpenAI client = OpenAI( base_url="https://api.hub.breign.eu/v1", api_key=os.environ["BREIGNHUB_API_KEY"], ) stream = client.chat.completions.create( model="<model>", messages=[{"role": "user", "content": "Say hello."}], stream=True, ) for chunk in stream: print(chunk.choices[0].delta.content or "", end="")
import OpenAI from "openai"; const client = new OpenAI({ baseURL: "https://api.hub.breign.eu/v1", apiKey: process.env.BREIGNHUB_API_KEY, }); const stream = await client.chat.completions.create({ model: "<model>", messages: [{ role: "user", content: "Say hello." }], stream: true, }); for await (const chunk of stream) { process.stdout.write(chunk.choices[0]?.delta?.content ?? ""); }
Lister les modèles
Renvoie les modèles accessibles à l’organisation de la clé. La disponibilité vient de l’organisation, pas de la clé.
curl https://api.hub.breign.eu/v1/models \ -H "Authorization: Bearer $BREIGNHUB_API_KEY"
Ce que la passerelle respecte
Mesuré sur la passerelle, pas déduit d’une spécification. Les champs ci-dessous se comportent comme OpenAI le documente, sauf indication contraire dans le tableau.
| Champ | Comportement |
|---|---|
| model, messages, tools, tool_choice: auto | none, max_tokens, stop, temperature, response_format: json_schema, stream, stream_options | Respecté |
| tool_choice: a named function | Accepté mais pas imposé par le moteur d’inférence : le modèle peut appeler un autre outil. Vérifiez le nom de l’outil dans la réponse. |
| finish_reason: "length" | Transmis. Une réponse non streamée coupée par max_tokens se termine par "length" (Anthropic : "max_tokens"), comme le fournisseur l’a dit. |
| usage.prompt_tokens_details.cached_tokens | Transmis quand le fournisseur le renseigne. DEEP répond 0 pour l’instant, même en cas de cache ; un zéro n’est pas mesuré. |
| POST /v1/messages/count_tokens | Disponible. Le prompt est mesuré par le fournisseur lui-même, par un appel d’un token : exact, mais mesuré et facturé comme tout autre appel. |
Utiliser BreignHUB depuis un agent de code
Tout outil permettant de définir une URL de base compatible OpenAI convient. Deux exemples.
opencode
Ajoutez un provider dans opencode.json. Utilisez @ai-sdk/openai-compatible, qui vise /v1/chat/completions. Marquez le modèle tool_call pour qu’opencode appelle les outils nativement, puis lancez /models et sélectionnez-le.
{
"$schema": "https://opencode.ai/config.json",
"provider": {
"breignhub": {
"npm": "@ai-sdk/openai-compatible",
"name": "BreignHUB",
"options": {
"baseURL": "https://api.hub.breign.eu/v1",
"apiKey": "{env:BREIGNHUB_API_KEY}"
},
"models": {
"<model>": {
"name": "Qwen3.6 35B",
"tool_call": true
}
}
}
}
}export BREIGNHUB_API_KEY=otoapk_… · opencode · /models
Tous les autres
Continue, Cline, aider, LangChain, le SDK AI de Vercel — tous acceptent une URL de base et une clé API. Renseignez ces deux valeurs et c’est terminé. Le tool calling et response_format: json_schema fonctionnent. La seule chose que la passerelle n’impose pas est un tool_choice qui force une fonction précise : le modèle peut en appeler une autre, vérifiez donc le nom de l’outil dans la réponse.
Erreurs
Les échecs n’utilisent pas l’enveloppe OpenAI. Une clé absente ou refusée répond 400 avec un champ Otoroshi-Error ; un corps mal formé répond 400 avec error et error_details ; une erreur levée par le cluster d’inférence est transmise telle que le cluster l’a produite.
# no key, or a key the gateway rejects — 400 { "Otoroshi-Error": "invalid apikey tuple" } # a body that is not valid JSON — 400 { "error": "bad_request", "error_details": "Unexpected end-of-input…" } # an error raised by the inference cluster, passed through { "detail": "Model not found" }
Créer une clé
Les clés se créent et se révoquent depuis le tableau de bord.