Une ligne de code, et tu tournes dans l’Union européenne.
L’API est compatible OpenAI. Tes SDK, tes frameworks et ton code existants continuent de fonctionner : tu changes base_url et tu choisis un niveau au lieu d’un nom de modèle.
Démarrage rapide : ton premier appel API
Crée une clé dans ton tableau de bord, sous Paramètres, Clés API. Tu ne vois le secret qu’une seule fois : ensuite, nous ne gardons qu’un hash et le préfixe. Mets-la dans une variable d’environnement, jamais dans ton dépôt.
curl https://api.europeanailab.eu/v1/chat/completions \
-H "Authorization: Bearer $UNION_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "eu-standard",
"messages": [{"role": "user", "content": "Explique l’autoliquidation de la TVA."}]
}'import os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["UNION_API_KEY"],
base_url="https://api.europeanailab.eu/v1", # la seule ligne qui change
)
resp = client.chat.completions.create(
model="eu-standard",
messages=[{"role": "user", "content": "Explique l’autoliquidation de la TVA."}],
)
print(resp.choices[0].message.content)Node, Go, Java, .NET ?
https://api.europeanailab.eu/v1 et utilise ta clé Union. Nous implémentons le contrat chat completions, streaming, tools et schémas JSON compris.Niveaux de modèles et fenêtres de contexte
Dans le champ model, tu passes un niveau, pas un nom de modèle. Ton intégration continue ainsi de fonctionner quand nous remplaçons le modèle sous-jacent, et cela arrivera, parce que les modèles open-weight sont retirés et dépassés.
| Niveau | Contexte | Entrée / 1 M | Sortie / 1 M | Idéal pour |
|---|---|---|---|---|
eu-lite | 131K | 0,40 € | 1,60 € | Tâches rapides et bon marché : classification, extraction, réponses courtes. |
eu-standard | 262K | 0,70 € | 3,50 € | Le niveau à tout faire. Par défaut pour le chat et la majeure partie du trafic API. |
eu-long | 1 000K | 1,00 € | 2,00 € | Des dossiers entiers, des contrats et des bases de code dans un seul prompt. |
eu-pro | 1 000K | 4,00 € | 12,00 € | Raisonnement poussé, agents, code complexe. |
Si tu dépasses la fenêtre de contexte d’un niveau, tu reçois un 400 qui indique le maximum : nous ne tronquons jamais ton prompt en silence.
Réponses en streaming
Le streaming fonctionne comme tu t’y attends, avec une différence importante à connaître, parce qu’elle touche à ton argent.
Active include_usage
stream_options: {"include_usage": true}, tu ne peux pas voir à la fin du flux ce qu’a coûté l’appel. Nous la mesurons de toute façon : il s’agit que toi aussi, tu puisses la voir et la vérifier.stream = client.chat.completions.create(
model="eu-standard",
messages=[{"role": "user", "content": "Écris un résumé."}],
stream=True,
# Sans cela, pas d’objet usage et tu ne vois pas le coût.
stream_options={"include_usage": True},
)
for chunk in stream:
if chunk.choices and chunk.choices[0].delta.content:
print(chunk.choices[0].delta.content, end="")
if chunk.usage: # dernier chunk
print("\n", chunk.usage)Si tu coupes un flux en cours de route, tu ne paies que ce qui a été généré jusque-là. Si la connexion interrompue empêche l’arrivée du chunk de consommation, nous estimons la consommation et la corrigeons lors du rapprochement quotidien avec notre fournisseur. Une telle ligne apparaît dans ton aperçu de consommation comme estimated jusqu’à sa régularisation.
Function calling et utilisation d’outils
Les tools suivent le schéma habituel. Si un modèle produit un appel d’outil qui ne correspond pas à ton schéma, nous le journalisons : en version 1, nous ne le corrigeons pas en silence, car réparer discrètement ta sortie est pire qu’un échec visible.
tools = [{
"type": "function",
"function": {
"name": "find_invoice",
"description": "Recherche une facture par son numéro.",
"parameters": {
"type": "object",
"properties": {"number": {"type": "string"}},
"required": ["number"],
},
},
}]
resp = client.chat.completions.create(
model="eu-standard", messages=messages, tools=tools
)Sortie structurée avec un schéma JSON
Passe un schéma JSON et valide la réponse de ton côté. Notre conseil : valide toujours, même quand le modèle se tient bien d’habitude.
resp = client.chat.completions.create(
model="eu-standard",
messages=[{"role": "user", "content": "Extrais le nom et le montant."}],
response_format={
"type": "json_schema",
"json_schema": {
"name": "invoice",
"schema": {
"type": "object",
"properties": {
"name": {"type": "string"},
"amount_eur": {"type": "number"},
},
"required": ["name", "amount_eur"],
},
},
},
)En-têtes de réponse : coût, niveau et routage
Chaque réponse te dit ce qui s’est passé. Ce n’est pas un bonus de débogage, c’est tout l’intérêt : tu peux vérifier toi-même que tu as obtenu ce que tu as payé.
| En-tête | Signification |
|---|---|
X-EU-Model-Tier | Le niveau sur lequel cette requête a tourné. |
X-EU-Routed | Présent quand la requête a été redirigée vers un autre modèle, avec la raison : censure ou erreur. |
X-EU-Degraded | true quand le modèle de remplacement est moins performant ou a une fenêtre de contexte plus petite. Tu paies alors le moins élevé des deux tarifs. |
X-EU-Refusal-Class | Présent en cas de refus que nous n’avons pas pu rediriger, par exemple A-unrouteable quand aucune alternative n’a assez de contexte. |
X-EU-Tokens-In / -Out | Tokens comptés pour cette requête. |
X-EU-Cost-EUR | Ce que cette requête a débité de ton solde, en euros. |
X-EU-Balance-EUR | Ton solde restant après cette requête. |
Limites de débit et plafonds de dépenses
Il y a une limite par clé et par compte, plus les plafonds que tu fixes toi-même. Ces derniers comptent plus qu’il n’y paraît : sans plafond, une clé qui fuite ou une boucle infinie dans ton propre code peut vider un solde en une nuit.
- Requêtes par minute, par clé et par compte.
- Plafond journalier et mensuel en euros, réglable par clé.
- Nouveaux comptes : 25 € par jour au maximum pendant les 48 premières heures, quel que soit le solde.
- Si nous voyons plus de dix fois ta moyenne hebdomadaire en une heure, nous mettons la clé en pause automatiquement et nous t’envoyons un e-mail. Mieux vaut une fausse alerte qu’un porte-monnaie vide.
- Une requête ne démarre que si ton solde atteint au moins 0,05 €.
Codes d’erreur et que faire
| Code | Signification | Que faire |
|---|---|---|
| 400 | Requête invalide, ou prompt plus long que la fenêtre de contexte. | Corrige la requête ; le maximum figure dans le message d’erreur. |
| 401 | Clé inconnue, révoquée ou en pause. | Vérifie la clé dans ton tableau de bord. |
| 402 | Solde insuffisant. | Recharge. La réponse contient un lien direct. |
| 403 | Requête contraire à la politique d’utilisation. | Voir l’usage raisonnable plus bas. |
| 429 | Limite de débit ou plafond atteint. | Attends et réessaie ; respecte Retry-After. |
| 502 / 503 | Modèle en amont indisponible, aucun repli possible. | Réessaie. Consulte la page Statut. |
Une requête échouée ne te coûte rien : si aucune réponse exploitable n’est revenue, rien n’est débité de ton solde.
Usage raisonnable et politique d’utilisation
Nous refusons les instructions pour des armes, des logiciels malveillants et de la fraude, ainsi que les contenus qui portent atteinte aux enfants. Ces refus sont définitifs : nous ne transmettons jamais une telle requête à un autre modèle pour obtenir quand même une réponse.
Qu’un modèle refuse une question légitime sur la politique, l’histoire ou un sujet de société sensible, c’est autre chose : nous le traitons comme un défaut et envoyons la question à un modèle qui n’a pas cet angle mort. Tu le vois dans l’en-tête X-EU-Routed: censorship.
L’un de nos modèles est distribué sous une licence qui a sa propre politique d’utilisation. Cette politique s’applique entièrement : la redirection ne permet pas de contourner les conditions d’une licence.
Tu ne sais pas si ton cas d’usage est acceptable ? Écris à hello@europeanailab.eu. Une réponse en amont nous coûte moins cher à tous les deux qu’une clé bloquée après coup.
Questions fréquentes
Les questions qui arrivent par e-mail avant que quiconque crée une clé : avec quoi l’API est compatible, ce que coûte une requête et où elle tourne.
Quels SDK OpenAI fonctionnent avec une API compatible OpenAI ?
Tous les SDK officiels, car ce sont de simples clients du contrat chat completions qui prennent la base URL en argument du constructeur. Python et Node sont les cas les plus courants ; Go, Java et .NET fonctionnent de la même façon. Tu gardes ta logique de retry, ta gestion du streaming et tes types.
Puis-je utiliser LangChain ou le Vercel AI SDK avec cette API ?
Oui. Les deux exposent la base URL dans la configuration de leur provider OpenAI : tu la fais pointer vers notre hôte et tu utilises une clé Union AI. Tout autre outil qui permet de remplacer la base URL fonctionne sur le même principe, y compris la plupart des frameworks d’agents et des outils d’évaluation.
L’API prend-elle en charge le streaming et le function calling ?
Oui, les deux, ainsi que la sortie structurée selon un schéma JSON. Les réponses en streaming transmettent la consommation de tokens à la fin du flux, tu peux donc mesurer une requête en streaming aussi précisément qu’une requête classique.
Quelles sont les limites de débit de l’API ?
Il y a une limite de requêtes par minute, par clé et par compte, plus des plafonds journaliers et mensuels en euros que tu fixes toi-même. Les nouveaux comptes sont plafonnés à 25 € par jour pendant les 48 premières heures, quel que soit le solde. Une limite atteinte renvoie un 429 avec un en-tête Retry-After.
Comment gérer les erreurs 429 et les retries ?
Respecte Retry-After au lieu de relancer tout de suite, et espace les tentatives de façon exponentielle avec du jitter, pour qu’un pic ne se synchronise pas entre tes workers. Ne relance pas un 402 : le solde est vide et une boucle ne ferait que répéter l’échec. Une seule nouvelle tentative suffit en général, car un deuxième échec donne rarement une réponse différente.
Comment savoir combien a coûté une requête API ?
Chaque réponse porte des en-têtes : X-EU-Tokens-In et X-EU-Tokens-Out pour les tokens comptés, X-EU-Cost-EUR pour ce qui a été débité de ton solde et X-EU-Balance-EUR pour ce qu’il reste. Tes propres logs peuvent donc répondre à la question du coût par fonctionnalité ou par client, sans ouvrir de tableau de bord.
Quel modèle tourne derrière chaque niveau ?
Chaque niveau correspond à un modèle open-weight nommé, publié avec sa licence et sa fenêtre de contexte sur la page Transparence IA. Tu achètes le niveau plutôt que le nom du modèle : nous pouvons ainsi remplacer le modèle sous-jacent sans casser ton intégration, et nous te prévenons quand nous le faisons.
Migrer une intégration existante tient en trois lignes : la clé, la base URL et un nom de niveau. Le changement complet, et ce qui ne se transpose pas, se trouve dans changer de fournisseur en trois lignes. Encore une question ? Les tarifs par niveau sont sur la page Tarifs, le modèle et la licence derrière chaque niveau sur Transparence IA, et ce qui se passe pendant une panne sur la page Statut. Deux lectures plus longues : ce que coûte une API d’IA par token et où vont vraiment tes prompts.
Passe à une IA faite pour les Européens.
Utilise l’IA sans envoyer tes données à l’étranger : tout sur des serveurs européens, à un prix européen.
13 € par mois pour le chat, résiliable à tout moment. Ou au token, à partir de 10 € de crédit.
Pas encore sûr ? Fais le quiz de 60 secondes →