Changer le base_url d'OpenAI ou Anthropic pour passer par une passerelle
Par Protypa · Mis à jour le 4 min de lecture
La réponse courte
Une passerelle (« gateway ») se place entre votre application et le modèle d'IA. Elle parle le même protocole que le fournisseur, donc votre code ne change presque pas : on remplace l'URL de base et la clé d'API. Tout ce que la passerelle fait ensuite (masquage, routage, comptage, journalisation, signature) se produit sans que votre code le sache.
La passerelle Subsidia comprend deux dialectes : OpenAI chat/completions et Anthropic messages. Elle répond sur https://api.subsidia.protypa.fr.
Ce qui change, et ce qui ne change pas
| Vous changez | Vous gardez |
|---|---|
L'URL de base (base_url / baseURL) | Votre SDK officiel (OpenAI, Anthropic) et sa version |
La clé d'API : une clé Subsidia sk_live_... | Le format des messages, le streaming, les outils (tools) |
Le champ model, si vous voulez une capacité Subsidia | Votre logique applicative |
Ce que vous obtenez en échange : les données personnelles repérables sont masquées avant un envoi externe, chaque appel est routé vers un modèle adapté à la tâche, l'usage est compté sur votre espace de travail, et chaque réponse revient avec un certificat signé et chaîné dont l'identifiant est dans l'en-tête x-pulse-proof.
Étape 1 : créer une clé
Dans la plateforme Subsidia, page Gateway (https://subsidia.protypa.fr/plateforme/gateway), créez une clé avec la portée engine. La clé complète, qui commence par sk_live_, n'est affichée qu'une fois : placez-la dans une variable d'environnement, jamais dans le code source.
export SUBSIDIA_API_KEY="sk_live_..."
Étape 2 : changer l'URL de base
Les deux formes d'en-tête d'authentification sont acceptées : Authorization: Bearer sk_live_... (SDK OpenAI, curl) et x-api-key: sk_live_... (SDK Anthropic).
SDK OpenAI en Python
import os
from openai import OpenAI
client = OpenAI(
base_url="https://api.subsidia.protypa.fr/v1", # la ligne qui change
api_key=os.environ["SUBSIDIA_API_KEY"],
)
raw = client.chat.completions.with_raw_response.create(
model="pulse-auto",
messages=[{"role": "user", "content": "Résume cette clause de résiliation."}],
)
completion = raw.parse()
print(completion.choices[0].message.content)
print(raw.headers.get("x-pulse-proof")) # identifiant du certificat
SDK OpenAI en TypeScript
import OpenAI from 'openai'
const client = new OpenAI({
baseURL: 'https://api.subsidia.protypa.fr/v1', // la ligne qui change
apiKey: process.env.SUBSIDIA_API_KEY,
})
const { data, response } = await client.chat.completions
.create({
model: 'pulse-auto',
messages: [{ role: 'user', content: 'Résume cette clause de résiliation.' }],
})
.withResponse()
console.log(data.choices[0].message.content)
console.log(response.headers.get('x-pulse-proof'))
SDK Anthropic en TypeScript
L'URL de base est ici l'hôte seul : le SDK ajoute lui-même /v1/messages.
import Anthropic from '@anthropic-ai/sdk'
const client = new Anthropic({
baseURL: 'https://api.subsidia.protypa.fr',
apiKey: process.env.SUBSIDIA_API_KEY,
})
const { data, response } = await client.messages
.create({
model: 'pulse-auto',
max_tokens: 1024,
messages: [{ role: 'user', content: 'Résume cette clause de résiliation.' }],
})
.withResponse()
console.log(data.content)
console.log(response.headers.get('x-pulse-proof'))
curl
curl -i https://api.subsidia.protypa.fr/v1/chat/completions \
-H "Authorization: Bearer $SUBSIDIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"pulse-auto","messages":[{"role":"user","content":"Bonjour"}]}'
Claude Code
Claude Code parle le protocole Anthropic. Les variables suivantes valent pour la session de terminal en cours :
export ANTHROPIC_BASE_URL="https://api.subsidia.protypa.fr"
export ANTHROPIC_AUTH_TOKEN="sk_live_..." # AUTH_TOKEN, pas API_KEY
export ANTHROPIC_MODEL="pulse-auto"
export ANTHROPIC_SMALL_FAST_MODEL="pulse-auto"
claude
Le champ model est une adresse
Les outils tiers n'exposent qu'un réglage toujours modifiable : le nom du modèle. La passerelle le lit comme une adresse : la partie avant le premier + choisit qui répond, chaque drapeau ajoute ou retire une capacité.
| Adresse | Effet |
|---|---|
pulse-auto | Synapse choisit le modèle selon la tâche (valeur par défaut) |
pulse-agent | Toujours le modèle complet configuré |
pulse-sensitive | Traitement local, sur une installation qui a un modèle local |
agent:<slug> | Servi par un de vos agents (prompt, mémoire, documents, outils) |
pulse-auto+cortex | Ancre la réponse dans votre base documentaire ; les passages utilisés sont engagés par empreinte dans le certificat |
agent:<slug>+nocortex+nomemory | L'agent sans base documentaire ni mémoire, pour un essai isolé |
Tout autre nom (gpt-4o…) | Accepté, enregistré dans le certificat, routé comme pulse-auto |
La base de l'adresse est sensible à la casse, les drapeaux non, et leur ordre ne compte pas. La liste complète est dans la documentation de l'adressage.
La ligne rouge : sans préfixe ni drapeau, rien n'est ajouté. Un nom comme gpt-4o est un passage fidèle : l'appel est quand même masqué, routé, comptabilisé et signé, mais aucun agent ni document n'entre dans votre prompt. Les capacités s'ajoutent par l'adresse, jamais d'office.
Ce que la passerelle vous renvoie
| En-tête | Contenu |
|---|---|
x-pulse-proof | Identifiant du certificat (pf_ + 32 caractères hexadécimaux) |
x-pulse-provider | Le fournisseur qui a répondu (ollama, openai…) |
x-pulse-pii-masked | Nombre de valeurs masquées avant l'envoi |
x-pulse-conversation | Identifiant de conversation, pour les appels agent: |
En flux (stream: true), seul x-pulse-proof est envoyé, avec le premier octet ; pour le reste, lisez le certificat. Le certificat est enregistré avant la fin de la réponse, et le texte signé est celui que vous avez reçu en flux. Il se récupère avec GET /v1/proofs/{id} et se contrôle sur la page Contrôler un certificat ou hors ligne (voir le guide de vérification).
Ce que cela ne fait pas
- Ce n'est pas un relais transparent vers OpenAI ou Anthropic. Le nom de modèle ne choisit ni le fournisseur ni le modèle : c'est Synapse, selon la configuration de l'installation. Si votre contrat exige un fournisseur précis, vérifiez
x-pulse-provideret le champegressdu certificat, ne présumez pas. - Ce n'est pas du pass-through au sens strict. Les appels sont masqués, routés, comptés et signés. « Passage fidèle » signifie seulement qu'aucune capacité n'est imposée à votre prompt.
- Le certificat prouve l'échange, pas l'exactitude de la réponse. Pour confronter une réponse à vos pièces, c'est le rôle du Vérificateur.
- Quelques écarts avec l'API d'origine : les champs inconnus sont acceptés et ignorés ;
max_tokensest plafonné par la passerelle (16 000 par défaut) au lieu d'être rejeté ; avec destools, l'appel est routé vers le modèle complet et, en flux, la réponse est émise en un seul bloc ; les adressesdebate:renvoient une erreur 501. - Les erreurs de quota diffèrent selon le dialecte : 402
insufficient_quotacôté OpenAI, 429 côté Anthropic. Un drapeau mal orthographié est ignoré sans erreur. - Le masquage est un repérage d'identifiants, pas une compréhension du texte : voir Masquer les données personnelles avant un envoi à OpenAI.
- Un appel est compté. L'usage est mesuré en questions sur votre espace de travail, et une clé peut avoir son propre plafond mensuel.
Checklist d'intégration
- Clé créée avec la portée
engine, stockée hors du code source. base_urlchangé (avec/v1pour OpenAI, hôte seul pour Anthropic).- Un test d'intégration lit
x-pulse-proofetx-pulse-providersur un appel réel. - L'identifiant de preuve est conservé à côté de l'enregistrement métier que la réponse alimente.
- Les erreurs 401, 402/429 et 403 (
scope_denied) sont gérées par votre code.
Pour tracer ces appels côté ingénierie, voir aussi Tracer les requêtes IA : observabilité ou preuve ?.
Questions fréquentes
Comment faire passer mon code OpenAI par une autre URL sans le réécrire ?
Les SDK officiels acceptent une URL de base. Avec la passerelle Subsidia, vous remplacez le base_url par https://api.subsidia.protypa.fr/v1 et la clé par une clé Subsidia (sk_live_...). Le reste du code, y compris le format des messages, ne change pas. Avec le SDK Anthropic, l'URL de base est l'hôte seul : le SDK ajoute /v1/messages.
Si j'envoie model gpt-4o, est-ce bien GPT-4o qui répond ?
Pas nécessairement. Un nom de modèle sans préfixe ni drapeau Subsidia est accepté, enregistré dans le certificat, puis routé comme pulse-auto : le fournisseur et le modèle sont choisis par Synapse selon l'installation. Lisez l'en-tête x-pulse-provider ou le champ egress du certificat pour savoir qui a réellement répondu.
Quels outils fonctionnent avec la passerelle ?
Tout client qui permet de définir une URL de base : les SDK officiels OpenAI et Anthropic, Claude Code, Cursor, n8n, LangChain. Pour Claude Code, on utilise ANTHROPIC_BASE_URL et ANTHROPIC_AUTH_TOKEN (et non ANTHROPIC_API_KEY, qui n'accepte que les clés au format Anthropic).
Où trouve-t-on l'identifiant de preuve d'une réponse ?
Dans l'en-tête de réponse x-pulse-proof, de la forme pf_ suivi de 32 caractères hexadécimaux. Il est aussi dans le champ pulse.proof du corps (dialecte OpenAI, réponse non diffusée). En flux, l'en-tête est envoyé avant le premier jeton.
La passerelle ajoute-t-elle des instructions à mon prompt ?
Non, pas sans que vous le demandiez. Sans préfixe ni drapeau Subsidia dans le nom du modèle, rien n'est ajouté à votre prompt et aucun agent ni base documentaire n'intervient. L'appel est tout de même masqué, routé, comptabilisé et signé. Les capacités supplémentaires (+cortex, agent:, pulse-sensitive) sont à demander dans l'adresse.
Que se passe-t-il si je fais une faute de frappe dans un drapeau ?
Un drapeau inconnu est ignoré sans erreur : pulse-auto+cortx est simplement un appel pulse-auto, sans ancrage documentaire. Vérifiez l'orthographe, ou le champ address du certificat pour voir ce qui a été interprété.
