Nouveau Inscription gratuite, 10 appels offerts. Jusqu'à 1 $, sans carte.

Bibliothèque de prompts

Gardez vos prompts dans votre espace de travail plutôt que dans votre code : versionnés, étiquetés et appelés par ID depuis n’importe quel SDK OpenAI. Déplacer une étiquette change ce que reçoit votre code dès la requête suivante, sans redéployer.

Appeler un prompt

Utilisez le point de terminaison habituel /v1/chat/completions, /v1/responses ou /v1/messages et ajoutez prompt_id et prompt_variables au corps de la requête. Les SDK exigent model et messages : indiquez n’importe quel nom de modèle et un message utilisateur vide. Dans les SDK OpenAI et Anthropic, les champs supplémentaires vont dans extra_body.

import os
from openai import OpenAI

client = OpenAI(base_url="https://synthorai.io/v1", api_key=os.environ["SYNTHORAI_API_KEY"])

reply = client.chat.completions.create(
    model="any",  # the version's model is used
    messages=[{"role": "user", "content": ""}],  # required by the SDK; dropped
    extra_body={
        "prompt_id": "support-reply",
        "prompt_variables": {
            "product": "Acme Cloud",
            "customer_message": "My invoice shows two charges.",
        },
    },
)
print(reply.choices[0].message.content)

En HTTP brut, les champs se placent au premier niveau du corps. Cet appel demande la version vers laquelle pointe l’étiquette staging :

curl https://synthorai.io/v1/chat/completions \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "any",
    "messages": [],
    "prompt_id": "support-reply",
    "prompt_label": "staging",
    "prompt_variables": {"product": "Acme Cloud", "customer_message": "My invoice shows two charges."}
  }'

Champs

Champ Type Rôle
prompt_id string L’ID du prompt dans votre espace de travail, tel qu’il apparaît sur la page Prompts.
prompt_variables object Les valeurs des variables {{name}} de la version : chaînes, nombres ou booléens, insérés comme texte. Une variable omise prend la valeur par défaut de la version ; sans valeur par défaut, l’appel échoue.
prompt_version integer Fige une version. Sans ce champ, l’appel reçoit la version vers laquelle pointe l’étiquette production.
prompt_label string Appelle la version vers laquelle pointe une autre étiquette, comme staging. Envoyez une version ou une étiquette, pas les deux.

Ce que devient la requête

  • Les messages de la version d’abord, les vôtres ensuite. Ce sont vos propres messages qui font avancer une conversation : les tours précédents, les appels d’outils et leurs résultats sont conservés tels que vous les envoyez. Seul le message utilisateur vide, celui qu’exigent les SDK, est retiré.
  • Le modèle de la version remplace celui de la requête. Une version sans modèle garde le vôtre.
  • Vos paramètres l’emportent. La temperature, max_tokens, top_p et le mode JSON de la version ne s’appliquent que si votre requête ne fixe pas le même paramètre.
  • Les quatre champs prompt_* s’arrêtent à la passerelle. Le fournisseur reçoit une requête ordinaire.
  • Sur /v1/responses, les messages vont dans input (un input sous forme de chaîne est votre tour utilisateur), max_tokens devient max_output_tokens et le mode JSON devient text.format.

Sur /v1/messages

Les quatre mêmes champs fonctionnent avec le SDK Anthropic. Le texte système de la version précède votre propre system, ses messages précèdent les vôtres, et temperature, top_p et max_tokens s’appliquent là où votre requête ne les définit pas. Le mode JSON n’a pas de champ sur ce point de terminaison et n’est pas transmis.

import os
from anthropic import Anthropic

client = Anthropic(base_url="https://synthorai.io", api_key=os.environ["SYNTHORAI_API_KEY"])

reply = client.messages.create(
    model="any",  # the version's model is used
    max_tokens=1024,
    messages=[{"role": "user", "content": ""}],  # required by the SDK; dropped
    extra_body={
        "prompt_id": "support-reply",
        "prompt_variables": {
            "product": "Acme Cloud",
            "customer_message": "My invoice shows two charges.",
        },
    },
)
print(reply.content[0].text)

Appels d’outils et conversations à plusieurs tours

Envoyez tools et la conversation jusqu’ici exactement comme sans prompt de bibliothèque. La version fournit le prompt système et le message d’ouverture ; vos messages portent le reste de la conversation, y compris les appels d’outils du modèle et vos résultats d’outils.

# Round 2 of a tool loop: send the conversation so far, as without a prompt.
# The gateway puts the version's messages first and these after them.
reply = client.chat.completions.create(
    model="any",
    tools=tools,
    messages=[
        {"role": "user", "content": ""},  # the SDK placeholder, dropped
        first.choices[0].message,           # the model's tool call
        {"role": "tool", "tool_call_id": call.id, "content": lookup_invoice(call)},
    ],
    extra_body={"prompt_id": "support-reply", "prompt_variables": variables},
)

