Skip to content

OpenAI Responses API

The Responses API is OpenAI’s interface for generating model responses and building agents. It is a superset of the Chat Completions API, with additional support for built-in tools, server-side conversation state management, and multi-modal inputs.

Terminal window
pip install 'strands-agents[openai]'

Requires openai>=2.0.0. Install or upgrade with pip install -U openai.

After installing dependencies, you can import and initialize the Responses provider as follows:

from strands import Agent
from strands.models.openai_responses import OpenAIResponsesModel
model = OpenAIResponsesModel(
model_id="gpt-4o",
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("Hello!")
print(response)

To connect to Amazon Bedrock’s OpenAI-compatible Mantle endpoints, see OpenAI-compatible endpoints (Mantle) on the Amazon Bedrock page.

The client_args configure the underlying OpenAI client. For a complete list of available arguments, refer to the OpenAI Python SDK.

The model configuration sets parameters for inference:

ParameterDescriptionExampleOptions
model_idID of a model to usegpt-4oreference
paramsModel and tool parameters{"tools": [{"type": "web_search"}]}reference
statefulEnable server-side conversation stateTrueTrue / False

Built-in tools run server-side and are passed via the params configuration. They work alongside any function tools registered on the agent.

model = OpenAIResponsesModel(
model_id="gpt-4o",
params={"tools": [{"type": "web_search"}]},
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("What are the latest developments in AI?")

Web search responses include URL citations that are streamed through the SDK’s citation system.

model = OpenAIResponsesModel(
model_id="gpt-4o",
params={
"tools": [{"type": "file_search", "vector_store_ids": ["vs_abc123"]}],
},
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("What does the document say about pricing?")

File search requires a vector store with uploaded files. Text responses stream correctly; file citation annotations are not yet mapped to the SDK citation schema.

model = OpenAIResponsesModel(
model_id="gpt-4o",
params={
"tools": [{"type": "code_interpreter", "container": {"type": "auto"}}],
},
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("Calculate the SHA-256 hash of 'hello world'")

The model executes code server-side and includes the results in its text response. The executed code and stdout/stderr are not currently surfaced to the caller.

The mcp built-in tool connects the model to a remote MCP server, letting it call tools hosted externally without any local MCP client setup.

model = OpenAIResponsesModel(
model_id="gpt-4o",
params={
"tools": [
{
"type": "mcp",
"server_label": "deepwiki",
"server_url": "https://mcp.deepwiki.com/mcp",
"require_approval": "never",
}
]
},
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("Using deepwiki, what language is the strands-agents/harness-sdk repo written in?")

The model discovers and calls tools exposed by the remote MCP server. The approval flow is not currently surfaced, so require_approval must be set to "never".

The shell built-in tool runs shell commands inside a hosted container managed by OpenAI.

model = OpenAIResponsesModel(
model_id="gpt-4o",
params={
"tools": [{"type": "shell", "environment": {"type": "container_auto"}}],
},
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
response = agent("Use the shell to compute the md5sum of the string 'hello world'.")

The model executes commands server-side and includes the output in its text response.

When stateful is enabled, the model manages conversation history server-side using OpenAI’s previous_response_id mechanism. The agent’s local message history is cleared after each turn, reducing payload size for multi-turn conversations.

model = OpenAIResponsesModel(
model_id="gpt-4o",
stateful=True,
client_args={"api_key": "<KEY>"},
)
agent = Agent(model=model)
agent("My name is Alice.")
# agent.messages is empty; conversation state is on the server
response = agent("What is my name?")
# The model remembers "Alice" via server-side state

When using a stateful model, the agent automatically uses a null conversation manager and throws an error if a conversation manager is also supplied.

OpenAI caches prompt prefixes automatically server-side. Set a cache configuration to route reads on a stable prompt_cache_key: the configured cache_key (cacheKey), or strands-<session id> when the agent has a session manager.

On models whose model info says they take cache points (GPT-5.6 and later, on the OpenAI API and Amazon Bedrock Mantle), the provider also places an explicit cache point (prompt_cache_breakpoint) at the end of each durable user message and sets prompt_cache_options.mode to explicit. Content added for a single call, such as context from a ContextInjector, goes after those points and after any tool outputs, so it never becomes part of a cache entry and the next request still reads the cached prefix.

from strands.models import CacheConfig
model = OpenAIResponsesModel(
model_id="gpt-6-sol",
cache_config=CacheConfig(messages_ttl="12h"),
client_args={"api_key": "<KEY>"},
)

The cache configuration maps onto the request as follows on models that take cache points:

SettingRequest field
messages_ttl / messagesTTL set to FalseNo cache points; implicit caching only
messages_ttl / messagesTTL set to "30m" or "12h"ttl on each cache point
ttl set to "30m" or "12h"prompt_cache_options.ttl
ttl set to "in_memory" or "24h"prompt_cache_retention

On older models, only ttl values "in_memory" and "24h" apply, through prompt_cache_retention. Any other TTL is ignored with a warning. tools_ttl / toolsTTL and system_prompt_ttl / systemPromptTTL have no effect. Caching fields you set in params, such as prompt_cache_options, take precedence over the cache configuration.

The provider decides from model info, not from the model ID. If you call a model that takes cache points through an alias the SDK does not recognize, such as a proxy or gateway name, opt in with a model_info (modelInfo) override:

from strands.models import CacheConfig, ModelCapabilities, ModelInfo
model = OpenAIResponsesModel(
model_id="my-proxy-alias",
cache_config=CacheConfig(),
model_info=ModelInfo(capabilities=ModelCapabilities(prompt_caching="cache_points")),
)

Cache points do not change what a stateful model stores server-side: injected content is still kept in the stored conversation.

Token counting is used by context management strategies to estimate input tokens before each model call.

The OpenAI Responses provider can use the native responses.input_tokens.count() API, which provides exact token counts including messages, instructions, and tool specifications.

You can enable native token counting with:

model = OpenAIResponsesModel(
model_id="gpt-4.1",
use_native_token_count=True,
)

When disabled (or if the API call fails), falls back to estimation with a character-based heuristic (characters ÷ 4 for text, characters ÷ 2 for JSON).