Developers
SDKs
Use the official OpenAI SDKs for JavaScript and Python against Cairva, including the cairva metering field.
Cairva doesn't ship its own SDK. Use the official OpenAI SDKs: the gateway speaks their format, so you change three things and keep the rest of your code.
| Setting | Value |
|---|---|
| Base URL | https://cairva.xyz/v1 |
| API key | Your Cairva key, cv_live_… or cv_test_… |
| Model | The id from GET /v1/models |
JavaScript and TypeScript
npm install openaiimport OpenAI from "openai";
const client = new OpenAI({
apiKey: process.env.CAIRVA_API_KEY,
baseURL: "https://cairva.xyz/v1",
});
const completion = await client.chat.completions.create({
model: "gemma4:e2b",
messages: [{ role: "user", content: "Summarise this ticket in one line." }],
max_tokens: 200,
});
console.log(completion.choices[0].message.content);The SDK keeps fields it doesn't know about on the object, so completion.cairva holds Cairva's metering details. In TypeScript, read it through a narrow type of your own:
type CairvaMeta = {
request_id: string;
allocation_id: string;
service_mode: "live" | "sandbox";
usage_source: "provider_reported" | "sandbox_estimate" | "pending";
remaining: { input: number; output: number };
};
function cairvaMeta(response: object): CairvaMeta | undefined {
return "cairva" in response ? (response.cairva as CairvaMeta) : undefined;
}
console.log(cairvaMeta(completion)?.remaining.output);Python
pip install openaiimport os
from openai import OpenAI
client = OpenAI(
api_key=os.environ["CAIRVA_API_KEY"],
base_url="https://cairva.xyz/v1",
)
completion = client.chat.completions.create(
model="gemma4:e2b",
messages=[{"role": "user", "content": "Summarise this ticket in one line."}],
max_tokens=200,
)
print(completion.choices[0].message.content)
print(completion.model_extra["cairva"]["remaining"])The Python SDK puts extra response fields in model_extra, so the metering object is completion.model_extra["cairva"]. On a streamed chunk it's chunk.model_extra["cairva"] on the final chunk.
Errors in the SDKs
Cairva errors arrive as the SDK's normal API errors. The product code is on the error:
try {
await client.chat.completions.create({ model: "gemma4:e2b", messages });
} catch (err) {
if (err instanceof OpenAI.APIError && err.code === "allocation_exhausted") {
// Out of allowance: alert someone, don't retry.
}
throw err;
}import openai
try:
client.chat.completions.create(model="gemma4:e2b", messages=messages)
except openai.APIStatusError as err:
if err.code == "allocation_exhausted":
pass # Out of allowance: alert someone, don't retry.
raiseBoth SDKs retry 429 and 5xx responses on their own and honour Retry-After. Leave that on. Don't retry 402 or 403. See Errors.
Other clients
Any HTTP client works. Send Authorization: Bearer <key> and JSON bodies to the endpoints in the API reference. Tools built on the OpenAI SDKs usually accept a custom base URL and key the same way. Check that they don't depend on tool calling or structured output, which Cairva doesn't support. See OpenAI compatibility.