Use the OpenAI SDK

Send requests through CoreValue with the OpenAI SDK you already use: change the base URL and the key, and keep your code.

CoreValue's gateway speaks the OpenAI API. Point the OpenAI SDK at it and use your CoreValue key in place of your OpenAI key. Every request is then checked against your budgets, sent to OpenAI with the provider key stored in CoreValue, and logged with its cost.

Before you start: add your OpenAI key under Gateway → Provider keys and create a CoreValue key under Governance → Keys. The Quickstart walks through both.

Change two lines

import os
from openai import OpenAI

client = OpenAI(
    base_url="https://gateway.corevalue.dev/v1",
    api_key=os.environ["COVA_API_KEY"],  # sk-cova-…
)

response = client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(response.choices[0].message.content)
import OpenAI from "openai";

const client = new OpenAI({
  baseURL: "https://gateway.corevalue.dev/v1",
  apiKey: process.env.COVA_API_KEY, // sk-cova-…
});

const response = await client.chat.completions.create({
  model: "gpt-4o-mini",
  messages: [{ role: "user", content: "Hello!" }],
});
console.log(response.choices[0].message.content);

Both SDKs read these when you construct the client with no arguments:

OPENAI_BASE_URL=https://gateway.corevalue.dev/v1
OPENAI_API_KEY=sk-cova-…

The rest of your code stays as it is. Streaming and tool calls work as they do against OpenAI.

What works through the gateway

EndpointNotes
chat.completionsIncluding streaming.
completionsLegacy completions.
embeddings
images and audio
responsesSupported for a subset of models and providers. See Responses API.

Call other providers with the same client

To reach Anthropic, Groq, Google and the rest through the OpenAI SDK, use the base URL https://gateway.corevalue.dev/gateway/v1 and put the provider in front of the model name:

client = OpenAI(
    base_url="https://gateway.corevalue.dev/gateway/v1",
    api_key=os.environ["COVA_API_KEY"],
)

client.chat.completions.create(
    model="groq/llama-3.3-70b-versatile",
    messages=[{"role": "user", "content": "Hello!"}],
)

On the plain /v1 base URL the prefix is not read, and the request goes to OpenAI. The full list of prefixes is on Other providers.

Tag requests with who and what they are for

Send attribution headers so spend can be split, and budgeted, by customer, feature or team:

client.chat.completions.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
    extra_headers={
        "Cova-Customer-Id": "acme-corp",
        "Cova-Feature-Id": "support-bot",
    },
)
await client.chat.completions.create(
  { model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello!" }] },
  { headers: { "Cova-Customer-Id": "acme-corp", "Cova-Feature-Id": "support-bot" } },
);

Set them once on the client with default_headers (Python) or defaultHeaders (TypeScript) if every request from a service shares them. See Tag your traffic and the full list in Headers.

Read the cost of a request

Every response carries Cova-Id and, for non-streaming requests, Cova-Request-Cost in US dollars. Read them through the SDK's raw response:

raw = client.chat.completions.with_raw_response.create(
    model="gpt-4o-mini",
    messages=[{"role": "user", "content": "Hello!"}],
)
print(raw.headers.get("Cova-Request-Cost"))
response = raw.parse()
const { data, response } = await client.chat.completions
  .create({ model: "gpt-4o-mini", messages: [{ role: "user", content: "Hello!" }] })
  .withResponse();
console.log(response.headers.get("Cova-Request-Cost"));

For a streamed request, the cost arrives after the stream ends. See Request cost lookup.

When a budget runs out

If a budget is set to block, the gateway refuses the request with HTTP 429 before it reaches OpenAI, and the SDK raises its usual rate-limit error. The OpenAI SDK retries a 429 by default, so a refused request may be tried again a few times before the error reaches your code. See Errors and Budgets and limits.

On this page