Outils et schéma de sortie dans une version

Une version peut contenir des outils de type fonction, un choix d’outil et un schéma JSON pour la réponse ; ils sont écrits au format du point de terminaison appelé. Les outils envoyés par votre requête s’ajoutent après ceux de la version, et un outil du même nom remplace celui de la version. Votre propre tool_choice et votre format de réponse l’emportent.

Partials

Un partial est un bloc de texte conservé une seule fois et inclus dans des prompts avec {{>id}}. Quand vous enregistrez une version d’un prompt, chaque inclusion est figée sur la version la plus récente du partial, affichée sous la forme {{>id@4}} : une version enregistrée ne change donc pas quand le partial change. La page du prompt signale qu’une version plus récente du partial existe et propose la mise à jour, qui enregistre une nouvelle version du prompt. Les variables d’un partial sont remplies par les prompt_variables de l’appel. Un partial ne s’appelle pas seul, et un partial inclus dans des versions enregistrées ne peut pas être supprimé.

Versions et étiquettes

Chaque enregistrement crée la version suivante, et une version enregistrée ne change jamais. production, staging et development existent sur chaque prompt ; vous pouvez ajouter vos propres étiquettes. Faites pointer production vers une version pour la mettre en ligne, et vers l’ancienne pour revenir en arrière. Votre code appelle toujours le même ID.

Un déplacement d’étiquette ou une suppression s’applique aux appels en 10 secondes environ. Déplacer des étiquettes et supprimer des prompts demande un rôle d’administrateur ou de propriétaire de l’espace de travail.

Essayer un brouillon

Dans l’éditeur de la page Prompts, le brouillon s’écrit à gauche et s’essaie à droite. Donnez une valeur à chaque variable et cliquez sur Run : le brouillon est rendu puis envoyé à son modèle, et la réponse s’affiche avec sa latence et son coût. L’appel est facturé et journalisé comme un appel du Playground, et rien du brouillon n’est conservé tant que vous n’avez pas enregistré la version. Show the request affiche la requête rendue pour chaque endpoint, sans appeler de modèle.

Tester une version avant de la publier

Les Tests d’un prompt contiennent des jeux de tests : des lignes de valeurs pour ses variables, avec en option un message utilisateur et une réponse attendue, et les contrôles qu’une réponse doit passer (contient, correspond à un motif, égale la réponse attendue, JSON valide, respecte le schéma de sortie, limite de latence ou de coût, ou un modèle qui juge selon un critère que vous rédigez). Une exécution appelle, pour chaque ligne, la version choisie et celle à laquelle vous la comparez, affiche les deux réponses côte à côte et indique combien de lignes ont réussi, ainsi que le coût et la latence de chacune. Chaque appel est facturé et journalisé comme un appel du Playground, sous une seule trace par exécution. Quand vous déplacez une étiquette, la boîte de dialogue affiche la dernière exécution de la version ; elle éclaire la décision sans la bloquer. Les jeux de tests et les réponses d’une exécution sont stockés chiffrés ; les réponses sont conservées 30 jours.

Déploiement progressif

Une étiquette peut envoyer une part de ses appels vers une autre version : « production : v6, v7 à 10 % ». La version reçue dépend de l’identifiant de session, à défaut de l’utilisateur final, à défaut de la requête : une conversation reste donc sur la même version. X-Synthorai-Prompt-Version indique laquelle a répondu, et la page Prompts affiche les deux côte à côte. Un administrateur modifie la part, déplace l’étiquette vers la version candidate ou arrête le déploiement ; un appel qui fixe prompt_version n’en fait jamais partie.

Webhooks de changement

Les administrateurs peuvent ajouter jusqu’à trois adresses sur la page Prompts ; elles reçoivent un POST quand un prompt est créé, reçoit une version, voit une étiquette déplacée ou un déploiement modifié, ou est supprimé. Chaque requête est signée : X-Synthorai-Signature: t=…,v1=…, le HMAC-SHA256 de l’horodatage, d’un point et du corps brut, avec le secret affiché une seule fois à l’ajout de l’adresse. Le texte d’une version n’est envoyé que si vous l’activez pour l’adresse. Une livraison en échec est retentée trois fois sur une demi-heure environ ; après cinq événements abandonnés de suite, l’adresse est désactivée jusqu’à ce que vous la réactiviez.

POST /hooks/prompts
X-Synthorai-Event: prompt.label_moved
X-Synthorai-Signature: t=1791140000,v1=5f2c…

