L'API Messages : vos premiers appels réels
La fenêtre de chat, c'est là que vous avez appris Claude ; l'APIAPIApplication Programming Interface : une interface standardisée qui permet aux applications de communiquer et d'échanger des données sans connaître leur fonctionnement interne respectif.Voir la définition complète → Messages, c'est là que vous le mettez au travail. Même modèle, sans UI. Vous envoyez une requête structurée, vous récupérez une sortie structurée, et vous le faites depuis votre propre code, à votre rythme, dans votre propre produit.
Vous avez déjà fait un « premier appel API » générique. Passons donc les préliminaires et allons droit à ce qui est spécifique à Claude : la forme de la requête, pourquoi le prompt `system` se trouve là où il est, et comment streamer les réponses longues sans laisser vos utilisateurs devant un écran vide.
La forme d'une requête Claude
Chaque appel à l'API Messages se construit à partir de quelques éléments obligatoires :
- `model` : quel Claude vous voulez (une variante Sonnet, Opus ou Haiku). Sonnet est le cheval de trait du quotidien, Opus le plus capable pour le raisonnement difficile, Haiku le rapide et peu coûteux.
- `max_tokens` : le plafond du nombre de tokenstokensUn token est l'unité de base de texte que traitent les modèles de langage : le plus souvent un fragment de mot, un mot entier ou un signe de ponctuation, plutôt qu'un simple caractère.Voir la définition complète → que Claude peut générer dans sa réponse. C'est une borne supérieure, pas une cible. Cela n'allonge pas la réponse ; cela la limite.
- `messages` : la conversation, sous forme de liste de tours. Chaque tour a un
role(userouassistant) et uncontent. - `system` (optionnel mais important) : un paramètre de premier niveau, séparé de la liste de messages. C'est là que vont le rôle, le ton et les règles.
Ce dernier point est la première chose qui fait trébucher ceux qui viennent d'autres API. Dans l'API Messages, le prompt system n'est pas un message avec role: "system". C'est un champ à part entière de la requête. Les modèles Anthropic sont entraînés autour de cette structure, et garder les instructions permanentes dans system plutôt que de les entasser dans un tour user améliore de façon mesurable la fiabilité avec laquelle Claude les suit.
Un token, pour rappel, est le morceau de texte que le modèle lit et écrit (environ quelques caractères). Vous payez par token entrant et par token sortant, donc max_tokens est aussi un levier de mamaUtiliser un logiciel pour automatiser les tâches et campagnes marketing répétitives, afin de personnaliser à grande échelle sur des canaux comme l'email, le web et le social.Voir la définition complète →îtrise des coûts.
Votre premier appel réel
Voici un appel complet et exécutable. Installez d'abord le SDK avec pip install anthropic et définissez votre clé dans la variable d'environnement ANTHROPIC_API_KEY.
import anthropic
client = anthropic.Anthropic() # lit ANTHROPIC_API_KEY depuis l'environnement
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
system="You are a precise release-notes editor. Reply in tight bullet points.",
messages=[
{
"role": "user",
"content": "Summarize: we shipped SSO, fixed a billing bug, and removed the legacy export.",
}
],
)
print(response.content[0].text)Regardons ce qui revient. La réponse est un objet, pas une chaîne brute. Son content est une liste de blocs de contenu, parce qu'une même réponse peut contenir plusieurs types de blocs (du texte, et plus tard des demandes d'usage d'outils). Pour une réponse en texte simple, vous lisez response.content[0].text. Vous récupérez aussi response.usage avec le décompte des tokens en entrée et en sortie, et response.stop_reason, qui vous dit *pourquoi* Claude s'est arrarrL'Annual Recurring Revenue (ARR) est le revenu normalisé et prévisible qu'une entreprise par abonnement attend de ses contrats actifs sur une année.Voir la définition complète →êté : end_turn signifie qu'il a terminé naturellement, max_tokens qu'il a atteint votre plafond et a été coupé. Vérifiez toujours stop_reason en production. Une réponse tronquée que vous traitez comme complète est un bug silencieux.
Vérifiez les noms de modèles et les paramètres à jour dans la référence de l'API Messages officielle avant de mettre en production, car les identifiants de modèles évoluent au fil du temps.
La conversation, c'est à vous de la porter
L'API est stateless. Claude ne se souvient pas de votre dernier appel. C'est *vous* qui portez la conversation en ajoutant chaque tour à la liste messages et en renvoyant l'ensemble.
Un échange multi-tours n'est qu'une liste alternée :
messages = [
{"role": "user", "content": "What's a good index for a time-series table?"},
{"role": "assistant", "content": "Start with a composite index on (device_id, ts)."},
{"role": "user", "content": "Why that order and not (ts, device_id)?"},
]Deux règles à intégrer. D'abord, les tours doivent alterner user et assistant ; vous ne pouvez pas envoyer deux tours user d'affilée. Ensuite, vous pouvez amorcer la réponse de l'assistant en terminant votre liste messages sur un tour assistant avec un contenu partiel. Claude continuera exactement là où vous l'avez laissé. Cette astuce, appelée prefilling, est réellement utile : préremplissez avec { pour forcer une sortie JSON, ou avec Here is the answer in three bullets: pour verrouiller le format. C'est un levier propre à Claude que l'interface de chat ne vous expose jamais.
Le streaming pour les réponses longues
Quand Claude rédige une longue réponse, vous ne voulez pas attendre la fin avant d'afficher quoi que ce soit. Le streaming renvoie la réponse par morceaux à mesure qu'ils sont générés, de sorte que le texte apparaît mot à mot, comme dans l'application Claude.
Changez un argument et itérez :
with client.messages.stream(
model="claude-sonnet-4-5",
max_tokens=2048,
system="You are a technical writer. Be concrete.",
messages=[{"role": "user", "content": "Explain database connection pooling."}],
) as stream:
for text in stream.text_stream:
print(text, end="", flush=True)
final = stream.get_final_message()
print("\n\nTokens used:", final.usage.output_tokens)La méthode stream() renvoie un context manager (le bloc with), qui garantit que la connexion se ferme proprement même si quelque chose échoue en cours de stream. L'utilitaire text_stream vous donne uniquement les deltas de texte, ce que vous voulez généralement pour une UI. Quand la boucle se termine, get_final_message() réassemble la réponse complète pour que vous disposiez tout de même de usage et stop_reason.
Streamez dès qu'une réponse peut être longue ou dès qu'un humain la regarde arriver. Pour de courts jobs en arrière-plan où rien n'attend la sortie, l'appel create() classique est plus simple et tout aussi rapide au total.
Anthropic API Crash Course
Ce qui fait que c'est Claude, et pas juste une API
Quelques comportements méritent d'être connus avant de construire dessus.
Les prompts system ont un poids réel. De par la place de system dans la requête, les instructions persistantes qui y figurent sont suivies plus régulièrement que le même texte enfoui dans un message user. Mettez ce qui est durable (rôle, format de sortie, contraintes dures) dans system, et la tâche propre à chaque requête dans le tour user.
Le contexte long est une fonctionnalité, pas seulement un chiffre. Les modèles Claude prennent en charge de grandes fenêtres de contexte, assez grandes pour y déposer des documents entiers, de longues transcriptions ou une portion conséquente d'une base de code. En pratique, cela veut dire que vous pouvez souvent passer le matériau source directement au lieu de construire du retrieval pour cela. Les tarifs et la taille exacte des fenêtres évoluent : confirmez les chiffres actuels dans la documentation plutôt que de les mémoriser.
La même API alimente les outils et les agents. Tout ce que vous construirez ensuite (l'usage d'outils, les connecteurs exposés par les applications Claude, les serveurs MCP et le Claude Agent SDK) repose sur cet appel messages.create exact. L'usage d'outils, ce ne sont que des types de blocs de contenu supplémentaires qui circulent dans la même forme de requête et de réponse que vous comprenez déjà. Maîtrisez bien cette surface et le reste du parcours Claude devient incrémental.
Vérification des acquis
1. Dans l'API Messages, comment faut-il fournir les instructions permanentes sur le rôle, le ton et les règles ?
2. Que contrôle réellement le paramètre max_tokens ?
3. D'après la leçon, quelle variante de Claude est décrite comme le cheval de trait du quotidien ?
4. Sélectionnez TOUTES les affirmations vraies concernant les éléments obligatoires/importants d'une requête à l'API Messages de Claude.
Sélectionnez toutes les réponses correctes.
5. Sélectionnez TOUTES les affirmations correctes sur les tokens et le coût dans l'API Messages.
Sélectionnez toutes les réponses correctes.
Lire les erreurs et être un bon client
Les appels réels échouent parfois. Les deux que vous rencontrerez en premier :
- `401` (authentification) : votre
ANTHROPIC_API_KEYest absente, erronée, ou n'est pas chargée dans l'environnement. Affichez la variable (pas la clé elle-même) pour confirmer que votre processus la voit. - `429` (rate limit) et `529` (surcharge) : vous envoyez trop vite, ou le service est brièvement saturé. Le remède est le même : ralentir et réessayer.
Le SDK réessaie déjà certains échecs avec un backoff exponentiel, mais vous devez tout de même encapsuler vos appels et gérer les cas où le SDK abandonne :
import anthropic
client = anthropic.Anthropic()
try:
response = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=512,
messages=[{"role": "user", "content": "One sentence on idempotency."}],
)
print(response.content[0].text)
except anthropic.RateLimitError:
print("Rate limited. Slow down and retry with backoff.")
except anthropic.APIStatusError as exc:
print(f"API error {exc.status_code}: {exc.message}")Attrapez RateLimitError spécifiquement quand vous voulez un backoff sur mesure, et repliez-vous sur APIStatusError pour tout le reste avec un statut non réussi. C'est la différence entre un script qui meurt au premier accroc et un service qui survit à une après-midi chargée.
Où garder vos clés
Une note opérationnelle, parce que ça pique dès le premier jour. Votre clé API est un secret rattaché à une facturation. Ne la codez jamais en dur dans le source, ne la committez jamais, ne l'expédiez jamais dans une application navigateur où les utilisateurs peuvent la lire. Gardez-la dans une variable d'environnement ou un gestionnaire de secrets, et laissez le SDK la lire automatiquement. Le constructeur anthropic.Anthropic() récupère ANTHROPIC_API_KEY sans argument, et c'est exactement pour cela que chaque extrait ci-dessus la laisse implicite. Si vous avez besoin d'appels côté navigateur, faites-les passer par un petit backend qui détient la clé, jamais par le client.
Vous pouvez générer et faire tourner vos clés dans la Console Anthropic, et le source du SDK se trouve sur github.com/anthropics si vous voulez lire comment les retries et le streaming sont implémentés.
Points clés
- Mettez les instructions permanentes dans le paramètre `system` de premier niveau, pas dans un message user. Claude est entraîné autour de cette structure et la suit plus fidèlement ; réservez les tours user à la tâche elle-même.
- Vérifiez toujours `stop_reason` et `usage`. Une réponse coupée à
max_tokensa l'air complète sans l'être, et le décompte de tokens est votre signal de coût et de budget. - Portez la conversation vous-même. L'API est stateless : ajoutez chaque tour user et assistant à la liste
messages, gardez-les strictement alternés, et utilisez le prefilling pour verrouiller le format de sortie quand vous en avez besoin. - Streamez dès qu'un humain attend. Utilisez
messages.stream()et l'utilitairetext_streampour les réponses longues ou destinées à l'utilisateur, etcreate()pour les jobs silencieux en arrière-plan. - Cet appel est le socle de tout ce qui suit. L'usage d'outils, les connecteurs, MCPMCPUn standard ouvert qui permet aux assistants IA de se connecter aux outils et données de l'entreprise de façon cohérente et gouvernée, sans intégration sur mesure à chaque fois.Voir la définition complète → et l'Agent SDK passent tous par la même forme de requête et de réponse
messages.createque vous venez d'apprendre.
À faire, tiré de cette leçon
Ces actions sont compilées dans le plan d'action du rôle.
- Placez les instructions permanentes dans le paramètre `system` de premier niveau de l'API
- Vérifiez systématiquement stop_reason et usage dans chaque réponse de l'API
- Streamez les réponses dès qu'un humain attend l'output