← Blog
October 14, 2026 · 16 min

Paying for a no: refusal billing, fallback credit and x402

An agent can pay for an answer and get a refusal instead. Whether that refusal costs anything depends on the provider, the policy category, the moment it arrived, and one status-code check in the seller's payment middleware.

Refusals used to be an edge case. In 2026 they are an API surface. Anthropic's newest models run safety classifiers that decline requests with a named category. OpenAI's GPT-6 returns a policy error code instead of output. And every model can still write "I can't help with that" as plain text.

On a prepaid account, a refusal is a line item at the end of the month. For an agent paying per call over x402, it is a payment it already signed. So we asked a narrow question: when the answer is no, who pays, how much, and can anyone downstream tell?

Our sources, all read or run on 2026-10-14: Anthropic's refusals and fallback, fallback credit, streaming refusals and pricing pages plus its API release notes; OpenAI's structured outputs and safety classifier guides and its OpenAPI spec at 8035270; Gemini's billing FAQ, safety settings guide and generateContent reference; OpenRouter's error and model-fallback docs; LiteLLM at b22a0bd; the Vercel AI SDK at 6ac1ee1; browser-use at c75e847; and the x402 reference middlewares at dd927a2. We also ran 480 calls against two local models under Ollama 0.30.6.

The short version: only one provider documents how it bills a refusal, and that rule changed twice in four months. The field that decides the bill is lost as soon as the response is translated into the Chat Completions shape. And x402's reference middleware settles on the HTTP status code, so a refusal that arrives as a 200 is a sale unless the seller decides otherwise.

Three kinds of no

The model writes it. This is the oldest kind and still the most common. The refusal is ordinary output. OpenAI's structured outputs guide adds a separate refusal field for safety refusals, because a refusal "does not necessarily follow the schema you have supplied." Anthropic's own taxonomy files "model-generated refusals" under "standard text responses."

A classifier declines, and the API returns a 200. Anthropic's refusals and fallback page says Claude Fable 5.1, Fable 5, Opus 5.5, Opus 5, Sonnet 5.5 and Haiku 5.5 "include safety classifiers that can decline a request." The response is "a normal response, not an error," with stop_reason: "refusal" and a stop_details object. Its category is one of cyber, bio, frontier_llm, reasoning_extraction or general_harms, or null when no named category applies. The decline can arrive before any output or mid-stream. In a Message Batch, a refused item comes back as result.type: "succeeded".

A classifier declines, and the API returns an error. OpenAI's Responses error enum in its OpenAPI spec now includes bio_policy. A Codex pull request merged on July 7 (openai/codex#31439) describes it as a Responses API contract change "from invalid_prompt and the legacy message to bio_policy." A later one (#46306, September 17) makes Codex treat it as non-retryable, "recognizing streaming failures and HTTP 400 responses." cyber_policy appears in the spec's session error codes. OpenRouter's GPT-6 guide documents both codes and surfaces them as an HTTP 403 with error_type: "refusal". When the block arrives after the stream has started, the 403 is a code inside the error body, "because the HTTP line was already committed."

Tools disagree on which kind this third case is. UK AISI's Inspect framework failed evaluation samples on bio_policy until a fix merged on September 30 turned it into a model output with stop_reason="content_filter". Codex keeps it as an error. Same event, two contracts.

Gemini sits in between. A blocked prompt returns promptFeedback.blockReason (SAFETY, OTHER, BLOCKLIST, PROHIBITED_CONTENT or IMAGE_SAFETY), and the reference says "no candidates are returned." A blocked response ends with finishReason: SAFETY, and "the content that was blocked is not returned." Both arrive as a normal GenerateContentResponse, not as an HTTP error.

Who bills what

Anthropic is the only provider we found that writes its refusal billing down in detail. The current rule, from the same page:

The rule applies on the Claude API, Bedrock, Claude Platform on AWS, Google Cloud and Microsoft Foundry. Its history is short. The API release notes show that on June 2, 2026 Anthropic stopped billing refusals that arrive before any output on the Claude API. On September 24 it resumed billing them for the three categories above, "the categories where we measure low volumes of false positives." The refusals page adds the reason: "To disrupt attempts to circumvent Anthropic's safeguards at scale." It also says the billed list "may change."

Note what this does to the usage object. A free refusal and a billed refusal report the same kind of token counts. Usage alone does not tell you whether you were charged. You need the category and the timing.

OpenAI documents no special billing rule for refusals the model writes; the refusal simply arrives as output. For bio_policy blocks, we found no statement either way on billing. Gemini's billing FAQ says "If your request fails with a 400 or 500 error, you won't be charged for the tokens used. However, the request will still count against your quota." A safety block is not a 400, and the pages we read do not say how it is billed.

One of the billed categories deserves a closer look from anyone building agents. Anthropic says a reasoning_extraction refusal "usually comes from a prompt that asks the model to put its thinking or reasoning in the output." Its list of common triggers includes "A reasoning, thinking, or trace field in JSON output or in a tool input." That is a common agent pattern. browser-use, for example, defaults to use_thinking=True, and its AgentOutput schema then includes a thinking field next to every action. We did not test whether that schema draws refusals on Claude. The point is that a category billed before any output overlaps with a shape agent frameworks emit on purpose.

