Verification Checklist

  • ✓Read usage.input_tokens on this response beside the new line you typed. A short line with an input count close to the whole history means the chain is on the meter.
  • ✓previous_response_id should be the previous response id. conversation is a different field. Neither one is a free-context switch.
  • ✓Check store. The default keep is about 30 days. false stops that object from being kept for the next id. It does not zero the input.
  • ✓If this turn resends top-level instructions, count that text as input you sent. The chain does not carry the previous top-level note, and resending it is not free.
  • ✓A cache hit is cached input inside the input total, not a deletion from input_tokens. Reasoning tokens sit on output. Do not add either detail on top of its total.

1. The id keeps the chain. It does not drop the input.

The conversation-state guide starts from a plain fact: each generation request is independent and stateless. A follow-up exists only if you pass earlier messages in input, or you let the API hold state. There are two holding paths. The Conversations API keeps a long-lived object. previous_response_id threads responses. Both save you from stitching items by hand. Neither one says the held tokens are free.

The same page states the billing rule right after the retention note: even when you use previous_response_id, all previous input tokens for responses in the chain are billed as input tokens. The migration guide names the matching mistake: assuming that field removes billing for prior context. Previous input tokens in the chain are still input. A turn whose only new text is “continue” can therefore show an input total close to the history, not close to that one word.

The documented phrase is previous input tokens. It is not a second formula that multiplies the last output by some extra rate. Whether the previous answer is inside this turn’s input is answered by usage.input_tokens on this response. Estimating from the new line treats the chain as free.

2. store keeps the object. It does not waive the meter.

Response objects are saved for 30 days by default. You can see them in dashboard logs or retrieve them. Set store to false when you create the response, and that retention stops. Conversation objects, and the items in them, are not on that 30-day TTL. A response attached to a conversation keeps its items with no 30-day cutoff.

Retention and billing sit in neighboring paragraphs, which is why they get merged. store: false means this object is not kept for the next id. It does not remove input from this turn’s usage, and it does not refund a turn that already posted. Once the object is gone, the next request has to carry the context in input yourself. Tokens you place there are input.

The migration guide also says zero-data-retention organizations are forced to store: false. The checklist for a stateless or zero-data-retention flow is to include encrypted reasoning items yourself when that reasoning must continue. Those items are content you send on the next request, not a free attachment. WebSocket mode uses the same previous_response_id rules. The connection-local cache is there for low-latency continuation. The id still controls lineage. If the id cannot be resolved, the guide tells you to set it to null and pass the full input. That full input is input.

3. Top-level instructions do not ride along.

The migration guide gives three ways to hold a thread: pass previous_response_id and let the API keep prior response context; pass prior output items back when you want to trim them; or use the Conversations API for a durable object. The first path has a limit that is easy to miss. Top-level instructions are not carried. Resend the stable note on every turn.

The resent note is input you supplied on this call, so it belongs in this turn’s usage.input_tokens. Omit it, and the model does not see a rule you thought was still there. Send it again, and it is not waived because the chain exists. A conversation id and a response id are different fields. One is the long-lived object. The other threads responses. What you save is stitching code. The docs do not call either path free context.

Manual replay is the same meter. Earlier user messages and assistant outputs placed in input are this request’s input. The API placing them, or you placing them, changes who stores the items. It does not change whether prior input is billed on this turn. The token-counting guide can size the input you submit yourself. The count includes formatting tokens for roles and boundaries, and it does not predict output. After the chain is attached, the total to reconcile is still usage on the response.

4. Window, cache, and reasoning are other columns.

The context window is the token ceiling for one request. It includes input, output, and, on some models, reasoning tokens. Tokens generated past that ceiling may be truncated in the response. Truncation means the extra generation did not all come back. It is not a refund of input already counted. Trimming a long history is pointed at the separate compaction page. Use that page for the threshold. What gets cut is what this turn would have put in the window, not a reversal of the previous bill.

Prompt caching is another column. The counting guide treats cached input as input whose price can differ from uncached input. It is still input. A hit reprices a matching prefix. It does not delete the chain from input_tokens. A write that costs more than ordinary input, and a breakpoint placed on text that changes every turn, is the subject of the cache-write article. This one does not restate those rates.

Reasoning tokens are output. A short visible answer can sit next to a much larger output total. That column is reconciled in the reasoning article. The short “continue” in this article is about input swollen by the chain. Both columns can appear on one response: input for the chain, output for what was generated. Adding the cached detail on top of input_tokens, or the reasoning detail on top of total output, counts one bill twice. File-search storage is a third clock. It can keep running on an idle day, and it is not the switch that decides whether this turn’s prior input is billed.

5. A top-up does not shorten the chain.

Reconcile the response, not the length of the last chat line. First, usage.input_tokens should show the chain’s prior input, not only “continue.” Second, store: about 30 days by default, and false only explains whether the object is still there. Third, whether this call resent top-level instructions. Read cached input apart from the input total, and reasoning apart from output. The four readings belong to one call. They do not collapse into “the chat looked short, so it should be cheap.”

Topping up an OpenAI balance happens before those columns post. Swapping stablecoins into assets you can load does not make previous_response_id bill only the new line, does not turn store: false into a refund, and does not pull history out of the next input. When that swap is the step you need, AllSwap does it without an account and without custody. A completed swap only means the asset moved. If the chain is still attached, the next short reply still bills prior input.