Function Calling

Use Function Calling to let the model request data or actions from your application during a Responses API workflow. This is useful when the model needs information or operations that aren't available in the prompt itself, such as calendar data, internal application state, or the result of a custom operation.

With this pattern, the model doesn't execute the function directly. Instead, it returns the function name and arguments, your application runs the function, and then your application sends the function output back so the model can continue and produce the user-facing answer.

What This Enables

Function Calling is useful when your application needs to stay in control of execution while still allowing the model to decide when outside information is needed.

Example use cases:

  • Looking up calendar events
  • Retrieving application data
  • Calling internal or external API
  • Running business logic or calculations

Within your function, you can call an external service, a database, one of your own library APIs, a CLI, or a local MCP server.

This approach gives you flexibility while keeping the execution path inside the application.

Execution Flow

A typical function calling interaction works las follows:

  1. The client sends a request that includes one or more function tool definitions.
  2. The model decides whether one of those tools is needed.
  3. If a tool is needed, the model returns the function name and arguments.
  4. The application runs the function and prepares the result.
  5. The application sends that result back in a follow-up request.
  6. The model uses that result to complete the response.

State Handling Options

There are two common ways to manage state across these requests:

  • Service-managed state

    Recommended for most use cases. The follow-up request includes previous_response_id, and the service tracks the earlier exchange.

  • Client-managed state

    The application keeps the full interaction history and sends the accumulated context with each request.

Tip

Keep tool definitions precise. Clear names, well-written descriptions, and well-defined parameters help the model select the right tool and generate usable arguments.

Define a Function Tool

To define a function tool, add an entry in the tools property with "type": "function".

The following example defines a tool that retrieves calendar events for a specified date:

tools = [
    {
        "type": "function",
        "name": "get_calendar_events",
        "description": "Return calendar events scheduled for a specific date.",
        "parameters": {
            "type": "object",
            "properties": {
                "date": {
                    "type": "string",
                    "description": "Date to query, for example 2026-04-02"
                }
            },
            "required": ["date"],
        },
    },
]

Include this tools array in the client.responses.create() request.

Example: Service-Managed State

In this pattern, the first request lets the model decide whether the tool is needed. The second request sends the tool result back and references the earlier response.

import json

tools = [
    {
        "type": "function",
        "name": "get_calendar_events",
        "description": "Return calendar events scheduled for a specific date.",
        "parameters": {
            "type": "object",
            "properties": {
                "date": {
                    "type": "string",
                    "description": "Date to query, for example 2026-04-02"
                }
            },
            "required": ["date"],
        },
    },
]

def get_calendar_events(date):
    # Replace this with actual calendar logic or an API call
    return [
        {"time": "09:00", "title": "Team standup"},
        {"time": "13:00", "title": "Design review"},
        {"time": "16:00", "title": "Project check-in"},
    ]

# Initial request
response = client.responses.create(
    model="openai.gpt-oss-120b",
    tools=tools,
    input="Show the calendar events for 2026-04-02.",
)

# Execute the requested function
tool_outputs = []
for item in response.output:
    if item.type == "function_call" and item.name == "get_calendar_events":
        args = json.loads(item.arguments)
        events = get_calendar_events(**args)
        tool_outputs.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps({"events": events}),
        })

# Follow-up request
final = client.responses.create(
    model="openai.gpt-oss-120b",
    instructions="Summarize the schedule clearly for the user.",
    tools=tools,
    input=tool_outputs,
    previous_response_id=response.id,
)

print(final.output_text)

Example: Client-Managed State

In this pattern, the application keeps the full exchange and resubmits it with the follow-up request.

import json

tools = [
    {
        "type": "function",
        "name": "get_calendar_events",
        "description": "Return calendar events scheduled for a specific date.",
        "parameters": {
            "type": "object",
            "properties": {
                "date": {
                    "type": "string",
                    "description": "Date to query, for example 2026-04-02"
                }
            },
            "required": ["date"],
        },
    },
]

def get_calendar_events(date):
    # Replace this with actual calendar logic or an API call
    return [
        {"time": "09:00", "title": "Team standup"},
        {"time": "13:00", "title": "Design review"},
        {"time": "16:00", "title": "Project check-in"},
    ]

conversation = [
    {"role": "user", "content": "Show the calendar events for 2026-04-02."}
]

response = client.responses.create(
    model="openai.gpt-oss-120b",
    tools=tools,
    input=conversation,
)

conversation += response.output

for item in response.output:
    if item.type == "function_call" and item.name == "get_calendar_events":
        args = json.loads(item.arguments)
        events = get_calendar_events(**args)
        conversation.append({
            "type": "function_call_output",
            "call_id": item.call_id,
            "output": json.dumps({"events": events}),
        })

final = client.responses.create(
    model="openai.gpt-oss-120b",
    instructions="Summarize the schedule clearly for the user.",
    tools=tools,
    input=conversation,
)

print(final.output_text)

Function calling is a strong option when the application must remain responsible for execution, access control, and integration logic, while still allowing the model to request the information it needs.