OpenRouter function calling lets a model propose tools and arguments while your application controls execution. Build a narrow tool contract, validate each call, and enforce the user’s permissions on the server.
Tool calling is a decision loop, not direct execution
A model can request a named tool with structured arguments. Your application—not the model—decides whether the tool exists, validates arguments, checks authorization, executes it, and sends the result back. That boundary is the core safety rule.
Checked October 15, 2026: tool support varies by model and provider. Confirm current capability in the model catalog and official tool-calling guide.
Define one narrow tool
tools=[{
"type":"function",
"function":{
"name":"get_order_status",
"description":"Look up one order owned by the authenticated user",
"parameters":{
"type":"object",
"properties":{"order_id":{"type":"string","pattern":"^ORD-[0-9]+$"}},
"required":["order_id"],
"additionalProperties":false
}
}
}]
Good tools are small, explicit, and least-privileged. Avoid a generic “run command” or “query database” tool.
Send tools with the conversation
payload={
"model":"openai/gpt-5.2",
"messages":[{"role":"user","content":"Where is order ORD-1042?"}],
"tools":tools,
"tool_choice":"auto"
}
The assistant may respond with a tool call instead of final prose. Parse the call, verify the requested name, and validate JSON arguments against the same schema.
Safe execution loop
ALLOWED={"get_order_status": get_order_status}
call=message["tool_calls"][0]
name=call["function"]["name"]
args=json.loads(call["function"]["arguments"])
if name not in ALLOWED: raise PermissionError("tool not allowed")
validate(instance=args,schema=TOOL_SCHEMAS[name])
result=ALLOWED[name](user_id=current_user.id,**args)
messages += [message,{
"role":"tool",
"tool_call_id":call["id"],
"content":json.dumps(result)
}]
# Send messages again for the final answer.
Bind the authenticated user or tenant on the server. Never trust a user ID supplied by the model.
Read versus write tools
| Tool type | Recommended control |
|---|---|
| Read-only lookup | Authorization, rate limit, bounded result |
| Draft/create | Preview plus idempotency key |
| Send/publish/pay/delete | Explicit human confirmation immediately before execution |
| Administrative | Usually exclude from model access |
Prevent prompt injection
Tool output is untrusted input. A webpage, email, or PDF can contain instructions telling the agent to disclose secrets or call another tool. Label external content as data, restrict available tools, separate planning from execution, and require confirmation for consequential actions.
Control loops and cost
- Maximum tool calls per run.
- Total deadline and token budget.
- Per-tool timeout and retry policy.
- Duplicate-call detection and idempotency.
- Audit log of requested, approved, executed, and returned data.
- Human escalation when the loop cannot progress.
Fallback compatibility
Every fallback model must support the same tool schema and response shape. If a provider lacks tools, fail clearly or route to a non-tool workflow. Do not let routing silently convert an agent into an ordinary chat response.
Troubleshooting
- No tool call: improve descriptions, confirm model support, and give a clear user task.
- Invalid arguments: tighten schema and use bounded repair.
- Repeated call: include the prior result and detect duplicate IDs/arguments.
- Unauthorized object: bind identity server-side and enforce ownership.
- Loop never ends: cap steps and create an escalation outcome.
OpenRouter function calling FAQ
Does the model execute my function?
No. It proposes a tool name and arguments. Your code owns validation, permission, execution, and errors.
Should every action require approval?
Low-risk reads may not. Sending, publishing, payment, deletion, or other irreversible actions should require an explicit final confirmation.
Read next
Use the structured outputs guide, AI agent security checklist, and pillar guide.
Official references
Documentation reviewed 15 October 2026. Examples illustrate the request pattern; confirm model availability and account settings before use. No uptime or performance benchmark is claimed.
