Pour appeler l'API Mistral, il faut trois choses : une clé créée dans la console Studio, une requête HTTP vers /v1/chat/completions et un identifiant de modèle. Le premier échange tient en dix minutes. La solidité de l'intégration se joue ensuite sur cinq réglages à ajouter au guide de démarrage officiel : l'endpoint européen, une version de modèle épinglée, un plafond de jetons vérifié à chaque réponse, des relances que le SDK ne fait pas seul et un coût calculé appel par appel.
Ce tutoriel s'adresse aux développeurs, makers et équipes ops qui intègrent Mistral dans une application métier, un CRM ou un outil interne. Nous avons fait tourner Mistral Small en production sur Tala, l'assistant téléphonique que nous développons, et nous avons rejoué chaque étape le 5 novembre 2026 avec le SDK Python 3.7.0 et le modèle mistral-small-2603. Les chiffres cités viennent de ces essais ou de la documentation officielle consultée le même jour. Si vous en êtes encore à décider s'il faut adopter Mistral, commencez par notre analyse de Mistral AI en entreprise, qui traite du choix avant la technique.
Créer sa clé API Mistral : mode gratuit ou paiement à l'usage
La clé se crée dans la console Studio, sur la page API Keys de console.mistral.ai, comme le décrit le guide de création de clé : bouton New key, un nom, une date d'expiration et la portée d'accès aux connecteurs. La clé complète ne s'affiche qu'une fois. Copiez-la dans votre coffre de secrets avant de fermer la fenêtre, puis exposez-la à votre code sous la variable MISTRAL_API_KEY. Nous créons une clé par projet et par environnement, avec une expiration courte en développement : une clé qui fuit dans un dépôt ou un journal se révoque alors sans couper la production.
Selon le même guide, le mode gratuit est actif par défaut, sans carte bancaire, avec des quotas d'usage et de débit. Il suffit pour prototyper, à une condition sur les données. La page d'aide de Mistral sur l'usage des données pour l'entraînement indique qu'en mode gratuit, les entrées et les sorties peuvent servir à entraîner les modèles. Le retrait se fait dans le panneau d'administration, menu Privacy, en désactivant l'option « Anonymous improvement data », et le réglage de l'API est distinct de celui de Vibe. Nous le coupons avant d'envoyer la moindre donnée client, même de test.
Le passage au paiement à l'usage change surtout les limites de débit. Mistral les compte en requêtes par seconde, en jetons par minute et en jetons par mois. Il les relève par paliers selon le montant déjà facturé : palier 2 au-delà de 20 €, palier 3 au-delà de 100 €, palier 4 au-delà de 500 €, d'après l'article d'aide sur les limites. Selon le même article, ajouter des crédits prépayés ne relève rien, et au-delà de la limite l'API répond par une erreur 429. Un projet qui lance un import de 50 000 documents le premier jour bute donc sur son palier de débit, quel que soit son budget. Sur nos appels du 5 novembre, chaque réponse portait des en-têtes comme x-ratelimit-remaining-tokens-minute et x-ratelimit-remaining-req-minute : lisez-les pour ralentir avant le 429 plutôt qu'après.
Premier appel à l'API Mistral, en curl puis en Python
Un premier appel tient en une requête POST sur https://api.eu.mistral.ai/v1/chat/completions, avec la clé dans l'en-tête Authorization: Bearer et trois champs : model, messages et max_tokens. Nous visons l'endpoint européen pour la localisation des données, et nous fixons max_tokens dès le départ. En curl, sans aucune dépendance :
curl https://api.eu.mistral.ai/v1/chat/completions \
-H "Authorization: Bearer $MISTRAL_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-2603",
"max_tokens": 200,
"messages": [{"role": "user", "content": "Donne trois idées de titre pour une FAQ produit."}]
}'
La réponse est un JSON dont le texte se trouve dans choices[0].message.content. Regardez aussi finish_reason. Sur notre essai, cette demande de trois titres a consommé les 200 jetons autorisés et s'est arrêtée au milieu du commentaire qui accompagnait le deuxième titre, avec finish_reason à "length". Une réponse coupée ressemble à une réponse complète tant qu'on ne lit pas ce champ, et c'est le premier contrôle à coder.
En Python, le SDK officiel s'installe par pip install mistralai. La version 3.7.0, publiée le 1er novembre 2026 sur PyPI, demande Python 3.10 ou plus récent, et le client s'importe depuis mistralai.client. Le code ci-dessous est celui que nous avons exécuté.
import os
from mistralai.client import Mistral
from mistralai.client.utils import BackoffStrategy, RetryConfig
client = Mistral(
api_key=os.environ["MISTRAL_API_KEY"],
server_url="https://api.eu.mistral.ai",
timeout_ms=30_000,
retry_config=RetryConfig("backoff", BackoffStrategy(500, 8_000, 2.0, 30_000), True),
)
reponse = client.chat.complete(
model="mistral-small-2603",
messages=[
{"role": "system", "content": "Tu réponds en français, en trois phrases au plus."},
{"role": "user", "content": "Résume ce ticket : le client ne reçoit plus les factures par e-mail depuis lundi."},
],
max_tokens=300,
temperature=0.2,
)
choix = reponse.choices[0]
if choix.finish_reason == "length":
raise RuntimeError("Réponse coupée : relever max_tokens ou resserrer la consigne")
print(choix.message.content)
print(reponse.usage.prompt_tokens, reponse.usage.completion_tokens)
Le paramètre qui compte le plus est retry_config. Dans le code de la version 3.7.0 du SDK Python, chat.complete ne relance aucune requête si vous ne fournissez pas de RetryConfig. Une fois la configuration passée, il relance sur les codes 429, 500, 502, 503 et 504, avec ici un délai initial de 500 ms, doublé à chaque essai, plafonné à 8 secondes, pour 30 secondes au total. Sans ce réglage, un 429 ponctuel remonte tel quel jusqu'à votre utilisateur.
Fixez aussi timeout_ms en fonction de la longueur de sortie attendue : sur notre essai, 1 500 jetons générés en mode non diffusé ont pris 10,7 secondes, et 30 secondes laissent de la marge. Créez enfin le client une seule fois par processus. Sur Tala, en juillet 2026, notre sonde de latence, qui surveillait plusieurs fournisseurs LLM, recréait un client à chaque mesure et comptait la poignée de main TLS comme une lenteur du fournisseur. Elle affichait 1 000 à 2 000 ms là où un vrai tour d'appel prenait environ 340 ms, et 6 appels sur 329 ont été déroutés à tort en 14 jours. Client unique, relances bornées, délai explicite : c'est le socle que nous posons en premier sur un projet d'agent IA sur mesure.
Quel identifiant de modèle écrire dans votre code
En production, écrivez un identifiant versionné comme mistral-small-2603, jamais un alias en -latest. La politique de cycle de vie des modèles prévient qu'un alias peut vous exposer à des changements silencieux de comportement et de prix. Elle fixe aussi les préavis : six mois avant le retrait d'un modèle en disponibilité générale, un mois pour un modèle en préversion publique. Après le retrait, l'identifiant répond en 404. Nous l'avons vérifié sur mistral-medium-2508, retiré le 31 août 2026 selon la table des modèles : l'API renvoie un 404 avec le message « Model mistral-medium-2508 is deprecated. ». Tout code qui porte encore cet identifiant en dur échoue depuis son retrait.
L'alias réserve deux autres surprises. Le 5 novembre 2026, l'API indiquait que mistral-large-latest désigne mistral-large-2512, soit Mistral Large 3. La même table le donne en dépréciation depuis le 31 octobre 2026, avec un retrait prévu le 30 avril 2027. Mistral Large 4 existe sous mistral-large-4-0, avec un million de jetons de contexte, mais en préversion publique depuis le 6 octobre 2026. Or les README officiels du SDK Python et du SDK TypeScript utilisent mistral-large-latest dans leurs exemples : copiés tels quels, ils branchent votre code sur un modèle déjà annoncé en retrait. Enfin, sur nos appels du 5 novembre, le champ model de la réponse renvoyait l'alias lui-même quand la requête visait un alias. Vos journaux ne disent alors plus quelle version a produit quelle réponse.
Pour la plupart des intégrations métier, Mistral Small 4 suffit. D'après sa fiche technique, il est en disponibilité générale depuis le 16 mars 2026, sous licence Apache 2.0, avec un contexte de 256 000 jetons (262 144 selon l'API), et il accepte les outils, les sorties structurées et les images. Sur la grille tarifaire relevée le 5 novembre 2026, il coûte 0,15 $ par million de jetons en entrée et 0,60 $ en sortie, contre 0,70 $ et 2,10 $ pour Large 4. Sur la même grille, Ministral 3 8B descend à 0,15 $ en entrée comme en sortie, pour le tri et le routage de gros volumes, et Mistral Embed coûte 0,10 $ par million de jetons en entrée.
Quel identifiant mettre dans votre code
Choix par usage, identifiants vérifiés sur l'API le 5 novembre 2026
L'alias suit la version courante sans toucher au code. Acceptable tant qu'aucun traitement ne dépend du format exact de la réponse.
mistral-small-latestDisponibilité générale, six mois de préavis avant retrait, 0,15 $ et 0,60 $ par million de jetons.
mistral-small-2603Un million de jetons de contexte, mais une préversion publique avec un mois de préavis seulement.
mistral-large-4-0Même prix en entrée et en sortie, 0,15 $ par million de jetons, assez pour attribuer une étiquette ou une catégorie.
ministral-8b-2512Embeddings à 0,10 $ par million de jetons en entrée, avec le même identifiant à l'indexation et à la requête.
mistral-embed-2312Sources : docs.mistral.ai (tarifs, cycle de vie des modèles) et réponses de /v1/models, relevés le 05/11/2026.
Placez l'identifiant dans votre configuration plutôt que dans le code, et journalisez-le à côté de chaque réponse. Changer de modèle, ou de fournisseur derrière une passerelle LLM compatible OpenAI, tiendra alors en une ligne, et vos journaux garderont la trace de ce qui a tourné.
Obtenir un JSON exploitable avec les sorties structurées
Pour récupérer des données plutôt que du texte libre, passez un schéma JSON dans response_format. Mistral propose deux modes. Le mode JSON garantit un JSON valide, mais la documentation des sorties structurées demande alors de décrire le format attendu dans le prompt. Les sorties structurées personnalisées imposent votre schéma, et la documentation les juge plus fiables. En Python, le SDK accepte directement un modèle Pydantic.
import os
from pydantic import BaseModel
from mistralai.client import Mistral
class Facture(BaseModel):
societe: str
montant_ht: float
date_echeance: str
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"], server_url="https://api.eu.mistral.ai")
reponse = client.chat.parse(
model="mistral-small-2603",
messages=[
{"role": "system", "content": "Extrais les informations de la facture. Date au format AAAA-MM-JJ."},
{"role": "user", "content": "Facture Atelier Brun, 1 240 euros HT, à régler avant le 15 décembre 2026."},
],
response_format=Facture,
max_tokens=200,
temperature=0,
)
facture = reponse.choices[0].message.parsed
print(facture)
Ce script renvoie societe='Atelier Brun' montant_ht=1240.0 date_echeance='2026-12-15' : le montant « 1 240 euros HT » devient le nombre 1240.0 et la date écrite en toutes lettres passe au format demandé. D'après la même documentation, le SDK ajoute au prompt système une phrase qui contient le schéma, ce qui se paie en jetons d'entrée à chaque appel. Sans SDK, la requête HTTP porte "response_format": {"type": "json_schema", "json_schema": {"name": "facture", "schema": {...}, "strict": true}}, et nous avons obtenu le même JSON par cette voie, avec le montant à 1240 et la date au format ISO.
Le schéma garantit la forme de la réponse. Il ne dit rien de l'exactitude du contenu. Quand une information manque dans le document source, un champ obligatoire pousse le modèle à le remplir quand même. Déclarez donc optionnels les champs qui peuvent manquer. Contrôlez ensuite dans votre code les règles métier que le schéma ignore : un montant positif, une échéance postérieure à la date de facture, un SIRET à 14 chiffres. Avant de brancher une extraction sur un CRM ou un ERP, comparez-la à une saisie humaine sur quelques dizaines de vrais documents. Les champs que le modèle complète faute de mieux apparaissent alors pour quelques centimes de jetons, avant d'atteindre la comptabilité.
Brancher vos outils métier avec le function calling
Pour brancher un outil métier, décrivez-le en JSON Schema dans le champ tools. Le modèle renvoie alors un tool_calls avec les arguments, votre code exécute la fonction et renvoie le résultat dans un message de rôle tool qui reprend le tool_call_id. Le modèle obtient ainsi l'état réel d'une commande dans votre ERP au lieu d'inventer la réponse. Selon la documentation du function calling, le paramètre tool_choice accepte auto, la valeur par défaut, any pour forcer un appel d'outil et none pour l'interdire. La même page indique que les appels parallèles sont autorisés par défaut et se coupent avec parallel_tool_calls à false.
La boucle d'un appel d'outil avec l'API Mistral
Quatre étapes entre votre code et le modèle, sur l'exemple d'un suivi de commande
- Déclarer
Quels outils le modèle peut-il demander ?
Vous envoyez la question du client et la liste des fonctions, chacune avec un nom, une description et un schéma de paramètres.
tools = [statut_commande]
- Choisir
Faut-il un outil pour répondre ?
Le modèle renvoie un appel avec ses arguments, sans texte, et un finish_reason à tool_calls.
statut_commande(numero="CMD-1042")
- Exécuter
Que dit votre système ?
Votre code interroge l'ERP ou la base, puis ajoute le résultat dans un message de rôle tool avec le tool_call_id reçu.
statut : expédiée, transporteur : Colissimo
- Répondre
Comment le dire au client ?
Le modèle rédige la réponse finale à partir du résultat. C'est à cette étape qu'il peut ajouter ce que l'outil n'a pas dit.
Réponse à relire contre le résultat de l'outil
Sur notre essai, la question « Où en est ma commande CMD-1042 ? » a produit l'appel attendu, statut_commande avec {"numero": "CMD-1042"}. La réponse finale reprenait correctement le statut et le transporteur, puis ajoutait une phrase de son cru : « Vous devriez bientôt recevoir un email avec le numéro de suivi ». Notre outil n'avait rien dit d'un email. Sur un service client, cette phrase devient une promesse que personne n'a faite. Ajoutez une consigne système qui interdit d'affirmer ce qui ne figure pas dans le résultat de l'outil, et un test de non-régression sur ce cas.
Forcer l'outil a un revers que nous n'attendions pas. Nous avons envoyé un simple « Bonjour » avec tool_choice forcé, à any ou à required, une valeur que l'API accepte aussi. Sur cinq essais, mistral-small-2603 n'a appelé aucun outil. Les quatre essais plafonnés à 200 jetons se sont tous arrêtés sur finish_reason à "length", après une salutation chargée d'emojis qui tournait en boucle dans un cas. Le cinquième, lancé sans max_tokens, n'avait toujours pas répondu au bout de 60 secondes. Laissez auto par défaut et réservez any aux étapes où un appel d'outil est la seule issue valable.
Sur Tala, en rejouant de vrais tours d'appel d'un de nos agents, mistral-small-2603 a déclenché la transition attendue quand la condition était remplie et s'en est abstenu sinon, 58 fois sur 60. Sur l'agent d'un client, un rejeu du même type l'a vu appeler l'outil de fin d'appel 16 fois sur 20 quand l'appelant demandait un conseiller : un bon taux global ne dispense pas de tester chaque parcours. Ce modèle nous a aussi appris à valider chaque sortie. Du 23 juin au 19 juillet 2026, 13 appels servis par mistral-small-2603 ont reçu à la place du texte un jeton de contrôle brut, <|tool_calls_section_begin|>. Notre filtre le retirait avant la synthèse vocale, il ne restait rien à prononcer et l'agent se taisait. Le correctif vaut pour tous les fournisseurs : si une réponse ne contient ni texte exploitable ni appel d'outil, relancez la génération une fois et journalisez l'événement. Le reste de la boucle est détaillé dans notre article sur l'architecture d'un agent LLM.
Données, région et coût : les réglages avant la mise en production
Si vos requêtes contiennent des données personnelles, appelez l'endpoint régional api.eu.mistral.ai. La page sur l'inférence régionale précise que Mistral ne s'engage sur aucun lieu de traitement pour l'endpoint global api.mistral.ai. L'endpoint européen coûte 1,1 fois le tarif standard, soit 10 % de plus, sur les jetons d'entrée, de sortie et de cache. Selon la même page, son périmètre est aussi réduit : le function calling y est le seul outil pris en charge, et les Agents, le traitement par lots et l'API Files n'y sont pas disponibles. Sur un essai de chaque côté, l'endpoint européen a répondu à une question courte en un peu plus d'une demi-seconde, comme le global.
La rétention compte autant que la région. La rétention zéro (ZDR) n'existe que sur les offres payantes, pour les appels sans état, et chaque demande est examinée au cas par cas. Elle exclut les Agents, les fichiers de traitement par lots, les conversations, les bibliothèques et /v1/files. Une architecture qui confie ses documents à Mistral pour un RAG sort donc de ce périmètre. Gardez vos documents et vos vecteurs chez vous, et n'envoyez à chaque appel que le passage utile.
Le coût se calcule à partir du champ usage de chaque réponse. Il donne prompt_tokens, completion_tokens et, dans prompt_tokens_details, les cached_tokens facturés au tarif réduit, 0,015 $ par million pour Small 4 selon la grille officielle. Même sur un prompt de 43 jetons, l'API en a compté 16 en cache lors de nos appels. Multipliez ces volumes par une table de prix indexée sur l'identifiant exact du modèle. Nous l'avons appris à nos dépens : notre calcul de coût devinait le fournisseur d'après des mots-clés du nom du modèle. Aucun identifiant Mistral ne correspondait, et le coût de ces appels s'enregistrait à zéro sans la moindre erreur.
Pour fixer un ordre de grandeur, prenons un scénario illustratif : 10 000 tickets par mois, 800 jetons d'entrée et 200 de sortie par ticket, avec Mistral Small 4. L'entrée représente 8 millions de jetons à 0,15 $, soit 1,20 $, et la sortie 2 millions à 0,60 $, soit 1,20 $ aussi. Avec le supplément européen, la facture mensuelle reste sous 3 $. Le temps de développement et de test pèse bien plus que les jetons. Les traitements différés peuvent aussi passer par le traitement par lots, à moitié prix et jusqu'à un million de requêtes par lot, hors endpoint régional. Pour situer Mistral face aux autres éditeurs, consultez les prix des API LLM comparés. Pour suivre la dépense mois après mois, appuyez-vous sur notre méthode FinOps pour les coûts LLM.
Intégrer l'API Mistral en interne ou avec une agence
Un développeur à l'aise avec HTTP intègre l'API Mistral seul en une journée, et un accompagnement se justifie ensuite sur le socle de production et sur les tests qui protègent chaque changement de modèle. Le travail long consiste à vérifier le comportement du modèle sur vos données réelles plutôt que sur trois exemples de démonstration. Sur Tala, un modèle plus gros, pressenti sur la foi d'un banc de développement, n'a prononcé le message d'accueil dans aucun des 20 tirages rejoués sur le contexte réel de production, avec ses 12 outils. Depuis, nous rejouons le vrai prompt de production une vingtaine de fois avant tout changement de modèle, et nous comparons les réponses à celles du modèle en service.
Nous conseillons de garder en interne ce qui touche à votre métier : les prompts, les schémas de sortie et les jeux de test, parce que ce sont eux qui bougent chaque semaine. L'accompagnement se justifie sur le socle technique : relances, journalisation, suivi des coûts, choix de l'endpoint et revue des données envoyées. Il se justifie aussi sur la batterie de tests qui protège chaque changement de modèle. C'est ce socle que nous livrons sur nos projets d'intégration, avant de rendre la main à l'équipe du client sur ses prompts. Votre intégration tourne déjà, avec des réponses coupées, des erreurs 429 en série ou une facture inexpliquée ? Vous pouvez contacter Noxcod avec un extrait de vos journaux, c'est souvent là que se lit la cause.
Questions fréquentes sur l'API Mistral AI
L'API Mistral AI est-elle gratuite ?
Oui pour démarrer : le mode gratuit est actif par défaut, sans carte bancaire, avec les limites de débit les plus basses, prévues pour le prototypage selon l'aide de Mistral. Avant d'y faire passer des données réelles, notez qu'en mode gratuit Mistral indique que les entrées et les sorties peuvent servir à l'entraînement, sauf retrait dans le menu Privacy. La rétention zéro n'est proposée que sur les offres payantes, sur demande. Pour un service en production, passez au paiement à l'usage dès le départ.
Quelle différence entre mistral-small-latest et mistral-small-2603 ?
mistral-small-latest est un alias qui pointe vers la version courante. Le 5 novembre 2026, il désignait mistral-small-2603, donc Mistral Small 4. L'alias suit les nouvelles versions sans prévenir votre code, au risque d'un changement de comportement ou de prix, et sur nos appels le champ model de la réponse ne renvoyait que l'alias. L'identifiant daté reste stable jusqu'à son retrait, annoncé six mois à l'avance en disponibilité générale. Gardez l'alias pour prototyper, l'identifiant daté pour la production.
Les données envoyées à l'API Mistral restent-elles en Europe ?
Seulement si vous appelez l'endpoint régional api.eu.mistral.ai. Pour l'endpoint global api.mistral.ai, Mistral ne s'engage sur aucun lieu de traitement. L'endpoint européen coûte 10 % de plus et ne propose ni Agents, ni traitement par lots, ni API Files. Si vous traitez des données personnelles, vérifiez aussi l'option d'entraînement de votre organisation dans le menu Privacy, et demandez la rétention zéro si vous êtes sur une offre payante.
Pourquoi l'API Mistral renvoie-t-elle une erreur 429 ?
Le 429 signale un dépassement de limite de débit : requêtes par seconde, jetons par minute ou jetons par mois. Les limites montent par paliers selon le montant déjà facturé, au-delà de 20 €, 100 € puis 500 €, et l'achat de crédits ne les relève pas. Dans votre code, passez une RetryConfig au SDK pour relancer avec un délai croissant, et lisez les en-têtes x-ratelimit-remaining pour ralentir avant d'atteindre la limite.
Existe-t-il un SDK officiel en JavaScript ou TypeScript ?
Oui, le paquet @mistralai/mistralai, en version 3.5.0 depuis le 1er novembre 2026, téléchargé environ 6,4 millions de fois sur la semaine précédant notre relevé du 5 novembre 2026. Son README officiel précise qu'il est publié en module ES uniquement : une application CommonJS doit passer par un import dynamique. Le client se crée avec new Mistral({ apiKey, serverURL }), où serverURL permet de viser l'endpoint européen, et il expose chat.complete comme le SDK Python.