Crédit de repli
Évitez de payer deux fois le coût de la mise en cache des prompts lorsque vous relancez une requête refusée sur un autre modèle.
Les caches de prompts sont propres à chaque modèle. Lorsqu'un modèle décline une requête et que vous la relancez sur un autre modèle, le préfixe de conversation déjà mis en cache pour le premier modèle doit être écrit de zéro dans le cache du nouveau modèle. Les écritures en cache coûtent plus cher que les lectures en cache. Le « fallback credit » (crédit de repli) supprime ce coût supplémentaire. Le refus transporte un jeton de crédit, vous renvoyez ce jeton lors de la nouvelle tentative, et celle-ci est facturée comme si la conversation s'était déroulée sur le nouveau modèle depuis le début.
Vous n'avez besoin de cette page que si vous construisez vous-même la nouvelle tentative : via HTTP brut ou avec une logique de relance personnalisée. Le repli côté serveur et le middleware du SDK appliquent automatiquement le crédit de repli. Si vous utilisez l'un ou l'autre, ignorez cette page.
Refus et repli traite de la détection des refus et du choix d'une approche de repli. Mise en cache des prompts explique les lectures en cache et les écritures en cache si ces termes sont nouveaux pour vous.
Le flux de base
Activez la fonctionnalité avec l'en-tête bêta
Envoyez la requête susceptible d'être refusée avec l'en-tête
anthropic-beta: fallback-credit-2026-07-01. L'en-têteserver-side-fallback-2026-07-01donne également accès aux mêmes champs, et l'en-tête antérieurfallback-credit-2026-06-01reste accepté et donne accès aux mêmes champs.Lisez deux champs dans le refus
Lors d'un refus,
stop_detailsinclut deux champs :fallback_credit_token: une chaîne opaque qui représente le crédit.fallback_has_prefill_claim: un booléen qui vous indique quelle forme de corps de requête utiliser pour la nouvelle tentative.
Les deux valent
nulllorsqu'aucun crédit n'est disponible pour le refus.Construisez la nouvelle tentative
Partez du corps de la requête refusée. Définissez
modelsur le modèle de repli et ajoutez le jeton en tant que paramètre de premier niveaufallback_credit_token. Choisissez la forme du corps dans le tableau suivant.Envoyez la nouvelle tentative avec le même en-tête
Envoyez la nouvelle tentative avec le même en-tête bêta
fallback-credit-2026-07-01. La nouvelle tentative a besoin de cet en-tête pour utiliser le jeton.
Le champ fallback_has_prefill_claim vous indique si la nouvelle tentative peut poursuivre la sortie partielle du modèle ayant refusé au lieu de repartir de zéro :
fallback_has_prefill_claim | Corps de la nouvelle tentative |
|---|---|
true | Le corps de la requête refusée, inchangé, plus un message assistant ajouté à la fin dont le content reprend le content de la réponse refusée. Le modèle de la nouvelle tentative poursuit la réponse là où le modèle ayant refusé s'est arrêté, et les appels d'outils serveur terminés ne sont pas réexécutés. |
false | Le corps de la requête refusée, inchangé. |
Exemple
L'exemple suivant effectue une requête susceptible d'être refusée et utilise le jeton de crédit lors d'une nouvelle tentative sur Claude Opus 4.8. Lorsqu'une tentative de relance est rejetée, l'exemple descend l'échelle de rejet : la séquence de formes de relance progressivement plus simples décrite dans Lorsqu'une nouvelle tentative est rejetée.
client = Anthropic()
request = {
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}],
}
def send(model: str, body: dict[str, object]) -> BetaMessage:
return client.beta.messages.create(
model=model, betas=["fallback-credit-2026-07-01"], **body
)
response = send("claude-fable-5", request)
if (
response.stop_reason == "refusal"
and (details := response.stop_details)
and (token := details.fallback_credit_token)
):
exact_body = request | {"fallback_credit_token": token}
# Privilégier la forme de continuation sauf si le claim vaut False
if details.fallback_has_prefill_claim is not False:
echoed = [block.model_dump() for block in response.content]
match echoed:
case [*_, {"type": "text"} as final_block]:
final_block["text"] = final_block["text"].rstrip()
attempt = exact_body | {
"messages": [
*request["messages"],
{"role": "assistant", "content": echoed},
]
}
else:
attempt = exact_body
try:
response = send("claude-opus-4-8", attempt)
except BadRequestError as error:
if "redemption temporarily unavailable" in error.message:
raise # Transient: retry with the token within its five-minute window
try:
# Revenir au corps inchangé, toujours avec le jeton
response = send("claude-opus-4-8", exact_body)
except BadRequestError as retry_error:
if "redemption temporarily unavailable" in retry_error.message:
raise # Transient: retry with the token within its five-minute window
# Le jeton lui-même a été rejeté : l'abandonner et réessayer sans.
response = send("claude-opus-4-8", request)
print(json.dumps({"stop_reason": response.stop_reason, "model": response.model}))Où cela fonctionne
Le crédit de repli est en bêta sur la Claude API, Amazon Bedrock, Claude Platform sur AWS, Google Cloud et Microsoft Foundry. Les refus dans les Message Batches ne génèrent pas de jetons de crédit, et l'utilisation ne s'applique qu'aux requêtes directes à l'API Messages : un jeton transmis dans une requête par lot est accepté mais ignoré.
Le modèle de la nouvelle tentative doit être l'une des cibles de repli autorisées du modèle ayant refusé. Pour Claude Fable 5.1 et Claude Fable 5, il s'agit de Claude Opus 4.8 (claude-opus-4-8) et de Claude Opus 5 (claude-opus-5).
Sur la Claude API et Claude Platform sur AWS, la liste des cibles est publiée sous allowed_fallback_models dans l'entrée de chaque modèle de l'API Models lorsque l'en-tête bêta server-side-fallback-2026-07-01 est défini. La liste n'est pas encore visible avec l'en-tête fallback-credit-* seul. Elle n'est pas exposée sur Amazon Bedrock, Google Cloud ni Microsoft Foundry.
Vérifier que le crédit a été appliqué
Le remboursement est visible dans le champ usage de la nouvelle tentative. Par rapport à ce que la même requête indiquerait sans le jeton, cache_creation_input_tokens est plus bas et cache_read_input_tokens est plus élevé du même montant. Un décalage nul signifie que le jeton a été honoré mais qu'il n'y avait rien à refacturer, par exemple parce que le cache du modèle de la nouvelle tentative était déjà chaud.
Lorsqu'une nouvelle tentative est rejetée
La plupart des nouvelles tentatives utilisent le crédit dès le premier essai. Lorsque ce n'est pas le cas, l'API renvoie une erreur 400 qui vous indique quoi essayer ensuite.
Continuation rejetée : renvoyez le corps inchangé
Si la nouvelle tentative qui ajoute le message assistant est rejetée avec une erreur 400, renvoyez le corps de la requête refusée inchangé, toujours avec le jeton.
Jeton rejeté : supprimez le jeton
Si le corps inchangé est également rejeté avec une erreur 400 dont le message mentionne
fallback_credit_token, relancez sans le jeton. Le crédit est perdu, mais la nouvelle tentative elle-même aboutit.
Ce rejet est transitoire, et non un verdict sur la forme de votre nouvelle tentative. Relancez la même requête, avec le même jeton, dans la fenêtre de cinq minutes du jeton. Ne passez pas à l'étape suivante de l'échelle.
Référence
Les sections suivantes couvrent les cas limites et les règles complètes d'utilisation du crédit. La plupart des intégrations n'en ont pas besoin.
L'utilisation du crédit compare la nouvelle tentative à la requête refusée. Chaque champ qui façonne le prompt doit correspondre exactement. Les champs qui ne façonnent pas le prompt peuvent changer lors de la nouvelle tentative.
| Règle | Champs |
|---|---|
| Doivent correspondre exactement | system, messages, tools, tool_choice, thinking et cache_control, plus output_config, mcp_servers, context_management et container lorsque vous les utilisez |
| Peuvent changer lors de la nouvelle tentative | model, max_tokens, stop_sequences, temperature, top_p, top_k, stream, metadata et service_tier |
La forme de continuation (fallback_has_prefill_claim: true) est la seule exception à la correspondance de messages : elle ajoute exactement un message assistant à la fin de messages.
Ne retirez pas les blocs thinking ou redacted_thinking des tours précédents lors de la nouvelle tentative, même si une relance simple sans jeton les retire habituellement. Le corps doit correspondre à la requête refusée, et le serveur gère lui-même ces blocs.
Envoyez les mêmes en-têtes anthropic-beta sur la nouvelle tentative que sur la requête refusée. Un en-tête bêta présent sur l'une des deux requêtes mais pas sur l'autre peut faire échouer la correspondance même lorsque les corps sont identiques. L'erreur 400 qui en résulte porte le même message request body ... does not match qu'une différence de corps, de sorte qu'une différence d'en-tête est facile à confondre avec un problème de corps. En particulier, n'ajoutez ni ne supprimez d'en-têtes bêta en fonction du modèle ciblé par la requête.
Deux familles d'en-têtes sont exemptées de la correspondance, dans l'intérêt de la nouvelle tentative :
server-side-fallback-*: une nouvelle tentative doit supprimer le paramètrefallbacks, et supprimer cet en-tête en même temps ne provoque pas de non-correspondance.fallback-credit-*: conservez cet en-tête sur les deux requêtes. La nouvelle tentative en a besoin pour utiliser le jeton.
Le champ ne vaut null que lorsque le jeton vaut également null, de sorte qu'une valeur que vous observez tout en détenant un jeton n'est jamais null. Il peut néanmoins être absent (None dans les SDK typés) sur Amazon Bedrock, Google Cloud et Microsoft Foundry pendant le déploiement de leur prise en charge du champ. Dans ce cas, considérez la forme de la nouvelle tentative comme inconnue plutôt que comme false. Essayez d'abord la forme avec message assistant ajouté, et appuyez-vous sur la gestion des rejets décrite dans Lorsqu'une nouvelle tentative est rejetée, qui se replie sur le corps inchangé.
Lorsque le jeton d'un refus prend en charge la forme de continuation, le content de la réponse ne contient que la sortie propre du modèle, et l'explication du refus est fournie dans stop_details.explanation. Vous pouvez donc reprendre content tel quel dans le message assistant ajouté.
Deux ajustements peuvent encore être nécessaires avant l'envoi :
- Si le dernier bloc que vous envoyez est un bloc
text, supprimez ses espaces de fin. - Omettez tout bloc
tool_usecôté client qui n'a pas detool_resultcorrespondant.
Si le contenu repris inclut un bloc fallback issu d'un repli côté serveur antérieur, conservez le bloc exactement là où il apparaissait. Il est accepté sur toute requête sans en-tête bêta. L'API utilise sa position pour valider les blocs de réflexion qui l'entourent, de sorte qu'une requête qui reprend des blocs de réflexion des deux côtés de cette frontière est rejetée si le bloc est omis ou déplacé.
Le jeton ne peut être utilisé que depuis l'organisation et l'espace de travail qui ont reçu le refus, y compris sur Microsoft Foundry. Sur Amazon Bedrock et Google Cloud, qui n'ont pas d'espaces de travail, le jeton est lié à l'identité de l'appelant de la plateforme à la place.
Le jeton expire cinq minutes après le refus. Passé ce délai, envoyez la nouvelle tentative sans lui. Le jeton est également sans état : le serveur ne stocke rien à son sujet, et il n'existe aucun point de terminaison pour l'inspecter ou le révoquer.
Lorsque le refus est survenu après que des outils serveur ont déjà été exécutés au sein de la requête, le jeton ne peut être utilisé qu'en poursuivant la réponse partielle. C'est cette restriction qui empêche les appels d'outils terminés d'être exécutés, et facturés, à nouveau.
Une combinaison peut donc rendre le jeton inutilisable par l'une ou l'autre forme, lorsque les deux conditions suivantes sont réunies :
- La requête utilisait
output_config.formatou untool_choicequi force l'utilisation d'outils. L'un comme l'autre exclut la forme avec message assistant ajouté. - Le refus est survenu après l'exécution d'outils serveur. Cela exclut le corps inchangé.
Si la nouvelle tentative avec corps inchangé est rejetée avec une erreur 400 indiquant que le jeton doit être utilisé en poursuivant la réponse partielle, abandonnez le jeton. Une nouvelle tentative sans lui aboutit, mais elle réexécute et refacture les outils serveur terminés. Remontez le coût ou l'erreur à votre appelant plutôt que de relancer silencieusement.
Étapes suivantes
Détectez les refus et choisissez entre le repli côté serveur, le middleware du SDK et une nouvelle tentative manuelle.
Comment les lectures en cache et les écritures en cache sont facturées.
Chaque valeur de stop_reason et comment la gérer.
L'utilitaire du SDK qui applique automatiquement le crédit de repli.
Was this page helpful?