Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.coval.dev/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Coval SDKs are generated from the public OpenAPI specs that power this API reference, so the surface area stays in sync with what the API actually accepts. On top of the generated client we ship hand-written ergonomics — auth, retries, pagination, and typed errors — for the calls you make most often.

TypeScript

@coval/sdk on npm. Production-grade today: lowercase x-api-key auth, retry-with-backoff, async pagination, typed errors.

Python

coval-sdk on PyPI. Demo-grade today — generated urllib3 client without the wrapper layer. Parity with the TypeScript ergonomics is in flight.
Both SDKs are MIT-licensed and live in coval-ai/coval-examples. A weekly cron regenerates them from the OpenAPI specs every Monday at 09:00 UTC.

Install

npm install @coval/sdk
If you want to track the very latest spec before a release lands on npm or PyPI, you can install directly from the source repo:
# npm has no native "install from a git subdirectory" syntax, so clone + install:
git clone https://github.com/coval-ai/coval-examples.git
cd coval-examples/typescript-sdk
npm install
npm run build
npm link        # or: npm pack && npm install ../coval-examples/typescript-sdk/coval-sdk-*.tgz

Quick start

import { CovalClient } from '@coval/sdk';

const coval = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
});

const page = await coval.agents.listAgents({ pageSize: 50 });
for (const agent of page.agents ?? []) {
  console.log(agent.id, agent.display_name);
}
The TypeScript client exposes every v1 API resource as a property on CovalClientcoval.agents, coval.conversations, coval.simulations, coval.traces, coval.metrics, and so on (22 resources total). The Python client is split into one *Api class per resource (AgentsApi, ConversationsApi, SimulationsApi, …) constructed against a shared ApiClient.

Auth

The Coval API gateway requires the header x-api-keylowercase. Uppercase X-API-Key is rejected with Missing API Key.
// Handled automatically — the CovalClient middleware sets the header for you.
const coval = new CovalClient({ apiKey: process.env.COVAL_API_KEY! });
If you see {"message": "Missing API Key"} from the gateway, check that the header name is lowercase. The TypeScript SDK takes care of this for you; the Python SDK leaves it to your set_default_header call.

Errors

The TypeScript SDK raises typed errors so you can branch on transport vs. API failures:
import { CovalApiError, CovalNetworkError, CovalClient } from '@coval/sdk';

const coval = new CovalClient({ apiKey: process.env.COVAL_API_KEY! });

try {
  await coval.agents.getAgent({ agentId: 'ag_does_not_exist' });
} catch (err) {
  if (err instanceof CovalApiError) {
    console.error(`HTTP ${err.status} ${err.code ?? ''}: ${err.message}`);
    console.error(`  request_id: ${err.requestId ?? '-'}`);
    console.error(`  body: ${JSON.stringify(err.body)}`);
  } else if (err instanceof CovalNetworkError) {
    console.error(`Network failure after ${err.attempts} attempt(s): ${err.message}`);
  } else {
    throw err;
  }
}
CovalApiError shapestatus, code, message, requestId, body, url, method. The requestId is sourced from x-request-id, x-amzn-requestid, or the response body in that order — include it when you file a support ticket.

Python: --raw fallback for legacy data

The Python client uses strict pydantic v2 models for every response, including regex patterns on IDs (e.g., agent_id must match ^[A-Za-z0-9]{22}$). If your org has historical data that predates the current spec — say, an agent created back when IDs had a different shape — pydantic will raise a ValidationError mid-stream and you’ll lose the rest of the page. The fix is to call the *_without_preload_content variant of any method and parse the response yourself:
import json

resp = AgentsApi(client).list_agents_without_preload_content(page_size=50)
body = json.loads(resp.data.decode("utf-8"))
for a in body["agents"]:
    print(a.get("id"), a.get("display_name"))
Every generated method has a _without_preload_content sibling. The TypeScript SDK does not have this issue — its types are emitted as interface declarations with no runtime validation, so unknown fields pass through.

Retries

The TypeScript SDK retries with exponential backoff and jitter on transient failures. Defaults:
SettingDefaultNotes
Max attempts3Includes the first attempt.
Base delay200msEffective delay = base * 2^(attempt-1) plus jitter.
Max delay5000msCap on any single backoff.
Retryable statuses408, 429, 500, 502, 503, 504Plus network/transport errors.
Retry-AfterHonoredNumeric seconds or HTTP-date both accepted.
// Override
const coval = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
  retry: { maxAttempts: 5, baseDelayMs: 100, maxDelayMs: 10_000 },
});

