Verification Checklist
- ✓Put this request's
toolsnext tousage.input_tokens. A long catalog with nofunction_callcan still produce a large input total. The definitions are on the meter. - ✓If you set
defer_loading, separate the name and description from the parameter schema. Tool search says a deferred function still shows its name and description up front. What is deferred is mostly the schema. - ✓Find
function_call_outputon the next request. A string, image, or file is as long as you made it, and it is input on that request. Do not estimate it from the short function call. - ✓On output, read the visible function call apart from formatting tokens and from
reasoning_tokens. The counting guide says some models can report more output than the visible text even when reasoning tokens are 0. - ✓If you count before sending, pass the tools with the input. The counting endpoint uses the same shape as Responses. A local tokenizer misses tools and structural tokens.
1. The definition enters the system message.
The function-calling guide puts the billing rule ahead of whether a tool actually runs. Under the hood, functions are injected into the system message in the syntax the model was trained on. Callable function definitions therefore count against the context limit and are billed as input tokens. The ways it offers to spend less are to load fewer functions, shorten descriptions, or use tool search so deferred tools load only when needed. It does not say an unused definition is refunded.
The input total can therefore match the catalog you attached, and miss the short function name in the chat. The model may return a function_call, or none. Once the definitions are on this request's tools, they are already in the input. Reading "it called nothing" as "this turn should not pay for tools" treats a call that did not happen as the same fact as a definition that was sent.
The token-counting guide makes that number checkable before you send. The input token count endpoint accepts the same input format as Responses: text, messages, images, files, tools, or conversations. It returns the exact count the model will receive. Tool definitions, including function schemas and MCP servers, add tokens to the context, so count them with the input. A local tokenizer can count plain text and still miss tools and structural tokens. Dividing characters by a constant treats the catalog as almost free.
2. What is deferred is the schema, not the name.
The tool-search guide says the model can load tools into context as they are needed, so you avoid loading every definition up front and may reduce token usage and cost. The same page draws the boundary. At the start of a request the model still sees the name and description of whatever is searchable. For a namespace or an MCP server, only that name and description show until tool search loads the functions inside. For an individual deferred function, the name and description are still visible from the start, so tool search mostly defers the parameter schema.
Newly discovered tools are injected at the end of the context window. The guide says that placement is there to preserve the model's cache, on both cost and latency. Appending at the end explains whether the cached prefix survives. It does not delete a name and description that were already in context. defer_loading on a namespace applies to the functions inside it, not to the namespace object. Tools that are not deferred stay callable immediately.
The same page says only gpt-5.4 and later models on the Responses API support tool_search. Earlier models have no deferred path, so the catalog still has to be attached in full. Which models qualify follows the current tool-search page, not a permanent roster. What you save is the parameter schema that has not loaded yet, and the function detail that a namespace has not expanded. You do not make "this tool is in the catalog" free.
3. The result you send back is the next input.
Function calling is two requests. The first carries the tools and receives a tool call. Your application executes it. The second request sends the tool output back, and only then do you get text, or further tool calls. The weather walkthrough lists what that second request contains: the tool definition, the original prompt, the model's tool call, and the tool-call output. The output can be JSON, or image and file contents.
The formatting section says the result in function_call_output should typically be a string, in a format you choose: JSON, an error code, or plain text. Images and files can be an array of objects instead. If the function returns nothing, the guide tells you to send a string that says whether it succeeded, such as success, rather than sending nothing. After you append the results to input, you send them back.
The short function_call is an output item on the first response: a name and arguments. The result you paste back is part of the next request's input. A page of search results, a table, or the word success differ in length because of what you placed there, not because the model only spoke a function name. The counting endpoint wants the payload you are about to send. Tools and that returned string, counted together, are the number the model will receive.
4. A short call, formatting, and cache are other columns.
After previous_response_id, prior input on the chain still bills as input. That is the chained-input article. That column is input already held in conversation state, not the size of the function catalog. Both can sit on one call: the chain bills prior input, and tools bill the definitions attached this turn. "The chain is attached" does not explain why the catalog is still in the input.
Prompt caching reprices. It does not delete. Tool search appends newly found tools at the end of the window so the cache can survive. A hit changes the unit price of a matching prefix. A write can cost more than ordinary input, which is the cache-write article. The definition is still in context. The cache did not waive it. Reasoning tokens are output. A short visible answer can sit next to a larger output total, reconciled in the reasoning article.
The counting guide also names formatting tokens as their own case. Some models, and the page includes GPT-5 models, generate tokens used to format or delimit response channels, tool calls, and other message structure. Those tokens do not appear in message content or logprobs, and they are not necessarily itemized in usage. Reported output can therefore be higher than the visible text even when reasoning_tokens is 0. That is structural overhead on the output column. It does not move the function definitions off the input column, and it is not reasoning still billing. File-search storage that accrues by the day is another clock. It is not the switch for this turn's definitions and the result you send back.
5. A top-up does not shorten the catalog.
Reconcile four columns on this request. First, the callable definitions in tools, including the ones the model never invoked. They bill as input. Second, the names and descriptions that remain at the start after deferral. The parameter schema arrives only once it is loaded. Do not read defer_loading as a free tool. Third, the string, image, or file you placed in function_call_output. It belongs to the next input. Fourth, on output: the visible function call, plus any formatting tokens above the visible text, read apart from the reasoning detail. All four land in usage. They do not collapse into "it only wanted to call one function, so this should be cheap."
Topping up an OpenAI balance happens before those columns post. Swapping stablecoins into assets you can load does not pull the function definitions out of the system message, does not turn deferred loading into a refund, and does not shorten the result you paste back. 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 catalog is still on this request, input still includes the definitions and the result you send back.