OpenAI Responses API function calling with a compatible gateway
The model proposes a call; your application owns execution. This guide shows the exact Responses shape and marks what still needs an authenticated model test.
What function calling does
The model does not run your function. It returns a structured function call; your application validates the arguments, runs approved code, and sends the result back. Treat model-produced arguments as untrusted input.
| Step | Responses API item | Your application |
|---|---|---|
| 1. Define | tools[] with a JSON Schema | Expose only approved functions |
| 2. Request | output[] may contain function_call | Parse name, arguments and call_id |
| 3. Execute | No external action is performed by the model | Authorize, validate, run and record the call |
| 4. Continue | Send function_call_output with the same call_id | Ask for the final response |
Verify the route, key and model first
Check GET /v1/models, then use an exact model ID returned to your key. On August 3, 2026, an unauthenticated production POST reached /v1/responses and returned 401 API_KEY_REQUIRED. This confirms route and authentication-middleware reachability only; it does not prove that a specific model supports function calling.
curl -sS https://monkeytheme.com/v1/models \ -H "Authorization: Bearer ***"
Send a minimal Responses API tool definition
OpenAI's current function-calling guide defines a Responses function directly inside tools. The schema below requires one string and rejects extra fields.
curl -sS https://monkeytheme.com/v1/responses \
-H "Authorization: Bearer ***" \
-H "Content-Type: application/json" \
-d '{
"model": "MODEL_ID_FROM_LIST",
"input": "What is the weather in Paris?",
"tools": [{
"type": "function",
"name": "get_weather",
"description": "Return current weather for a city.",
"parameters": {
"type": "object",
"properties": {
"city": {"type": "string"}
},
"required": ["city"],
"additionalProperties": false
},
"strict": true
}]
}'With strict mode, every property must be listed in required and each object must set additionalProperties to false. Represent an optional value with a type that includes null.
Execute calls and return their results
Responses can contain zero, one or several function calls. Iterate over all output items instead of assuming the first item is text.
import json
from openai import OpenAI
client = OpenAI(
api_key="YOUR_KEY",
base_url="https://monkeytheme.com/v1",
)
response = client.responses.create(
model="MODEL_ID_FROM_LIST",
input="What is the weather in Paris?",
tools=[weather_tool],
)
next_input = list(response.output)
for item in response.output:
if item.type != "function_call":
continue
args = json.loads(item.arguments)
result = dispatch_approved_function(item.name, args)
next_input.append({
"type": "function_call_output",
"call_id": item.call_id,
"output": json.dumps(result),
})
final = client.responses.create(
model="MODEL_ID_FROM_LIST",
input=next_input,
tools=[weather_tool],
)
print(final.output_text)dispatch_approved_function is application code, not an SDK helper. It should reject unknown function names and validate authorization before doing anything outside the process.
Do not confuse Responses and Chat Completions shapes
| Detail | Responses | Chat Completions |
|---|---|---|
| Function definition | Function fields sit directly in the tools[] item | Function fields sit under tools[].function |
| Returned call | output[] item with type function_call | choices[0].message.tool_calls[] |
| Correlation field | call_id | tool_call_id when returning a tool message |
| Function result | function_call_output input item | role: tool message |
Put safety checks around the executor
- Allowlist function names; never map a model-supplied name to arbitrary code.
- Parse JSON, validate again server-side and reject unknown fields.
- Apply the current user's authorization to every resource ID.
- Require confirmation for destructive or externally visible actions.
- Use idempotency keys for writes and keep an audit record of the call ID.
- Return bounded, redacted output. Do not feed secrets back into the model context.
Sources and related guides
FAQ
Does the model execute my function?
No. The model returns a structured call. Your application decides whether to run it and sends the result back.
Does a 401 response prove function calling works?
No. It only proves the request reached the authentication layer. Use a real key and an exact model ID to test function calling.
Should I trust strict mode as an authorization check?
No. Strict mode constrains the argument schema. Your application must still authenticate the user, authorize resources and validate business rules.
Can one response contain several function calls?
Yes. OpenAI advises applications to assume zero, one or multiple calls and iterate over the returned call items.
Can I use the Chat Completions tool shape with Responses?
No. The function definition, returned call and tool-result messages use different shapes. Convert them explicitly.