// getting started · 5 min

Your first call

Ringside speaks the OpenAI wire format, so the fastest path is to take code you already have, change two lines, and watch it run against Ringside instead. Here is that, then the same call in raw curl so you can see what is actually going over the wire.

Get a key

Sign up, open the dashboard, and create an API key. It looks like ko_live_.... Treat it like a password: it can spend money, so keep it on a server and out of your frontend. Browsers get a different, short-lived token (covered later). Put the key in an environment variable rather than pasting it into code.

Point an SDK at Ringside

Any OpenAI SDK works. You change the base URL to Ringside and use your Ringside key. Nothing else about your code changes: the same chat.completions.create call, the same response shape.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.fightclub.pro/v1",   # <- the only real change
    api_key=os.environ["FC_API_KEY"],          # <- your Ringside key
)

resp = client.chat.completions.create(
    model="fc:openai/gpt-4o-mini",
    messages=[{"role": "user", "content": "Say hello in one short sentence."}],
)
print(resp.choices[0].message.content)

What came back

The response is the OpenAI chat-completion shape you already parse: a choices array with a message, plus a usage block with token counts. So existing parsing code keeps working unchanged. Ringside adds a couple of response headers, like which concrete model a match: reference resolved to, but you can ignore those until you need them.

{
  "id": "chatcmpl_...",
  "object": "chat.completion",
  "model": "openai/gpt-4o-mini",
  "choices": [
    { "index": 0, "finish_reason": "stop",
      "message": { "role": "assistant", "content": "Hello, good to meet you." } }
  ],
  "usage": { "prompt_tokens": 14, "completion_tokens": 7, "total_tokens": 21 }
}

Streaming, if you want tokens as they arrive

Set stream: true and you get server-sent events exactly like OpenAI: a series of chunk deltas ending with [DONE]. The SDKs expose it as an async iterator. Nothing Ringside-specific here; it is the standard streaming contract.

When a call fails

Errors come back in the OpenAI error envelope: an HTTP status plus a JSON error object with a type, a code and a message. A 401 means the key is wrong. A 402 means a wallet is empty or a budget was hit (more on that next page). A 429 is rate limiting, back off and retry. A 400 is a malformed request, read the message. Always branch on the code, not the prose message, since messages can change.

You now have a working call. The next page is the one piece of Ringside that is genuinely different from talking to OpenAI directly: how spend is tracked per end-customer.