Las cachés de prompts son específicas de cada modelo. Cuando Claude Fable 5 rechaza una solicitud y la reintentas en otro modelo, el prefijo de conversación que ya estaba en caché para Claude Fable 5 debe escribirse desde cero en la caché del nuevo modelo, y las escrituras en caché cuestan más que las lecturas de caché. El "fallback credit" (crédito de fallback) elimina ese costo adicional: el rechazo incluye un token de crédito, tú repites ese token en el reintento, y el reintento se factura como si la conversación hubiera estado en el nuevo modelo desde el principio.
Solo necesitas esta página cuando construyes el reintento tú mismo: con el SDK de Ruby o PHP, mediante HTTP sin procesar, o con lógica de reintento personalizada. El fallback del lado del servidor y el middleware del SDK aplican el crédito de fallback automáticamente. Si usas cualquiera de los dos, omite esta página.
Rechazos y fallback cubre cómo detectar rechazos y elegir un enfoque de fallback. Almacenamiento en caché de prompts explica las lecturas y escrituras de caché si esos términos son nuevos para ti.
Habilita la función con el encabezado beta
Envía la solicitud que podría ser rechazada con el encabezado anthropic-beta: fallback-credit-2026-06-01. El encabezado server-side-fallback-2026-06-01 también otorga los mismos campos.
Lee dos campos del rechazo
En un rechazo, stop_details incluye fallback_credit_token, una cadena opaca que representa el crédito, y fallback_has_prefill_claim, un booleano que te indica qué forma de cuerpo de reintento usar. Ambos son null cuando no hay crédito disponible para el rechazo.
Construye el reintento
Comienza desde el cuerpo de la solicitud rechazada. Establece model al modelo de fallback y agrega el token como el parámetro de nivel superior fallback_credit_token. Elige la forma del cuerpo según la tabla a continuación.
Envía el reintento con el mismo encabezado
Envía el reintento con el mismo encabezado beta fallback-credit-2026-06-01. El reintento necesita el encabezado para canjear el token.
El campo fallback_has_prefill_claim te indica si el reintento puede continuar la salida parcial del modelo rechazado en lugar de comenzar de nuevo:
fallback_has_prefill_claim | Cuerpo del reintento |
|---|---|
true | El cuerpo de la solicitud rechazada, sin cambios, más un mensaje de asistente añadido al final cuyo content repite el content de la respuesta rechazada. El modelo de reintento continúa la respuesta desde donde se detuvo el modelo rechazado, y las llamadas a herramientas del servidor ya completadas no se vuelven a ejecutar. |
false | El cuerpo de la solicitud rechazada, sin cambios. |
El ejemplo a continuación realiza una solicitud que podría ser rechazada, canjea el token de crédito en un reintento contra Claude Opus 4.8, y degrada a través de la escalera de rechazos cubierta en Cuando un reintento es rechazado.
El crédito de fallback está en beta en la API de Claude, Claude Platform en AWS, Amazon Bedrock, Vertex AI y Microsoft Foundry. Los tokens de crédito devueltos en los resultados de Message Batches no se pueden canjear; el canje aplica solo a solicitudes directas de la API de Messages.
El modelo de reintento debe ser uno de los destinos de fallback permitidos del modelo rechazado. En el lanzamiento, el destino permitido de Claude Fable 5 es Claude Opus 4.8 (claude-opus-4-8).
El reembolso es visible en el usage del reintento: cache_creation_input_tokens es menor, y cache_read_input_tokens es mayor en la misma cantidad, de lo que la misma solicitud reportaría sin el token. Un desplazamiento de cero significa que el token fue aceptado pero no había nada que revalorizar, por ejemplo porque la caché del modelo de reintento ya estaba caliente.
La mayoría de los reintentos se canjean en el primer intento. Cuando uno no lo hace, la API devuelve un error 400 que te indica qué intentar a continuación.
Continuación rechazada: reenvía el cuerpo sin cambios
Si el reintento que añade el mensaje de asistente es rechazado con un error 400, reenvía el cuerpo de la solicitud rechazada sin cambios, todavía con el token.
Token rechazado: elimina el token
Si el cuerpo sin cambios también es rechazado con un error 400 cuyo mensaje menciona fallback_credit_token, reintenta sin el token. El crédito se pierde, pero el reintento en sí se procesa.
Si la solicitud rechazada ejecutó herramientas del servidor, un reintento sin token vuelve a ejecutar y a facturar esas herramientas. En ese caso, muestra el error 400 a tu llamador en lugar de continuar hasta un reintento sin token.
Las secciones a continuación cubren casos límite y las reglas completas de canje. La mayoría de las integraciones no las necesitan.
Detecta rechazos y elige entre el fallback del lado del servidor, el middleware del SDK y un reintento manual.
Cómo se facturan las lecturas y escrituras de caché.
Was this page helpful?
client = Anthropic()
request = {
"max_tokens": 1024,
"messages": [{"role": "user", "content": "Hello, Claude"}],
}
def send(model, body):
return client.beta.messages.create(
model=model, betas=["fallback-credit-2026-06-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}
# Prefiere la forma de continuación a menos que la afirmación sea False
if details.fallback_has_prefill_claim is not False:
# Repite el contenido del rechazo, eliminando espacios en blanco finales de un
# bloque de texto final (el validador de prefill lo rechaza; la coincidencia
# del lado del servidor tolera la edición). Las solicitudes con herramientas también
# omiten bloques tool_use sin par, y luego vuelven a eliminar espacios tras las omisiones.
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 str(error):
raise # Transient: retry with the token within its five-minute window
try:
# Recurre al cuerpo sin cambios, aún con el token
response = send("claude-opus-4-8", exact_body)
except BadRequestError as error:
if "redemption temporarily unavailable" in str(error):
raise # Transient: retry with the token within its five-minute window
# El propio token fue rechazado: descártalo y reintenta sin él.
response = send("claude-opus-4-8", request)
print(json.dumps({"stop_reason": response.stop_reason, "model": response.model}))Cada valor de stop_reason y cómo manejarlo.