Skip to content

Developers

SDKs

Use the official OpenAI SDKs for JavaScript and Python against Cairva, including the cairva metering field.

On this page

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.

SettingValue
Base URLhttps://cairva.xyz/v1
API keyYour Cairva key, cv_live_… or cv_test_…
ModelThe id from GET /v1/models

JavaScript and TypeScript

Terminal
npm install openai
JavaScript
import 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:

TypeScript
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

Terminal
pip install openai
Python
import 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;
}

Both 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.