{
  "type": "prompt.label_moved",
  "created_at": "2026-10-05T03:12:44Z",
  "prompt": "support-reply",
  "kind": "prompt",
  "label": "production",
  "from": 6,
  "version": 7,
  "by": 42
}

# Verify: hex(HMAC-SHA256(secret, "1791140000" + "." + raw_body)) == v1

Import, export et prompts stockés d’OpenAI

Nouveau prompt › Importer lit un corps de requête Chat Completions ou Responses collé, ou un fichier .prompt de LiteLLM, et en fait une première version : messages, modèle, paramètres, outils et schéma de sortie. Exporter télécharge un prompt avec toutes ses versions dans un seul fichier JSON, qui s’importe de la même façon, et Copier vers un espace de travail le copie dans un autre espace dont vous êtes membre. Les prompts stockés d’OpenAI cessent de fonctionner le 2026-11-30 et ne peuvent pas être relus : recréez le prompt ici sous son identifiant pmpt_…, et une requête /v1/responses qui envoie prompt avec cet identifiant est servie par la bibliothèque sans changer de code. Sa version, quand c’est un nombre, choisit cette version de la bibliothèque ; sans elle, l’appel reçoit production.

Rendre sans appeler de modèle

POST /v1/prompts/{id}/render renvoie la requête qu’un appel enverrait, ainsi que la version retenue, sans appeler de modèle. Envoyez prompt_variables, éventuellement prompt_version ou prompt_label, et format : chat (par défaut), responses ou messages. L’appel n’est pas facturé et n’apparaît pas dans Logs ; il compte dans la limite de débit de la clé. Servez-vous-en pour vérifier ce qu’une version envoie, ou pour appeler un point de terminaison que les champs prompt_* n’atteignent pas.

curl https://synthorai.io/v1/prompts/support-reply/render \
  -H "Authorization: Bearer $SYNTHORAI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "format": "chat",
    "prompt_variables": {"product": "Acme Cloud", "customer_message": "My invoice shows two charges."}
  }'

{
  "prompt_id": "support-reply",
  "version": 6,
  "format": "chat",
  "request": {
    "model": "claude-sonnet-5",
    "temperature": 0.3,
    "messages": [
      {"role": "system", "content": "You answer billing mail for Acme Cloud."},
      {"role": "user", "content": "My invoice shows two charges."}
    ]
  }
}

En-têtes de réponse

X-Synthorai-Prompt-Version indique quelle version a répondu, ce qu’un appel par étiquette ne peut pas savoir autrement. Si la bibliothèque est illisible, la passerelle répond avec la dernière copie lue, pendant 24 heures au plus, et ajoute X-Synthorai-Prompt-Stale: 1 ; une étiquette déplacée entre-temps prend effet dès que la bibliothèque redevient lisible.

Erreurs

Elles sont renvoyées avant tout appel de modèle et ne sont donc jamais facturées. Elles suivent le format d’erreur du point de terminaison appelé.

Statut Code Quand
400 prompt_variable_missing Une variable n’a ni valeur ni valeur par défaut. Le message la nomme.
400 prompt_invalid Un champ est mal formé : version et étiquette à la fois, objet ou liste comme valeur de variable, plus de 64 variables ou plus de 64 Ko au total. Un prompt rendu de plus de 1 Mo est refusé de la même façon. Il en va de même d'un appel qui ne laisse rien à envoyer : tous les messages de la version sont vides une fois rendus et la requête n'en apporte aucun.
404 prompt_not_found Aucun prompt avec cet ID dans l’espace de travail de la clé, aucune version de ce numéro, ou l’étiquette ne pointe encore vers aucune version.
409 prompt_unreadable La version enregistrée n’est plus lisible. Enregistrez-en une nouvelle.
503 prompt_unavailable La bibliothèque est momentanément illisible et la passerelle n’a pas de copie récente de ce prompt. Réessayez.

Statistiques par version

Chaque appel est enregistré avec le prompt et la version utilisés. La page Prompts affiche, par version, les appels, les erreurs, la dépense, les tokens, la latence et le délai avant le premier token, sur les 7, 30 ou 90 derniers jours ; le nombre d’appels d’une version ouvre ces appels dans Logs. Faites tourner une nouvelle version sous staging à côté de production et comparez-les avant de déplacer production.

Dans Logs, filtrez avec prompt = support-reply et prompt_version = 7 ; le détail d’une requête indique son prompt et sa version. Les enregistrements exportés les portent aussi : run.prompt_id et run.prompt_version dans les fichiers et les webhooks, gen_ai.prompt.name et gen_ai.prompt.version sur les spans OTLP.

Voir aussi : Prompts · Chat Completions · Responses API