Claude Platform Docs
MessagesDévelopper avec Claude

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

  1. 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ête server-side-fallback-2026-07-01 donne également accès aux mêmes champs, et l'en-tête antérieur fallback-credit-2026-06-01 reste accepté et donne accès aux mêmes champs.

  2. Lisez deux champs dans le refus

    Lors d'un refus, stop_details inclut 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 null lorsqu'aucun crédit n'est disponible pour le refus.

  3. Construisez la nouvelle tentative

    Partez du corps de la requête refusée. Définissez model sur le modèle de repli et ajoutez le jeton en tant que paramètre de premier niveau fallback_credit_token. Choisissez la forme du corps dans le tableau suivant.

  4. 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_claimCorps de la nouvelle tentative
trueLe 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.
falseLe 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).

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.

  1. 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.

  2. 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.

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.

É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?