Three Correct Ways to Connect OpenAI Agents SDK to a Custom API

The OpenAI Agents SDK needs tracing disabled and Chat Completions enabled to connect to third-party gateways; three approaches available.
The OpenAI Agents SDK defaults to the Responses API and OpenAI tracing, causing 404s and tracing errors when connecting to third-party gateways that implement only /v1/chat/completions. Fix it in two steps: set_tracing_disabled(True) and set_default_openai_api("chat_completions"). The author validated three approaches on openai-agents 0.23.1: explicit OpenAIChatCompletionsModel, a process-level default client, or OpenAIProvider(use_responses=False) via RunConfig. Also ensure base_url ends at /v1, and note that function tools work normally on Chat Completions.
Title
Three Correct Ways to Connect OpenAI Agents SDK to a Custom API
Meta Description
The OpenAI Agents SDK defaults to the Responses API and OpenAI tracing, which leads to 404s when connecting to third-party compatible gateways. This article covers three configuration approaches (OpenAIChatCompletionsModel, a process-level default client, and OpenAIProvider), plus base_url path rules, tool-calling verification, and a checklist to help developers quickly adapt to custom APIs.
The OpenAI Agents SDK (PyPI package name openai-agents) gives Python developers a clean framework for tool-calling agents. But its defaults are oriented toward OpenAI's official services: it communicates via the Responses API and sends tracing data back to OpenAI. The moment you point it at a third-party OpenAI-compatible gateway without changing these defaults, you'll hit 404s that look like "wrong model ID" errors, or mysterious network errors from the tracer.
This article is based on openai-agents version 0.23.1 and validates three viable approaches against a local mock service that implements only /v1/chat/completions. The examples use the APIClaw gateway (built by the author; evaluate it at your own discretion), with a base URL of https://apiclaw.biz/v1. You can freely substitute the host, key, and model with the /v1 endpoints of vLLM, LiteLLM, Ollama, or any server that supports Chat Completions.

