# Changer le base_url d'OpenAI ou Anthropic pour passer par une passerelle

> Une passerelle d'IA est un point d'entrée unique qui parle le même protocole que OpenAI ou Anthropic : il suffit de changer le base_url du SDK et la clé d'API. Avec la passerelle Subsidia (https://api.subsidia.protypa.fr/v1), chaque appel est masqué, routé, comptabilisé et signé, et l'identifiant du certificat revient dans l'en-tête x-pulse-proof. Le fournisseur et le modèle sont choisis par l'installation, pas par le nom de modèle que vous envoyez.

Source : https://subsidia.protypa.fr/guides/passerelle-compatible-openai-anthropic · mis à jour le 2026-10-25 · Protypa

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

```bash
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

```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

```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`.

```typescript
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

```bash
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 :

```bash
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](https://dev.subsidia.protypa.fr/docs/model-addressing).

**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](/certificat) ou hors ligne (voir le [guide de vérification](/guides/verifier-un-certificat-de-reponse-ia)).

## 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-provider` et le champ `egress` du 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_tokens` est plafonné par la passerelle (16 000 par défaut) au lieu d'être rejeté ; avec des `tools`, l'appel est routé vers le modèle complet et, en flux, la réponse est émise en un seul bloc ; les adresses `debate:` renvoient une erreur 501.
- **Les erreurs de quota diffèrent selon le dialecte** : 402 `insufficient_quota` cô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](/guides/masquer-donnees-personnelles-avant-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

1. Clé créée avec la portée `engine`, stockée hors du code source.
2. `base_url` changé (avec `/v1` pour OpenAI, hôte seul pour Anthropic).
3. Un test d'intégration lit `x-pulse-proof` et `x-pulse-provider` sur un appel réel.
4. L'identifiant de preuve est conservé à côté de l'enregistrement métier que la réponse alimente.
5. 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 ?](/guides/tracer-requetes-ia-observabilite-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é.