The other ledger: the account

Refusals also accumulate somewhere other than the invoice. OpenAI's safety classifiers guide describes an escalation ladder. Requests are classified into risk thresholds. "If your org hits high thresholds repeatedly, OpenAI returns an error and sends a warning email." If the requests continue past the stated time threshold, "usually seven days," OpenAI stops the org's access to GPT-5, the model the guide covers.

The documented mitigation is the safety_identifier parameter: a stable, hashed ID per end user, so enforcement can block one identifier instead of the whole org. A blocked identifier receives an "identifier blocked" error on all future GPT-5 requests. Anthropic's Messages API has a similar field, metadata.user_id, which "Anthropic may use … to help detect abuse."

For a multi-tenant seller, this ledger is the bigger risk. The org is the seller. Without a per-customer identifier, a provider's escalation sees one customer, and one agent's refusals count against everyone routed through the same account.

What a fallback costs

The usual answer to a refusal is to retry on another model. Anthropic now does that on the server. Setting fallbacks: "default" with the server-side-fallback-2026-07-01 beta header retries a declined request on the model Anthropic recommends for that refusal category. You can instead name up to three fallback models. A few rules matter for cost:

The hidden cost of any fallback is the prompt cache. Caches are per model, so the retry has to write the whole prefix again. Fallback credit fixes that: the refusal carries a fallback_credit_token, and a retry that echoes it "is billed as though the conversation had been on the new model all along."

The difference is easy to price. Take a 40,000-token cached conversation on Opus 5.5 that gets declined and moves to Opus 4.8. Without the credit, the retry writes 40,000 tokens to Opus 4.8's five-minute cache at $6.25 per million: $0.25. With it, the same tokens bill as cache reads at $0.50 per million: $0.02. If the refused attempt was uncached and in a billed category, it also cost 40,000 × $4 per million on Opus 5.5: $0.16, before any output.

The credit has strict terms. The token "expires five minutes after the refusal." It "redeems only from the organization and workspace that received the refusal." The retry must match the refused request exactly on system, messages, tools, tool_choice, thinking and cache_control. The target must be a permitted fallback: Opus 4.8 or Opus 5 for Fable 5.1, Fable 5 and Opus 5.5; Opus 4.8 for Opus 5; Sonnet 5 for Sonnet 5.5. Batch refusals mint no credit, and Haiku 5.5 refusals carry none.

In practice, the credit belongs to whoever holds the workspace. An agent behind a gateway cannot redeem it. Only the gateway can.

Routers handle this differently. OpenRouter's model fallbacks trigger on errors, including "Moderation flags for filtered models," and requests are "priced using the model that was ultimately used." It states that its fallbacks parameter on the Messages endpoint "does not use Anthropic's server-side fallback feature." It does not resend a 403 policy block to another endpoint serving the same model. LiteLLM's router has content_policy_fallbacks. A 200 whose finish_reason is content_filter is converted into a ContentPolicyViolationError only when such a fallback is configured. Otherwise "original response is returned." The check runs on non-streaming ModelResponse objects.

What survives translation

Most agents do not speak the Messages API. They speak Chat Completions, through an SDK, a router or a gateway. OpenAI's spec allows five finish_reason values: stop, length, tool_calls, content_filter and function_call. There is no refusal value and no place for a category. Here is what each layer we read does with an Anthropic refusal:

So once a refusal crosses into the Chat Completions shape, the field that decides whether it was billed is gone. A client sees content_filter for a free cyber decline, a billed bio decline, a Gemini block and, in LiteLLM's case, an unexplained OTHER.

The refusal nobody labels

The classifier cases at least come with a flag. The most common refusal an agent meets carries none: a model following a system prompt that scopes what it may answer. Every seller with a system prompt produces these. We measured what they look like on the wire.

Setup: Ollama 0.30.6, qwen2.5:7b and qwen2.5:3b, num_ctx 8192, temperature 0.8, seeds 1000–1009, max_tokens 300, on the OpenAI-compatible endpoint. The system prompt makes the model a billing assistant that must answer anything else with exactly "I can't help with that." We sent five off-topic requests and one on-topic control, ten times each, in four conditions: short or long context (the policy alone, about 63 tokens, or the policy plus about 2,600 tokens of reference text) and free text or a strict json_schema response format.

# off-topic requests refused, out of 50 per cell
                     short/text  short/json  long/text  long/json
qwen2.5:7b               50          48          38         19
qwen2.5:3b               29          10          10          0

# all 480 calls
refusals                       204
finish_reason on refusals      "stop" 204/204
message.refusal field present  0/480
avg prompt tokens, long refusal ~2,648  (7b: ~14 completion tokens)

Three things stand out. First, a refusal on the wire is indistinguishable from an answer. Every one ended with finish_reason: "stop", none set a refusal field, and every one reported full usage. Only reading the text tells them apart.

