# OpenAI Agents SDK on a Custom OpenAI-Compatible API: Chat Completions, Responses and the Tracing Trap

> Source: <https://ainexusdaily.vercel.app/article/2026-10-17-openai-agents-sdk-on-a-custom-openai-compatible-api-chat-completions-responses-a>
> Published: 2026-10-17 10:03:23+00:00

# OpenAI Agents SDK on a Custom OpenAI-Compatible API: Chat Completions, Responses and the Tracing Trap

I'm Aman Kumar. The OpenAI Agents SDK (openai-agents on PyPI) is a clean way to run tool-calling agents in Python. Out of the box it talks to api.openai.com over the Responses API and ships traces back to OpenAI. Point it at another OpenAI-compatible server without changing those defaults and you ge

I'm Aman Kumar. The OpenAI Agents SDK (openai-agents on PyPI) is a clean way to run tool-calling agents in Python. Out of the box it talks to api.openai.com over the Responses API and ships traces back to OpenAI. Point it at another OpenAI-compatible server without changing those defaults and you get 404s that look like "the model is wrong" or mysterious network errors from the tracer. I wrote this against openai-agents 0.23.1 and verified the three working setups below on a local mock that only implements /v1/chat/completions. The examples use APIClaw, a gateway I build, so weigh that accordingly. Base URL is https://apiclaw.biz/v1. Copy the model ID from /v1/models or the model hub; I use YOUR_MODEL_ID below. On that hub you will see IDs like deepseek-v4-flash, deepseek-v4-pro or claude-sonnet-5-5. Crypto is on the site; other payment methods go through support. Swap host, key and model for whatever you run — vLLM, LiteLLM, Ollama's /v1 endpoint, or any server that speaks Chat Completions. Two defaults bite people: API shape. set_default_openai_api defaults to "responses". Most third-party gateways implement /v1/chat/completions, not /v1/responses. Hitting Responses on a chat-only gateway returns NotFoundError (404). Tracing. Unless you call set_tracing_disabled(True), the SDK tries to export traces using an OpenAI API key. On a custom gateway that key is either absent or not valid for OpenAI's trace endpoint, so you get noise even when chat works. Fix both before you debug model IDs. from agents import set_default_openai_api, set_tracing_disabled set_tracing_disabled(True) set_default_openai_api("chat_completions") Pass an AsyncOpenAI client with your base URL into OpenAIChatCompletionsModel. The agent never touches 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", # include /v1 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()) Runner.run_sync(...) works the same way if you do not want asyncio at the call site. When every agent in the process should use the same gateway, set the process defaults once. 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", # plain string is fine now ) result = Runner.run_sync(agent, "List three reasons to pin a base URL.") print(result.final_output) Order matters. If you leave the default API on "responses", the same client still posts to /v1/responses and a chat-only gateway 404s. OpenAIProvider is what RunConfig(model_provider=...) expects when you want a provider object instead of globals. 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 into OpenAIProvider instead of a prebuilt client. The OpenAI Python client appends /chat/completions to whatever you put in base_url. base_url Request path Typical result on an OpenAI-layout gateway https://apiclaw.biz/v1 /v1/chat/completions Works https://apiclaw.biz /chat/completions 404 https://apiclaw.biz/v1/chat/completions /v1/chat/completions/chat/completions 404 Always stop at /v1. Do not paste the full chat endpoint into base_url. On my chat-only mock, leaving the default API on "responses" raised: openai.NotFoundError: Error code: 404 - {'error': {'message': 'Responses API not available on this gateway', 'type': 'invalid_request_error'}} That is not a bad model ID. The SDK is calling a different route. Switch to chat completions (any of A/B/C above) and retry with the same model string. Function tools go through the same model wrapper. 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 a gateway strips tool_calls from chat responses, the agent will loop or answer without tools — that is a server capability issue, not an Agents SDK base-URL bug. Check one raw /v1/chat/completions request with "tools" in the body before you dig into the runner. pip install openai-agents (I tested 0.23.1). set_tracing_disabled(True) unless you intentionally send traces to OpenAI. Force Chat Completions: OpenAIChatCompletionsModel, or set_default_openai_api("chat_completions"), or OpenAIProvider(..., use_responses=False). base_url ends with /v1, not /v1/chat/completions. Model ID is the full string from the gateway's model list, not a short nickname. Confirm a plain client.chat.completions.create(...) works before wrapping it in Agent. Once those six are right, the Agents SDK stops fighting the gateway and you can focus on instructions, tools and handoffs.

## Key Takeaways

- •I'm Aman Kumar
- •This story was reported by **Dev.to** , covering developments in the**dev** space.
- •AI advancements continue to reshape industries — read the full article on Dev.to for complete coverage.

📖 Continue reading the full article:

[Read Full Article on Dev.to →](https://dev.to/amankumar_apiclaw/openai-agents-sdk-on-a-custom-openai-compatible-api-chat-completions-responses-and-the-tracing-184d)
