Crédito de fallback
Evite pagar o custo do cache de prompt duas vezes ao repetir uma solicitação recusada em outro modelo.
Os caches de prompt são por modelo. Quando um modelo recusa uma solicitação e você a repete em outro modelo, o prefixo da conversa já armazenado em cache para o primeiro modelo precisa ser gravado no cache do novo modelo do zero. Gravações em cache custam mais do que leituras de cache. O "fallback credit" (crédito de fallback) elimina esse custo extra. A recusa carrega um token de crédito, você ecoa o token na nova tentativa, e a nova tentativa é cobrada como se a conversa tivesse ocorrido no novo modelo desde o início.
Você só precisa desta página quando constrói a nova tentativa por conta própria: via HTTP bruto ou com lógica de repetição personalizada. O fallback do lado do servidor e o middleware do SDK aplicam o crédito de fallback automaticamente. Se você usa qualquer um deles, pule esta página.
Recusas e fallback aborda a detecção de recusas e a escolha de uma abordagem de fallback. Cache de prompt explica leituras de cache e gravações em cache, caso esses termos sejam novos para você.
O fluxo básico
Ative com o cabeçalho beta
Envie a solicitação que pode ser recusada com o cabeçalho
anthropic-beta: fallback-credit-2026-07-01. O cabeçalhoserver-side-fallback-2026-07-01também concede os mesmos campos, e o cabeçalho anteriorfallback-credit-2026-06-01continua sendo aceito e concede os mesmos campos.Leia dois campos da recusa
Em uma recusa,
stop_detailsinclui dois campos:fallback_credit_token: uma string opaca que representa o crédito.fallback_has_prefill_claim: um booleano que informa qual formato de corpo de nova tentativa usar.
Ambos são
nullquando não há crédito disponível para a recusa.Construa a nova tentativa
Comece a partir do corpo da solicitação recusada. Defina
modelcomo o modelo de fallback e adicione o token como o parâmetro de nível superiorfallback_credit_token. Escolha o formato do corpo na tabela a seguir.Envie a nova tentativa com o mesmo cabeçalho
Envie a nova tentativa com o mesmo cabeçalho beta
fallback-credit-2026-07-01. A nova tentativa precisa do cabeçalho para resgatar o token.
O campo fallback_has_prefill_claim informa se a nova tentativa pode continuar a saída parcial do modelo que recusou em vez de recomeçar:
fallback_has_prefill_claim | Corpo da nova tentativa |
|---|---|
true | O corpo da solicitação recusada, inalterado, mais uma mensagem de assistente anexada cujo content ecoa o content da resposta recusada. O modelo da nova tentativa continua a resposta de onde o modelo que recusou parou, e as chamadas de ferramentas de servidor concluídas não são reexecutadas. |
false | O corpo da solicitação recusada, inalterado. |
Exemplo
O exemplo a seguir faz uma solicitação que pode ser recusada e resgata o token de crédito em uma nova tentativa no Claude Opus 4.8. Quando uma tentativa de repetição é rejeitada, o exemplo degrada pela escada de rejeição: a sequência de formatos de nova tentativa progressivamente mais simples abordada em Quando uma nova tentativa é rejeitada.
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}
# Prefira o formato de continuação, a menos que a afirmação seja 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:
# Recorra ao corpo inalterado, ainda com o token
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
# O próprio token foi rejeitado: descarte-o e tente novamente sem ele.
response = send("claude-opus-4-8", request)
print(json.dumps({"stop_reason": response.stop_reason, "model": response.model}))Onde funciona
O crédito de fallback está em beta na Claude API, Amazon Bedrock, Claude Platform on AWS, Google Cloud e Microsoft Foundry. Recusas em Message Batches não emitem tokens de crédito, e o resgate se aplica apenas a solicitações diretas à Messages API: um token passado em uma solicitação em lote é aceito, mas ignorado.
O modelo da nova tentativa deve ser um dos destinos de fallback permitidos do modelo que recusou. Para Claude Fable 5.1 e Claude Fable 5, esses são Claude Opus 4.8 (claude-opus-4-8) e Claude Opus 5 (claude-opus-5).
Na Claude API e na Claude Platform on AWS, a lista de destinos é publicada como allowed_fallback_models na entrada de cada modelo na Models API quando o cabeçalho beta server-side-fallback-2026-07-01 está definido. A lista ainda não é visível apenas com o cabeçalho fallback-credit-*. Ela não é exposta no Amazon Bedrock, Google Cloud ou Microsoft Foundry.
Verificando se o crédito foi aplicado
O reembolso é visível no usage da nova tentativa. Em comparação com o que a mesma solicitação reportaria sem o token, cache_creation_input_tokens é menor e cache_read_input_tokens é maior na mesma quantidade. Uma variação de zero significa que o token foi honrado, mas não havia nada a reprecificar, por exemplo porque o cache do modelo da nova tentativa já estava aquecido.
Quando uma nova tentativa é rejeitada
A maioria das novas tentativas é resgatada na primeira tentativa. Quando uma não é, a API retorna um erro 400 que informa o que tentar em seguida.
Continuação rejeitada: reenvie o corpo inalterado
Se a nova tentativa que anexa a mensagem de assistente for rejeitada com um erro 400, reenvie o corpo da solicitação recusada inalterado, ainda com o token.
Token rejeitado: remova o token
Se o corpo inalterado também for rejeitado com um erro 400 cuja mensagem menciona
fallback_credit_token, tente novamente sem o token. O crédito é perdido, mas a nova tentativa em si é processada.
Essa rejeição é transitória, não um veredito sobre o formato da sua nova tentativa. Repita a mesma solicitação, com o mesmo token, dentro da janela de cinco minutos do token. Não avance para o próximo degrau da escada.
Referência
As seções a seguir abordam casos extremos e as regras completas de resgate. A maioria das integrações não precisa delas.
O resgate compara a nova tentativa com a solicitação recusada. Todo campo que molda o prompt deve corresponder exatamente. Campos que não moldam o prompt podem mudar na nova tentativa.
| Regra | Campos |
|---|---|
| Devem corresponder exatamente | system, messages, tools, tool_choice, thinking e cache_control, além de output_config, mcp_servers, context_management e container quando você os usa |
| Podem mudar na nova tentativa | model, max_tokens, stop_sequences, temperature, top_p, top_k, stream, metadata e service_tier |
O formato de continuação (fallback_has_prefill_claim: true) é a única exceção à correspondência de messages: ele adiciona exatamente uma mensagem de assistente ao final de messages.
Não remova blocos thinking ou redacted_thinking de turnos anteriores na nova tentativa, mesmo que uma nova tentativa simples sem token normalmente os remova. O corpo deve corresponder à solicitação recusada, e o servidor lida com esses blocos por conta própria.
Envie os mesmos cabeçalhos anthropic-beta na nova tentativa e na solicitação recusada. Um cabeçalho beta presente em uma das duas solicitações, mas não na outra, pode fazer a correspondência falhar mesmo quando os corpos são idênticos. O erro 400 resultante carrega a mesma mensagem request body ... does not match de uma diferença de corpo, então uma diferença de cabeçalho é fácil de ser interpretada erroneamente como um problema de corpo. Em particular, não adicione nem remova cabeçalhos beta com base no modelo ao qual a solicitação se destina.
Duas famílias de cabeçalhos estão isentas da correspondência, em benefício da nova tentativa:
server-side-fallback-*: uma nova tentativa deve remover o parâmetrofallbacks, e remover esse cabeçalho junto com ele não causa uma incompatibilidade.fallback-credit-*: mantenha esse cabeçalho em ambas as solicitações. A nova tentativa precisa dele para resgatar o token.
O campo é null apenas quando o token também é null, então um valor que você observa enquanto possui um token nunca é null. Ele ainda pode estar ausente (None nos SDKs tipados) no Amazon Bedrock, Google Cloud e Microsoft Foundry enquanto o suporte ao campo é implantado nessas plataformas. Nesse caso, trate o formato da nova tentativa como desconhecido em vez de false. Tente primeiro o formato com mensagem de assistente anexada e conte com o tratamento de rejeição em Quando uma nova tentativa é rejeitada, que recorre ao corpo inalterado.
Quando o token de uma recusa suporta o formato de continuação, o content da resposta carrega apenas a saída do próprio modelo, e a explicação da recusa é entregue em stop_details.explanation. Portanto, você pode ecoar content na mensagem de assistente anexada como está.
Dois ajustes ainda podem ser necessários antes do envio:
- Se o bloco final que você envia for um bloco
text, remova seus espaços em branco finais. - Omita qualquer bloco
tool_usedo lado do cliente que não tenha umtool_resultcorrespondente.
Se o conteúdo ecoado incluir um bloco fallback de um fallback do lado do servidor anterior, mantenha o bloco exatamente onde ele apareceu. Ele é aceito em qualquer solicitação sem um cabeçalho beta. A API usa sua posição para validar os blocos de pensamento ao redor dele, então uma solicitação que ecoa blocos de pensamento de ambos os lados dessa fronteira é rejeitada se o bloco for omitido ou movido.
O token só pode ser resgatado pela organização e pelo workspace que receberam a recusa, inclusive no Microsoft Foundry. No Amazon Bedrock e no Google Cloud, que não têm workspaces, o token é vinculado à identidade do chamador da plataforma.
O token expira cinco minutos após a recusa. Depois disso, envie a nova tentativa sem ele. O token também é stateless: o servidor não armazena nada sobre ele, e não há endpoint para inspecioná-lo ou revogá-lo.
Quando a recusa chegou depois que ferramentas de servidor já haviam sido executadas dentro da solicitação, o token só pode ser resgatado continuando a resposta parcial. Essa restrição é o que impede que as chamadas de ferramentas concluídas sejam executadas, e cobradas, novamente.
Uma combinação pode, portanto, deixar o token impossível de resgatar por qualquer dos formatos, quando ambas as condições a seguir são verdadeiras:
- A solicitação usou
output_config.formatou umtool_choiceque força o uso de ferramentas. Qualquer um deles exclui o formato com mensagem de assistente anexada. - A recusa chegou depois que ferramentas de servidor haviam sido executadas. Isso exclui o corpo inalterado.
Se a nova tentativa com corpo inalterado for rejeitada com um erro 400 dizendo que o token deve ser resgatado continuando a resposta parcial, descarte o token. Uma nova tentativa sem ele é processada, mas reexecuta e cobra novamente as ferramentas de servidor concluídas. Exponha o custo ou o erro ao seu chamador em vez de repetir silenciosamente.
Próximos passos
Detecte recusas e escolha entre fallback do lado do servidor, o middleware do SDK e uma nova tentativa manual.
Como leituras de cache e gravações em cache são cobradas.
Cada valor de stop_reason e como lidar com ele.
O auxiliar do SDK que aplica o crédito de fallback automaticamente.
Was this page helpful?