Second, a refusal is almost all input. With the long context, the 7B model spent about 2,648 prompt tokens to produce a refusal of about 14 tokens. Whatever the seller charges for input, the agent pays it for a no.

Third, compliance is not stable. More context and a schema both made the policy leak: the 7B model refused 50 of 50 off-topic requests with a short prompt and free text, and 19 of 50 with a long prompt and a schema. Under the schema, refusals that did happen came back as valid objects, {"answer": "I can't help with that.", "invoice_items": []}, which any validator accepts. We showed the same effect of constrained decoding in our structured outputs audit; here it applies to the refusal itself.

x402 settles on status, not on outcome

The x402 v2 specification defines how a payment is verified and settled. It does not say when a seller should settle. That decision lives in the reference middleware, and all four we read make it the same way. Hono checks res.status >= 400 and skips settlement; Express checks res.statusCode >= 400; FastAPI checks response.status_code >= 400; the Go echo middleware checks capture.statusCode >= 400.

So the shape of the refusal decides the payment. A 200 refusal settles. A 403 block does not. A model-written refusal settles like any answer.

Under the exact scheme that is all or nothing. Under upto, the seller can settle any amount up to the authorized maximum. The scheme spec says the settled amount "MAY be 0 (no charge if no usage occurred)," and the EVM binding adds that a zero settlement needs no on-chain transaction. The SDK exposes this as setSettlementOverrides, which accepts atomic units, a percentage or a dollar amount. Its own comment warns that a different amount "is only valid in schemes that support partial settlement, such as upto." We made the metering case for upto in our upto post. Refusals are the sharpest instance of it.

Put the provider rules next to the middleware rule and the mismatches are plain:

What it means for LLM4Agents

We are the seller in the middle of every one of those rows. We hold the upstream accounts, we choose the response shape, and we run the settlement. Agents see none of what decides the bill.

Our responses use the Chat Completions shape, so the refusal category is gone by the time a response leaves us, as it is for every layer we read. Our walk-up path decides what to settle from the measured cost of the call, and nothing in that computation looks at why the call ended. Today a refusal is a sale. We have not yet measured what our upstream reports for a refusal it did not bill. If it reports token counts and no cost, which is how Anthropic says an unbilled refusal looks, any price computed from tokens would charge an agent for a call nobody charged us for. That is the first thing to test.

The account ledger is the larger threat. Every agent we serve reaches the provider through accounts we control. Without a per-agent identifier in the request, a provider's escalation ladder sees one customer. One agent probing a classifier puts every other agent's access at risk.

The opportunity is the mirror image. An agent cannot hold a workspace, redeem a five-minute credit token, read a category and price it, or carry an identifier the provider trusts. A gateway can do all four. Our fallback chains already handle errors. A refusal is the one failure they do not cover, because it arrives as a success.

Staying on the frontier

In order of cost and urgency.

1. Classify before settling. Detect every refusal shape before the settlement decision: stop_reason: "refusal", finish_reason: "content_filter", a non-empty message.refusal, and the bio_policy and cyber_policy codes. Log it as its own signal. A refusal is an HTTP 200, so error-rate monitoring never sees it.

2. Settle a refusal at what it cost. Under upto, an unbilled pre-output refusal settles 0, a billed category settles the upstream charge for the input, and a mid-stream refusal settles what upstream billed. Under exact, skipping settlement is the only way to charge nothing. Never settle a worst-case quote for an empty content.

3. Carry the category. Fill message.refusal instead of leaving it empty, and add the category and billed amount to the response and the receipt, for example as an X-Refusal-Category header. The name is ours to choose; the signal is what matters.

4. Make policy blocks unambiguous. Return OpenAI's policy errors as a 403 with error_type: "refusal" and a do-not-retry hint. We argued for explicit retry signals in our 402 vs 429 audit. A retried bio block is a second identical block, and it lands on the same account.

5. Send a per-agent identifier we set ourselves. Derive a safety_identifier and an Anthropic metadata.user_id from a hash of the paying wallet or agent ID. Overwrite any value the client sends, so an agent cannot rotate its way around enforcement.

6. Make refusal fallback opt-in and credit-aware. Let a models chain treat a refusal as a trigger. Where the chain matches Anthropic's permitted targets, pass the chain's own models as the named fallbacks list so the credit applies, and report each attempt from usage.iterations on the receipt. Do not use "default" routing behind a quote: it can pick a model outside the chain, and Opus 4.8, a permitted target for Opus 5.5, costs $5 per million input tokens against Opus 5.5's $4. The chain is already quoted at its most expensive link, so named fallbacks change the settled amount, not the quote.

7. Lint for billed categories. When a request to a classifier-equipped Claude model carries a response schema or tool input with a thinking, reasoning or trace property, return a warning with the 402. A 402 is free to request. That makes it the cheapest place to tell an agent its prompt matches a pattern that is billed before any output.

Pay per call, in stablecoins, over an OpenAI-compatible API

One 402, one signature, 345+ models. No subscription, no minimum.

Register your agent