SDK Quick Start
Get started with the @cova/gateway SDK for per-call FinOps metadata
The @cova/gateway SDK (TypeScript) and cova-gateway SDK (Python) are thin
header helpers that attach per-call FinOps metadata — user IDs, prompt IDs,
custom properties, and fallback chains — to your LLM requests through the
CoreValue AI Gateway.
The SDK is a thin header helper — it does NOT wrap or intercept your LLM
calls. You still use the OpenAI SDK (or any HTTP client) to make requests.
The SDK only builds the Cova-* headers and parses the gateway response
metadata. See D-5: SDK Scope for the rationale.
Prerequisites
- Sign up for a CoreValue account
- Generate an API key at API Keys
— it will start with
sk-cova- - Set your gateway base URL to
https://gateway.corevalue.dev/v1
Install
npm install @cova/gateway
# peer dependency: openai ^5.10.2
npm install openaipip install cova-gateway
# runtime dependency: httpx >=0.28.0buildHeaders / build_headers
Build a Cova-* header record to attach to any HTTP client. This is the
simplest way to add FinOps metadata to your requests.
import { buildHeaders } from "@cova/gateway";
const headers = buildHeaders({
userId: "user_abc123",
promptId: "prompt_42",
properties: {
region: "us-east-1",
tier: "premium",
},
fallbacks: ["groq/llama-3.1-70b", "together/meta-llama/Llama-3-70B"],
});
// headers === {
// "Cova-User-Id": "user_abc123",
// "Cova-Prompt-Id": "prompt_42",
// "Cova-Property-Region": "us-east-1",
// "Cova-Property-Tier": "premium",
// "Cova-Fallbacks": '["groq/llama-3.1-70b","together/meta-llama/Llama-3-70B"]',
// }from cova_gateway import build_headers
headers = build_headers(
user_id="user_abc123",
prompt_id="prompt_42",
properties={
"region": "us-east-1",
"tier": "premium",
},
fallbacks=["groq/llama-3.1-70b", "together/meta-llama/Llama-3-70B"],
)
# headers === {
# "Cova-User-Id": "user_abc123",
# "Cova-Prompt-Id": "prompt_42",
# "Cova-Property-Region": "us-east-1",
# "Cova-Property-Tier": "premium",
# "Cova-Fallbacks": '["groq/llama-3.1-70b","together/meta-llama/Llama-3-70B"]',
# }Pass these headers to your HTTP client alongside Authorization: Bearer $COVA_API_KEY.
wrap
Wrap a raw provider response and its headers into a CovaResponse<T> that
includes the parsed CovaGatewayMeta (request ID, provider, model, cost, etc.).
import { wrap } from "@cova/gateway";
// `response` is the raw fetch Response from the gateway
const data = await response.json();
const result = wrap(data, response.headers);
console.log(result.data); // raw provider response
console.log(result.gateway); // CovaGatewayMeta
console.log(result.gateway.requestId); // "550e8400-..."
console.log(result.gateway.requestCost); // 0.0015from cova_gateway import wrap
# `response` is the raw httpx.Response from the gateway
data = response.json()
result = wrap(data, dict(response.headers))
print(result.data) # raw provider response
print(result.gateway) # CovaGatewayMeta
print(result.gateway.request_id) # "550e8400-..."
print(result.gateway.request_cost) # 0.0015streamChat / stream_chat
Stream a chat completion through the OpenAI client while automatically
capturing the gateway's final SSE cova frame. The last yielded value is
{ cova: CovaGatewayMeta } — all prior values are normal OpenAI chunks.
import OpenAI from "openai";
import { streamChat } from "@cova/gateway";
const client = new OpenAI({
baseURL: "https://gateway.corevalue.dev/v1",
apiKey: process.env.COVA_API_KEY, // sk-cova-XXXXXXXXXXXXXXXX
});
const stream = streamChat(
client,
{
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello, world!" }],
stream: true,
},
{
userId: "user_abc123",
properties: { feature: "chat" },
}
);
for await (const chunk of stream) {
if ("cova" in chunk) {
// Final frame — gateway metadata
console.log(chunk.cova.requestCost); // 0.0015
console.log(chunk.cova.provider); // "openai"
} else {
// Normal OpenAI streaming chunk
process.stdout.write(chunk.choices?.[0]?.delta?.content ?? "");
}
}import asyncio
from openai import AsyncOpenAI
from cova_gateway import stream_chat
client = AsyncOpenAI(
base_url="https://gateway.corevalue.dev/v1",
api_key="sk-cova-XXXXXXXXXXXXXXXX", # os.environ["COVA_API_KEY"]
)
async def main():
stream = stream_chat(
client,
{
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello, world!"}],
"stream": True,
},
cova_opts={
"user_id": "user_abc123",
"properties": {"feature": "chat"},
},
)
async for chunk in stream:
if "cova" in chunk:
# Final frame — gateway metadata
print(chunk["cova"].request_cost) # 0.0015
print(chunk["cova"].provider) # "openai"
else:
# Normal OpenAI streaming chunk
delta = chunk.get("choices", [{}])[0].get("delta", {})
print(delta.get("content", ""), end="")
asyncio.run(main())fetchNative / fetch_native
Make a direct HTTP request to the gateway and get back both the raw response
and the parsed CovaGatewayMeta. Useful when you're not using the OpenAI SDK.
fetchNative is async in TypeScript (uses global fetch).
fetch_native is synchronous in Python (uses httpx.Client).
import { fetchNative } from "@cova/gateway";
const { response, gateway } = await fetchNative(
"https://gateway.corevalue.dev/v1/chat/completions",
{
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${process.env.COVA_API_KEY}`,
},
body: JSON.stringify({
model: "gpt-4o-mini",
messages: [{ role: "user", content: "Hello!" }],
}),
cova: {
userId: "user_abc123",
properties: { feature: "chat" },
},
}
);
const data = await response.json();
console.log(gateway.requestId); // "550e8400-..."
console.log(gateway.requestCost); // 0.0015from cova_gateway import fetch_native
response, gateway = fetch_native(
"https://gateway.corevalue.dev/v1/chat/completions",
init={
"method": "POST",
"headers": {
"Content-Type": "application/json",
"Authorization": "Bearer sk-cova-XXXXXXXXXXXXXXXX",
},
"json": {
"model": "gpt-4o-mini",
"messages": [{"role": "user", "content": "Hello!"}],
},
},
cova_opts={
"user_id": "user_abc123",
"properties": {"feature": "chat"},
},
)
data = response.json()
print(gateway.request_id) # "550e8400-..."
print(gateway.request_cost) # 0.0015CovaHeaderOptions
All SDK functions accept the same options object for per-call metadata:
| Field | TS name | Python name | Type | Validation |
|---|---|---|---|---|
| User ID | userId | user_id | string | [a-zA-Z0-9_\-:.], max 256 |
| Prompt ID | promptId | prompt_id | string | [a-zA-Z0-9_\-:.], max 256 |
| Properties | properties | properties | Record<string, string> | name [a-zA-Z0-9_] max 64; value max 256 |
| Fallbacks | fallbacks | fallbacks | string[] | max 5 models, compact JSON |
CovaGatewayMeta
The gateway returns metadata via response headers (non-streaming) or the final SSE frame (streaming). The SDK parses it into this shape:
| Field | TS | Python | Source |
|---|---|---|---|
| Request ID | requestId | request_id | Cova-Id |
| Provider | provider | provider | Cova-Provider |
| Model | model | model | Cova-Model |
| Status | status | status | Cova-Status |
| Request Cost | requestCost | request_cost | Cova-Request-Cost |
| Estimated Cost | estimatedCost | estimated_cost | Cova-Request-Cost-Estimate |
| Credits Remaining | creditsRemaining | credits_remaining | Cova-Credits-Remaining |
| Gateway Mode | gatewayMode | gateway_mode | Cova-Gateway-Mode |
| Translation Warning | translationWarning | translation_warning | Cova-Translation-Warning |
Next Steps
SDK Migration
Migrating from @cova/sdk or @cova/async? See the side-by-side migration guide.
Provider Routing
Learn how the gateway routes requests across major providers.
Header Directory
Full reference for all Cova-* request and response headers.