Référence API
URL de base http://127.0.0.1:3001/v1. Authentifiez-vous avec Authorization: Bearer $YOURBRAND_KEY ou x-api-key: $YOURBRAND_KEY, sur tous les endpoints de modèles.
Vue d'ensemble
Les requêtes et les réponses sont en JSON sur HTTPS, sauf mention contraire de l'endpoint. Les endpoints parlent les formats OpenAI et Anthropic : les SDK et agents existants fonctionnent après un simple changement d'URL de base. Un champ que nous ne prenons pas en charge reçoit une erreur 400 au lieu d'être ignoré.
- URL de base
http://127.0.0.1:3001/v1- Authentification
Authorization: Beareroux-api-keyavec votre clé, sur tous les endpoints de modèles.GET /v1/modelsne demande aucune clé.- Requêtes relayées
- Certains modèles sont relayés à des fournisseurs qui ont une politique sans journaux. Chaque clé commence en mode strict : les requêtes ne vont qu'à nos propres GPU ou à des fournisseurs sans journaux, et sont refusées plutôt qu'envoyées ailleurs. Vous pouvez le désactiver clé par clé.
user,metadataetsafety_identifiersont retirés d'abord, et votre IP et vos en-têtes ne sont jamais transmis. - Limites de débit
- Requêtes en parallèle selon le forfait. Aucun plafond par minute ni par token.
- Streaming
- Server-sent events sur chat completions, Responses et Messages.
- Erreurs
- Le format d'erreur de la famille de l'endpoint, avec un statut 4xx ou 5xx. Voir Erreurs.
Chat
Chat completions et Responses prennent le format d'OpenAI, Messages celui d'Anthropic. Les trois gèrent le streaming et acceptent les mêmes modèles.
POST/v1/chat/completionsCréer une complétion de chatBearer · x-api-key
Génère une réponse pour une conversation. Les corps de requête et de réponse sont ceux d'OpenAI : les SDK OpenAI et tout outil construit dessus fonctionnent sans modification.
Paramètres
| Champ | Type | Remarques |
|---|---|---|
model | string | Obligatoire. Un identifiant de la page Modèles. |
messages | array | Obligatoire. Des objets avec role (system, developer, user, assistant, tool) et content. |
stream | boolean | Envoie la réponse en server-sent events. false par défaut. |
temperature | number | De 0 à 2. Sans ce champ, la valeur par défaut du modèle s'applique. |
max_tokens | integer | Plafonne la longueur de la réponse. Limité par la sortie max. du modèle. |
tools | array | Définitions de fonctions, sur les modèles qui gèrent les appels d'outils. |
Exemple de requête
curl http://127.0.0.1:3001/v1/chat/completions \ -H "Authorization: Bearer $YOURBRAND_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-abliterated","messages":[{"role":"user","content":"hello"}]}'
import OpenAI from "openai"; const client = new OpenAI({ apiKey: process.env.YOURBRAND_KEY, baseURL: "http://127.0.0.1:3001/v1" }); const res = await client.chat.completions.create({ model: "qwen3.8-27b-abliterated", messages: [{ role: "user", content: "hello" }], });
import os from openai import OpenAI client = OpenAI(api_key=os.environ["YOURBRAND_KEY"], base_url="http://127.0.0.1:3001/v1") res = client.chat.completions.create( model="qwen3.8-27b-abliterated", messages=[{"role": "user", "content": "hello"}], )
using System.Net.Http.Json; var key = Environment.GetEnvironmentVariable("YOURBRAND_KEY"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("Authorization", $"Bearer {key}"); var res = await http.PostAsJsonAsync("http://127.0.0.1:3001/v1/chat/completions", new { model = "qwen3.8-27b-abliterated", messages = new[] { new { role = "user", content = "hello" } }, }); Console.WriteLine(await res.Content.ReadAsStringAsync());
#include <cpr/cpr.h> #include <cstdlib> #include <iostream> int main() { std::string key = std::getenv("YOURBRAND_KEY"); auto res = cpr::Post( cpr::Url{"http://127.0.0.1:3001/v1/chat/completions"}, cpr::Header{{"Authorization", "Bearer " + key}, {"Content-Type", "application/json"}}, cpr::Body{R"({ "model": "qwen3.8-27b-abliterated", "messages": [{"role":"user","content":"hello"}] })"}); std::cout << res.text << "\n"; }
require "json" require "net/http" res = Net::HTTP.post( URI("http://127.0.0.1:3001/v1/chat/completions"), { model: "qwen3.8-27b-abliterated", messages: [{ role: "user", content: "hello" }], }.to_json, "Authorization" => "Bearer #{ENV['YOURBRAND_KEY']}", "Content-Type" => "application/json", ) puts res.body
package main import ( "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "model": "qwen3.8-27b-abliterated", "messages": [{"role":"user","content":"hello"}] }` req, _ := http.NewRequest("POST", "http://127.0.0.1:3001/v1/chat/completions", strings.NewReader(body)) req.Header.Set("Authorization", "Bearer "+os.Getenv("YOURBRAND_KEY")) req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() out, _ := io.ReadAll(res.Body) fmt.Println(string(out)) }
Réponse
{
"id": "chatcmpl-8f1c…",
"object": "chat.completion",
"created": 1793282400,
"model": "qwen3.8-27b-abliterated",
"choices": [{
"index": 0,
"message": { "role": "assistant", "content": "Hello! What are you building?" },
"finish_reason": "stop"
}],
"usage": { "prompt_tokens": 9, "completion_tokens": 8, "total_tokens": 17 }
}
Streaming
Avec "stream": true, chaque événement est une ligne data: contenant un chat.completion.chunk. Le dernier fragment contient usage, puis le flux se termine par data: [DONE].
POST/v1/responsesCréer une réponseBearer · x-api-key
Le format Responses d'OpenAI, streaming compris : client.responses.create() fonctionne.
Exemple de requête
curl http://127.0.0.1:3001/v1/responses \ -H "Authorization: Bearer $YOURBRAND_KEY" \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-abliterated","input":"hello"}'
POST/v1/messagesCréer un messageBearer · x-api-key
Le format Messages d'Anthropic, streaming compris. Pointez le SDK Anthropic vers http://127.0.0.1:3001, sans /v1 : il ajoute /v1/messages lui-même.
Paramètres
| Champ | Type | Remarques |
|---|---|---|
model | string | Obligatoire. Un identifiant de la page Modèles. |
max_tokens | integer | Obligatoire. Plafonne la longueur de la réponse. |
messages | array | Obligatoire. role vaut user ou assistant ; content est une chaîne ou une liste de blocs {"type": "text"}. |
system | string | Prompt système, placé hors de messages. |
stream | boolean | Envoie la réponse en server-sent events nommés. false par défaut. |
temperature | number | De 0 à 1. Sans ce champ, la valeur par défaut du modèle s'applique. |
Exemple de requête
curl http://127.0.0.1:3001/v1/messages \ -H "x-api-key: $YOURBRAND_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-abliterated","max_tokens":1024,"messages":[{"role":"user","content":"hello"}]}'
import Anthropic from "@anthropic-ai/sdk"; const client = new Anthropic({ apiKey: process.env.YOURBRAND_KEY, baseURL: "http://127.0.0.1:3001" }); const msg = await client.messages.create({ model: "qwen3.8-27b-abliterated", max_tokens: 1024, messages: [{ role: "user", content: "hello" }], });
import os import anthropic client = anthropic.Anthropic(api_key=os.environ["YOURBRAND_KEY"], base_url="http://127.0.0.1:3001") msg = client.messages.create( model="qwen3.8-27b-abliterated", max_tokens=1024, messages=[{"role": "user", "content": "hello"}], )
using System.Net.Http.Json; var key = Environment.GetEnvironmentVariable("YOURBRAND_KEY"); using var http = new HttpClient(); http.DefaultRequestHeaders.Add("x-api-key", key); http.DefaultRequestHeaders.Add("anthropic-version", "2023-06-01"); var res = await http.PostAsJsonAsync("http://127.0.0.1:3001/v1/messages", new { model = "qwen3.8-27b-abliterated", max_tokens = 1024, messages = new[] { new { role = "user", content = "hello" } }, }); Console.WriteLine(await res.Content.ReadAsStringAsync());
#include <cpr/cpr.h> #include <cstdlib> #include <iostream> int main() { std::string key = std::getenv("YOURBRAND_KEY"); auto res = cpr::Post( cpr::Url{"http://127.0.0.1:3001/v1/messages"}, cpr::Header{{"x-api-key", key}, {"anthropic-version", "2023-06-01"}, {"Content-Type", "application/json"}}, cpr::Body{R"({ "model": "qwen3.8-27b-abliterated", "max_tokens": 1024, "messages": [{"role":"user","content":"hello"}] })"}); std::cout << res.text << "\n"; }
require "json" require "net/http" res = Net::HTTP.post( URI("http://127.0.0.1:3001/v1/messages"), { model: "qwen3.8-27b-abliterated", max_tokens: 1024, messages: [{ role: "user", content: "hello" }], }.to_json, "x-api-key" => "#{ENV['YOURBRAND_KEY']}", "anthropic-version" => "2023-06-01", "Content-Type" => "application/json", ) puts res.body
package main import ( "fmt" "io" "net/http" "os" "strings" ) func main() { body := `{ "model": "qwen3.8-27b-abliterated", "max_tokens": 1024, "messages": [{"role":"user","content":"hello"}] }` req, _ := http.NewRequest("POST", "http://127.0.0.1:3001/v1/messages", strings.NewReader(body)) req.Header.Set("x-api-key", os.Getenv("YOURBRAND_KEY")) req.Header.Set("anthropic-version", "2023-06-01") req.Header.Set("Content-Type", "application/json") res, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer res.Body.Close() out, _ := io.ReadAll(res.Body) fmt.Println(string(out)) }
Réponse
{
"id": "msg_4e1a…",
"type": "message",
"role": "assistant",
"model": "qwen3.8-27b-abliterated",
"content": [{ "type": "text", "text": "Hello! What are you building?" }],
"stop_reason": "end_turn",
"stop_sequence": null,
"usage": { "input_tokens": 9, "output_tokens": 8 }
}
Événements du flux, dans l'ordre
message_startLe message avec un contenu vide et la consommation de tokens en entrée.content_block_startOuvre le bloc de texte 0.content_block_deltaRépété. Chacun contient untext_delta.content_block_stopFerme le bloc 0.message_deltastop_reasonet la consommation de tokens en sortie.message_stopLe flux est terminé.
POST/v1/messages/count_tokensCompter les tokensBearer · x-api-key
Le nombre de tokens en entrée qu'utiliserait une requête Messages, sans l'exécuter.
Exemple de requête
curl http://127.0.0.1:3001/v1/messages/count_tokens \ -H "x-api-key: $YOURBRAND_KEY" \ -H "anthropic-version: 2023-06-01" \ -H "Content-Type: application/json" \ -d '{"model":"qwen3.8-27b-abliterated","messages":[{"role":"user","content":"hello"}]}'
Réponse
{ "input_tokens": 9 }
Embeddings et audio
Une requête, une réponse complète. Des exemples de requêtes pour chaque modèle sont sur la page Modèles.
POST/v1/embeddingsCréer des embeddingsBearer · x-api-key
Des embeddings pour une ou plusieurs entrées, dans l'ordre des entrées, au format d'OpenAI.
POST/v1/rerankReclasser des documentsBearer · x-api-key
Les documents envoyés, classés par pertinence pour une requête, chacun avec son index et son score, le plus pertinent en premier.
POST/v1/audio/speechSynthétiser la paroleBearer · x-api-key
L'audio parlé d'un texte, au format d'OpenAI. La réponse est le fichier audio, pas du JSON.
POST/v1/audio/transcriptionsTranscrire un audioBearer · x-api-key
Le texte d'un fichier audio, au format d'OpenAI. Le fichier est envoyé en multipart/form-data.
Images et vidéo
Les images reviennent dans le même appel. Les vidéos sont des tâches que vous interrogez, puis téléchargez. Des exemples de requêtes pour chaque modèle sont sur la page Modèles.
POST/v1/images/generationsGénérer des imagesBearer · x-api-key
Les images générées, incluses dans la réponse, au format d'OpenAI.
POST/v1/videosCréer une vidéoBearer · x-api-key
Renvoie tout de suite l'identifiant d'une tâche. Interrogez GET /v1/videos/{id} jusqu'à ce que la tâche soit terminée, puis téléchargez la vidéo depuis GET /v1/videos/{id}/content. La vidéo est stockée chiffrée et supprimée avec sa tâche une heure après la fin.
Modèles
Tous les modèles du catalogue. Aucune clé requise.
GET/v1/modelsLister les modèles
Tous les identifiants de modèles au format de liste d'OpenAI : client.models.list() fonctionne.
Exemple de requête
curl http://127.0.0.1:3001/v1/models
Réponse
{ "object": "list", "data": [{ "id": "qwen3.8-27b-abliterated", "object": "model", "owned_by": "yourbrand" }, …] }
Erreurs
Chaque endpoint répond avec le format d'erreur de sa famille : la gestion des erreurs des SDK fonctionne sans modification.
| Statut | Type | Que faire |
|---|---|---|
400 | invalid_request_error | Corrigez la requête. Le message indique le champ fautif, ou un champ que nous ne prenons pas en charge. Une requête bloquée pour un contenu que la loi interdit reçoit aussi une erreur 400, et n'est pas facturée. |
401 | authentication_error | Vérifiez la clé et l'en-tête d'authentification. |
404 | not_found_error | L'identifiant du modèle ou l'endpoint n'existe pas. |
429 | rate_limit_error | Limite de parallélisme du forfait dépassée. Attendez Retry-After secondes. |
500 | api_error | Quelque chose a échoué de notre côté. Réessayez avec backoff. |
503 | — | Le modèle n'est pas en service pour le moment. Réessayez, ou changez de modèle. |
Format OpenAI, tous les autres endpoints
{ "error": {
"message": "Model `nope` does not exist.",
"type": "not_found_error" } }Format Anthropic, Messages et count_tokens
{ "type": "error",
"error": {
"type": "not_found_error",
"message": "model: nope does not exist." } }Limites de débit
Les limites comptent les requêtes en cours, pas les requêtes par minute : un 429 signifie que vous dépassez la limite de parallélisme de votre forfait. Il n'y a aucun plafond de tokens par minute. Chaque 429 contient Retry-After en secondes.
| Forfait | Requêtes en parallèle | Mensuel |
|---|---|---|
| Paiement à l'usage | 2 | — |
| Starter | 3 | $15 |
| Pro | 5 | $39 |
| Max | 8 | $99 |
Requêtes en cours
Le code de relance est dans le guide de gestion des erreurs.