Two Traps in the Default Configuration
Trap One: API Shape Mismatch
set_default_openai_api defaults to "responses", but most third-party gateways implement only /v1/chat/completions and do not provide /v1/responses. Sending a Responses request to a Chat-only gateway returns a NotFoundError (404) directly.
Responses API is OpenAI's next-generation interface introduced in 2025. Compared with Chat Completions, it leans more toward "stateful conversations" and "built-in tool orchestration," and both its request body and response structure differ. Third-party gateways (vLLM, LiteLLM, Ollama, etc.) generally implement /v1/chat/completions as a compatibility layer because it is the de facto universal protocol in the ecosystem and is widely supported; /v1/responses appeared later, and most gateways have not caught up yet. The SDK's set_default_openai_api parameter determines which route it calls, so setting it to "chat_completions" essentially makes the SDK fall back to the most compatible protocol layer.
Trap Two: Nowhere for Tracing Data to Go
Unless you explicitly call set_tracing_disabled(True), the SDK will try to export tracing data using your OpenAI API key. On a custom gateway, that key either doesn't exist or is invalid for OpenAI's tracing endpoint, so chat works fine but the logs are full of noise.
Before troubleshooting model IDs, fix these two things first:
from agents import set_default_openai_api, set_tracing_disabled
set_tracing_disabled(True)
set_default_openai_api("chat_completions")
The tracing mechanism built into the Agents SDK packages each run's agent calls, tool calls, and handoffs into a trace, which by default is exported to OpenAI's tracing endpoint for visual debugging in the official dashboard. This process is independent of the conversation requests themselves, so even if chat requests already point to a third-party gateway, tracing export still attempts to access the OpenAI domain and authenticate with your OpenAI key. On a self-hosted or third-party gateway, that key is usually not a valid OpenAI key, so the export fails and repeatedly reports errors in the logs. set_tracing_disabled(True) simply disables this optional observability feature and does not affect the agent's reasoning or tool-calling behavior.
Approach A: OpenAIChatCompletionsModel (Most Explicit)
Pass an AsyncOpenAI client configured with a custom base_url into OpenAIChatCompletionsModel, and the agent will never touch the Responses path.
import asyncio
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIChatCompletionsModel, set_tracing_disabled
set_tracing_disabled(True)
client = AsyncOpenAI(
base_url="https://apiclaw.biz/v1", # note the /v1 included
api_key="YOUR_API_KEY",
)
model = OpenAIChatCompletionsModel(
model="YOUR_MODEL_ID",
openai_client=client,
)
agent = Agent(
name="assistant",
instructions="Reply in one short paragraph.",
model=model,
)
async def main():
result = await Runner.run(agent, "What is a base URL in an OpenAI client?")
print(result.final_output)
asyncio.run(main())
If you don't want to introduce asyncio at the call site, Runner.run_sync(...) works identically.
Approach B: Setting a Process-Level Default Client
When all agents in the process should use the same gateway, setting the global default once is cleaner.
from openai import AsyncOpenAI
from agents import (
Agent,
Runner,
set_default_openai_client,
set_default_openai_api,
set_tracing_disabled,
)
set_tracing_disabled(True)
set_default_openai_client(
AsyncOpenAI(base_url="https://apiclaw.biz/v1", api_key="YOUR_API_KEY")
)
set_default_openai_api("chat_completions")
agent = Agent(
name="assistant",
instructions="Be concise.",
model="YOUR_MODEL_ID", # now just pass the string directly
)
result = Runner.run_sync(agent, "List three reasons to pin a base URL.")
print(result.final_output)
Order matters: if the default API is still "responses", the same client will still send requests to /v1/responses, and a Chat-only gateway will still return 404.
Approach C: OpenAIProvider + use_responses=False
When you need to pass a provider object through RunConfig(model_provider=...) rather than modifying global configuration, OpenAIProvider is the standard approach.
from openai import AsyncOpenAI
from agents import Agent, Runner, OpenAIProvider, RunConfig, set_tracing_disabled
set_tracing_disabled(True)
client = AsyncOpenAI(base_url="https://apiclaw.biz/v1", api_key="YOUR_API_KEY")
provider = OpenAIProvider(openai_client=client, use_responses=False)
agent = Agent(
name="assistant",
instructions="Be concise.",
model="YOUR_MODEL_ID",
)
result = Runner.run_sync(
agent,
"Explain chat completions vs responses in one sentence.",
run_config=RunConfig(model_provider=provider),
)
print(result.final_output)
use_responses=False makes get_model return OpenAIChatCompletionsModel. You can also pass base_url= and api_key= directly to OpenAIProvider, saving you from pre-building the client.
RunConfig is the per-run configuration object for Runner.run / run_sync. It can override the model provider, model settings, input filters, and so on without changing process-level global state. OpenAIProvider encapsulates the logic of "how to construct a model object from a model name": when use_responses=True (the default), get_model returns a model wrapper that goes through the Responses route; setting it to False returns OpenAIChatCompletionsModel. The advantage of this approach is that the configuration travels with the call, so different agents in the same process can use different providers — ideal for scenarios with multiple gateways coexisting or where test and production environments are mixed.
/v1 Path Rules for base_url
The OpenAI Python client appends /chat/completions to the base_url you provide. Getting the path wrong has immediate consequences:
| base_url | Actual request path | Typical result on an OpenAI-layout gateway |
|---|---|---|
https://apiclaw.biz/v1 | /v1/chat/completions | Success |
https://apiclaw.biz | /chat/completions | 404 |
https://apiclaw.biz/v1/chat/completions | /v1/chat/completions/chat/completions | 404 |
Always stop at /v1; never paste the full chat endpoint into base_url.
What You'll See If You Keep Responses
On the author's Chat-only mock service, keeping the default "responses" throws:
openai.NotFoundError: Error code: 404 -
{'error': {'message': 'Responses API not available on this gateway',
'type': 'invalid_request_error'}}
This is not a wrong model ID — the SDK is calling a different route. After switching to Chat Completions (any of the approaches above), retry with the same model string.
Function Tools Work as Usual on Chat Completions
Function tools go through the same model wrapper, so functionality is unaffected. Here's a minimal example:
from agents import Agent, Runner, OpenAIChatCompletionsModel, function_tool, set_tracing_disabled
from openai import AsyncOpenAI
set_tracing_disabled(True)
client = AsyncOpenAI(base_url="https://apiclaw.biz/v1", api_key="YOUR_API_KEY")
@function_tool
def add(a: int, b: int) -> int:
"""Add two integers."""
return a + b
agent = Agent(
name="math",
instructions="Use the add tool for arithmetic.",
model=OpenAIChatCompletionsModel(model="YOUR_MODEL_ID", openai_client=client),
tools=[add],
)
print(Runner.run_sync(agent, "What is 7 + 5?").final_output)
If the gateway strips tool_calls from the chat response, the agent will get stuck in a loop or give an answer without tool calls — that's a server capability issue, not an Agents SDK base_url defect. Before diving deep into debugging the runner, verify with a raw /v1/chat/completions request that includes a "tools" field.
Practical Checklist
pip install openai-agents(version 0.23.1 was tested in this article).- Unless you genuinely want to send tracing data to OpenAI, call
set_tracing_disabled(True). - Force Chat Completions: pick one of
OpenAIChatCompletionsModel,set_default_openai_api("chat_completions"), orOpenAIProvider(..., use_responses=False). base_urlends with/v1, not/v1/chat/completions.- The model ID is the full string from the gateway's model list, not a short alias.
- Before wrapping it in an
Agent, confirm that a bareclient.chat.completions.create(...)call works.
Once these six items are in place, the Agents SDK stops fighting the gateway, and you can focus on refining your instructions, tools, and agent handoff logic.
One-line Summary
The OpenAI Agents SDK requires disabling tracing and switching to Chat Completions when connecting to third-party gateways, with three approaches to choose from.
Paragraph Summary
The article points out that the OpenAI Agents SDK defaults to communicating via the Responses API and sending tracing data back to OpenAI. When connecting to third-party compatible gateways that implement only /v1/chat/completions, this produces 404s and tracing errors that are easily mistaken for wrong model IDs. The fix takes just two steps: call set_tracing_disabled(True) to disable tracing, then use set_default_openai_api("chat_completions") to switch the API shape. The author validated three approaches on version 0.23.1 of openai-agents: explicitly constructing an OpenAIChatCompletionsModel, setting a process-level default client, or passing OpenAIProvider(use_responses=False) via RunConfig. The article also emphasizes that base_url must end at /v1, that function tools work as usual on Chat Completions, and that a gateway stripping tool_calls is a server capability issue.
Related articles

Chain of Thought Isn't Just for AI: How Humans Can Use CoT to Improve Thinking Quality
Chain of Thought isn't just a prompt trick for large models. Starting from a Hacker News discussion, this article analyzes why CoT works for human thinking too, breaks down actionable ways to transfer it, and highlights the key differences between human CoT and machine CoT.
Cloudflare Teams Up with OpenAI: Closi…
Cloudflare Teams Up with OpenAI: Closing the Loop from Vulnerability Discovery to Defense with AI
Cloudflare uses OpenAI Daybreak to investigate security vulnerabilities and generate reviewable remediation plans, while developers use Codex to boost coding efficiency and quality.

Orca Multi-Agent Orchestration in Practice: A Guide to Parallel Collaboration with Claude and Codex
Orca is Stable AI's free open-source agent workbench supporting 34 agents like Claude Code and Codex in parallel. Learn its Git worktree isolation, multi-model orchestration, and mobile management.