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.

first-call.sh
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.

python
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="")
typescript
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é.

models.sh
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.

ChampComportement
model, messages, tools, tool_choice: auto | none, max_tokens, stop, temperature, response_format: json_schema, stream, stream_optionsRespecté
tool_choice: a named functionAccepté 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_tokensTransmis 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_tokensDisponible. 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.

opencode.json
{
  "$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.

errors.json
# 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.

Créer une clé