Why most providers speak OpenAI

When OpenAI shipped the chat.completions endpoint, it became the default shape for every provider that launched after. Today you can hit OpenRouter, Fireworks, Together, Groq, DeepSeek, and many others with the exact same OpenAI SDK, by changing the base_url and the model string.

Same SDK, three destinations

The AsyncOpenAI client talks to any OpenAI-compatible endpoint when you change base_url.

utils/llm_provider.py
python
from openai import AsyncOpenAI

# Same SDK, three destinations
openai = AsyncOpenAI(api_key=OPENAI_KEY)

openrouter = AsyncOpenAI(
    api_key=OPENROUTER_KEY,
    base_url='https://openrouter.ai/api/v1',
)

fireworks = AsyncOpenAI(
    api_key=FIREWORKS_KEY,
    base_url='https://api.fireworks.ai/inference/v1',
)

# All three respond to the exact same call
response = await client.chat.completions.create(
    model=model_string,
    messages=[{'role': 'user', 'content': 'Hello'}],
)

The AsyncOpenAI client does not care who serves the request. Swap base_url and api_key and the wire protocol is identical.

Because compatibility is a spectrum. Tool calling, JSON mode, response_format, logprobs, and streaming cancellation behave differently across providers. The happy path is the same. The edges differ. Your abstraction is the place where you handle those differences in one file instead of every service.

Quiz: Quiz

Loading practice…