// Disable entirely
const noRetry = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
  retry: false,
});
When all attempts are exhausted on a transport error, the wrapper throws CovalNetworkError. When a non-retryable status (e.g., 400, 404) comes back, it falls through to the normal error path and raises CovalApiError immediately.
Retry-with-backoff is TypeScript-only today. Python parity is on the roadmap — in the meantime, wrap your own calls with tenacity or a similar library.

Pagination

The Coval v1 API uses next_page_token-style pagination. The TypeScript SDK ships an async iterator that handles the loop for you:
import { CovalClient, paginate, collectAll } from '@coval/sdk';

const coval = new CovalClient({ apiKey: process.env.COVAL_API_KEY! });

// Iterate lazily across pages
for await (const agent of paginate({
  fetchPage: (pageToken) => coval.agents.listAgents({ pageToken, pageSize: 50 }),
  items: (page) => page.agents,
  nextToken: (page) => page.next_page_token,
})) {
  console.log(agent.id, agent.display_name);
}

// Or buffer everything into an array
const allAgents = await collectAll({
  fetchPage: (pageToken) => coval.agents.listAgents({ pageToken, pageSize: 50 }),
  items: (page) => page.agents,
  nextToken: (page) => page.next_page_token,
});
paginate and collectAll work with any list endpoint — provide fetchPage, items, and nextToken callbacks for the method you’re calling.
Pass maxPages to cap iteration. Useful when you want a quick preview of a large list without hitting the full backlog.
The Python SDK does not include a pagination helper yet — it’s on the roadmap. For now, use a while loop on next_page_token — see the list_agents.py example for the shape.

Customization

Base URL

Point the client at staging, a self-hosted gateway, or a regional endpoint:
const coval = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
  baseUrl: 'https://staging.api.coval.dev',
});

Middleware (TypeScript)

Inject request/response middleware after the auth and error layers — useful for logging, OpenTelemetry spans, or attaching request IDs you control:
const coval = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
  middleware: [
    {
      async pre(ctx) {
        console.log(`-> ${ctx.init.method} ${ctx.url}`);
      },
      async post(ctx) {
        console.log(`<- ${ctx.response.status} ${ctx.url}`);
      },
    },
  ],
});

Custom fetch

Swap the underlying fetch implementation — for example, to use undici with keepalive in a long-running Node process, or to stub network calls in tests:
import { fetch as undiciFetch, Agent } from 'undici';

const dispatcher = new Agent({ keepAliveTimeout: 60_000 });
const coval = new CovalClient({
  apiKey: process.env.COVAL_API_KEY!,
  fetch: ((url, init) => undiciFetch(url, { ...init, dispatcher })) as typeof fetch,
});

Versioning and regeneration

Both SDKs are generated from the same OpenAPI specs that this API reference is built from. On the source repo, a weekly cron regenerates the clients every Monday at 09:00 UTC and opens a PR if the specs have drifted.
  • Minor version bumps (0.2.x0.3.0) reflect spec evolution — new endpoints, new optional fields, additional response shapes. Generally safe to upgrade.
  • Major version bumps (0.x1.0) are reserved for breaking changes in the hand-written wrapper layer (CovalClient options, error class shapes, pagination helper signature). The generated surface follows the spec independently.
To regenerate locally:
git clone https://github.com/coval-ai/coval-examples.git
cd coval-examples
node scripts/bundle-spec.mjs       # pull and bundle the latest specs
bash scripts/generate-sdks.sh      # regenerate both clients
The TypeScript SDK is production-grade today. The Python SDK is currently demo-grade — the generated client without the wrapper layer. Wrapper parity (retry, pagination, typed errors) is on the roadmap. Until then, the Python --raw fallback documented above is the workaround for orgs whose data fails strict pydantic validation.

Going deeper

Source repo

Full SDK source, examples folder, and the generation scripts. Open issues here.

TypeScript examples

list-agents.ts, submit-conversation.ts — runnable end-to-end samples.

Python examples

list_agents.py with --raw fallback pattern for legacy data.

OpenAPI specs

The specs that power both SDKs are published at https://api.coval.dev/v1/openapi.

API keys

How to mint and rotate API keys from the dashboard.

CLI

Prefer the shell? coval-cli covers the same surface area.