The actual function call ID sent by an assistant is not enforced, to where you have to absolutely use what the model sent you. You can make up your own.
The primary requirement is that a function_call must be immediately followed by a function_call_output, both with call_id
. The purpose of call_id is to pair the return to the calling function and its arguments in the case of parallel tool calls.
Here is how to actually be returning a function call to the Responses API in input
with stateless messages.
First, I give you an entire API request JSON body (with “input”), stripped right from the network call of the Prompts Playground when it was returning a function output:
{
"model": "gpt-4o",
"input": [
{
"role": "system",
"content": [
{
"type": "input_text",
"text": "You are WeatherPal, a virtual assistant acclaimed for your meteorology expertise and your ability to provide accurate weather conditions across the United States.\nCurrent time of latest input: 2025-03-14T17:22:00Z"
}
]
},
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Toledo Ohio looking hot out right now?"
}
]
},
{
"type": "function_call",
"call_id": "call_qCYF1LIA9qAK0Nvp24dMqNUP",
"name": "get_current_us_weather",
"arguments": "{\"us_city\":\"Toledo\"}"
},
{
"type": "function_call_output",
"call_id": "call_qCYF1LIA9qAK0Nvp24dMqNUP",
"output": "Toledo, OH - Current conditions: 62F, partly cloudy"
}
],
"tools": [
{
"type": "function",
"name": "get_current_us_weather",
"description": "Retrieves the current weather for a specified US city",
"parameters": {
"type": "object",
"required": [
"us_city"
],
"properties": {
"us_city": {
"type": "string",
"description": "The name of the US city for which to retrieve the current weather"
}
},
"additionalProperties": false
},
"strict": true
},
{
"type": "function",
"name": "get_usa_city_forecast",
"description": "Function for 5-day forecast retrieval.",
"parameters": {
"type": "object",
"required": [
"us_city"
],
"properties": {
"us_city": {
"type": "string",
"description": "Major city name, state abbreviation (e.g. Miami, FL)."
}
},
"additionalProperties": false
},
"strict": true
}
],
"text": {
"format": {
"type": "text"
}
},
"temperature": 1,
"top_p": 1,
"parallel_tool_calls": true,
"reasoning": {},
"stream": true,
"max_output_tokens": 2048,
"store": true
}
Then let’s break it down, writing Python to make the complete API call (but not demonstrating parsing the assistant message that had the first function call)
Weather function? Why not two of them…with strict structured outputs
from openai import OpenAI
MODEL = "gpt-4o"
TOOLS = [
{
"type": "function",
"name": "get_current_us_weather",
"description": "Retrieves the current weather for a specified US city",
"parameters": {
"type": "object",
"required": ["us_city"],
"properties": {
"us_city": {
"type": "string",
"description": (
"Major city name, state abbreviation (e.g. Miami, FL)."
),
}
},
"additionalProperties": False,
},
"strict": True,
},
{
"type": "function",
"name": "get_usa_city_forecast",
"description": "Function for 5-day forecast retrieval.",
"parameters": {
"type": "object",
"required": ["us_city"],
"properties": {
"us_city": {
"type": "string",
"description": (
"Major city name, state abbreviation (e.g. Miami, FL)."
),
}
},
"additionalProperties": False,
},
"strict": True,
},
]
The function specification with your functions is indeed a type of tool. It is placed in the AI context with other tools that tell the AI how to send to them, but functions uses a post-trained namespace format.
The API request input context that sends function execution results
We’re sending a system (or developer) message, and the user question. Then the assistant-produced function call, and a function return. You’d also include “assistant” role “output_text” if the AI wrote something along with its tool call (which is different than the single assistant role message of Chat Completions being fed back with tool_calls inside).
INPUT = [
{
"role": "system",
"content": [
{
"type": "input_text",
"text": (
"You are WeatherPal, a virtual assistant acclaimed "
"for your meteorology expertise and your ability to "
"provide accurate weather conditions across the United States.\n"
"Current time of latest input: 2025-03-14T17:22:00Z"
),
}
],
},
{
"role": "user",
"content": [
{
"type": "input_text",
"text": "Toledo Ohio looking hot out right now?",
}
],
},
{
"type": "function_call",
"call_id": "call_xyz1234",
"name": "get_current_us_weather",
"arguments": "{\"us_city\":\"Toledo, OH\"}",
},
{
"type": "function_call_output",
"call_id": "call_xyz1234",
"output": "Toledo, OH - Current conditions: 62F, partly cloudy",
},
]
The API call, by OpenAI’s Python library module SDK
# Create an OpenAI client instance, which uses OPENAI_API_KEY of environment
client = OpenAI()
response = client.responses.create(
model=MODEL, input=INPUT,
tools=TOOLS, tool_choice="auto", parallel_tool_calls=True,
temperature=1, top_p=0.5, max_output_tokens=2048,
stream=False, store=False,
)
# Output the non-stream response
print(response.output[0].content[0].text)
(This print command only expects output text, while the AI could be invoking another function call for you to capture.)
Put it all together, and the AI will happily answer about what your function had returned:
It's currently 62°F and partly cloudy in Toledo, Ohio. It doesn't seem too hot right now!
(updated to focus on the prominence of “functions” vs “tools” in the usage of Responses API endpoint)