When a reasoning model on OpenAI’s Responses API calls a tool, the response’s output array can hold items of type reasoning alongside the function call. With store: false, one of them looks roughly like this:
{
"id": "rs_...",
"type": "reasoning",
"summary": [],
"encrypted_content": "<long encrypted string>"
}
There isn’t much in it for your code to use. The items are opaque, the API doesn’t return their reasoning text, and summary stays empty unless you opt in to summaries. So it’s easy to write a tool loop that keeps the function call and throws the rest away.
But OpenAI’s docs ask you to send these items back. The function calling guide says they “must also be passed back with tool call outputs”. The reasoning guide says “we highly recommend” it, because that “allows the model to continue its reasoning process to produce better results in the most token-efficient manner.” When the model calls several functions in a row, that covers every reasoning item, function call and function output since the last user message.
You don’t have to work out which items matter, because the simplest option is to send all of them, and the service ignores the ones that aren’t relevant to your functions. If you trim history to save tokens, make sure everything between the last user message and your function output goes into the next request untouched.
Sending them back
How you send them depends on whether OpenAI kept the response. Responses are stored by default, and in that case previous_response_id is enough: you pass the ID along with your function output, and your code never handles the earlier items.
With store: false there is no stored response to continue from, and the same goes for organizations on Zero Data Retention, so the items have to go into input by hand. The function calling guide’s Python sample does it this way:
input_list += response.output
# after running the tool
input_list.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": horoscope,
})
The next request depends on the encrypted_content string in that list. When a request includes it, the migration guide says, “it is decrypted in memory, used for generating the next response, and then securely discarded”, and any new reasoning tokens come back encrypted. So your code has to hold on to those strings between calls.
Earlier turns
Everything so far is about one turn, the run of tool calls after a single user message. Reasoning from earlier turns has its own setting, reasoning.context. With current_turn, reasoning from the active turn is available, but reasoning from earlier turns doesn’t go into the next sample. With all_turns, the available and compatible items from earlier turns go in too. Currently the GPT-5.6 models use all_turns by default and earlier models default to current_turn.
all_turns only has an effect when the request can reach the earlier items, through previous_response_id, a conversation, or replaying the complete history yourself, which also works with store: false. The setting can’t bring back items your loop already threw away.
This note was put together from OpenAI’s current docs, and nothing here was run against the API, so we don’t have a number for what a dropped reasoning item costs. If you’ve measured it, we’d be glad to see the numbers. For now we’d keep the whole output list, and because the reasoning.context default already differs between model generations, look at the model’s page before switching.

