Skip to main content

coval-sdk (Python)

Typed Python client for the Coval evaluation platform API. The API classes and Pydantic v2 models are generated from the same public OpenAPI specs that power the API reference. CovalClient adds authentication, safe retries, pagination, and one entry point for every public v1 resource.

Install

pip install coval-sdk

Requires Python 3.9+.

Quick start

import os

from coval_sdk import CovalClient, paginate

with CovalClient(os.environ["COVAL_API_KEY"]) as coval:
  for agent in paginate(
    coval.agents.list_agents,
    items_field="agents",
    page_size=50,
  ):
    print(agent.id, agent.display_name)

The client sends the required lowercase x-api-key header and defaults to https://api.coval.dev/v1.

Retries

GET, HEAD, and OPTIONS requests retry 408, 429, and transient 5xx responses up to three total attempts with exponential backoff. Mutating requests are not retried by default, which avoids duplicating side effects.

from coval_sdk import CovalClient

# Disable transport retries.
coval = CovalClient(api_key, retries=False)

# Use a custom base URL.
staging = CovalClient(api_key, base_url="https://staging.api.coval.dev/v1")

Connection reuse

Pooled connections idle for longer than max_idle_seconds (default 5.0) are closed rather than reused. Some network paths silently drop an idle connection without closing it; reusing one of those stalls the request until your timeout expires, because the request never reaches the server at all.

# Tune the idle bound, or pass None to reuse connections indefinitely.
coval = CovalClient(api_key, max_idle_seconds=2.0)

If you submit infrequently, connection pooling saves you little — the handshake is amortised over requests you are not making — so a lower bound costs almost nothing.

Diagnosing timeouts

A request that dies in transit leaves no server-side trace, so the client keeps counters describing how the pool has behaved:

coval.connection_stats.as_dict()
# {'opened': 1, 'reused': 12, 'expired': 3}

Each counter records the outcome of one attempt to take a connection from the pool: opened when none was available, reused when a pooled one was still within the idle bound, and expired when one was discarded for being too old. Exactly one is incremented per attempt.

A high expired relative to reused means connections are usually going stale between requests, which is expected if you call the API infrequently.

opened is deliberately not the number of TCP connections established — an expired connection is closed and then transparently reconnects, so it costs a handshake as well:

coval.connection_stats.connections_established  # opened + expired

Include these when reporting intermittent timeouts. For per-connection detail:

import logging
logging.getLogger("coval_sdk.client").setLevel(logging.DEBUG)

Counters are unavailable when max_idle_seconds=None, since the pool is then left entirely to urllib3.

Generated client

All generated API classes, models, ApiClient, Configuration, and typed exceptions remain available for lower-level usage:

from coval_sdk import AgentsApi, ApiClient, Configuration

config = Configuration(host="https://api.coval.dev/v1")
with ApiClient(config) as client:
  client.set_default_header("x-api-key", api_key)
  page = AgentsApi(client).list_agents(page_size=50)

Malformed list resources

List responses validate each resource independently. If one resource does not match the published schema, the SDK omits that item, returns the remaining typed resources, and emits InvalidListItemWarning. The warning identifies the response field and list index but does not include resource contents.

Applications that prefer strict failure can enable it on the client:

from coval_sdk import CovalClient

coval = CovalClient(api_key, strict_response_validation=True)

Single-resource and malformed top-level responses still raise Pydantic validation errors.

What's included

  • 25 typed API classes, including agents, conversations, runs, run templates, metrics, monitors, reports, tags, webhooks, and organization configuration
  • Pydantic v2 request and response models
  • Lowercase API-key authentication and connection pooling
  • Safe retry and token-pagination helpers
  • Warning-backed isolation for malformed resources in list responses

Development

From the repository root:

COVAL_SPECS_DIR=../docs/api-reference/v1 node scripts/bundle-spec.mjs
bash scripts/generate-sdks.sh
python -m pytest python-sdk/tests

License

MIT.

Metadata

Release files for coval-sdk 0.7.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for coval-sdk 0.7.0
File Size Uploaded Provenance
coval_sdk-0.7.0.tar.gz 318.8 kB With provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for coval-sdk 0.7.0
File Interpreter ABI Platform
coval_sdk-0.7.0-py3-none-any.whl Python 3 none any Details

Total release size: 1.3 MB

Release files / coval_sdk-0.7.0.tar.gz

Download URL coval_sdk-0.7.0.tar.gz
Size 318.8 kB
Tags Source
SHA-256 checksum
How to use checksums
582ac2e6e010f48824d67fd6413b20c673c2e1cdfe163c18680405be05e94dd7
BLAKE2b-256 checksum
How to use checksums
ca19b6708c08572708ad603961d08ced6cb0821b029be30ea3b523bb7dfee0b3
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Release files / coval_sdk-0.7.0-py3-none-any.whl

Download URL coval_sdk-0.7.0-py3-none-any.whl
Size 938.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
b58ddfed3085706fc1758df31ddd81b5573b99f3d107c5d25c977df9581bd8db
BLAKE2b-256 checksum
How to use checksums
b82a18c3796641c4668694c79063c6c6a493535975657bf35507ba281982eefb
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

Security for coval-sdk 0.7.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for coval_sdk-0.7.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Aug 31, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page