SDKs¶
Venturi maintains first-party, fully typed SDKs for TypeScript and
Python. Both are generated from the same OpenAPI 3.1 document that defines
the REST API, so the client surface always matches the contract. Each
SDK builds in the platform conventions you would otherwise implement by hand:
token refresh, cursor-pagination iterators, idempotency-key generation,
Retry-After-aware backoff, and typed problem+json errors.
Package availability
The SDKs are distributed to every onboarded customer in the onboarding
artifact bundle, which you download from the authenticated onboarding
channel in the product, and through your private package channel. The
TypeScript package is @venturi/sdk; the Python distribution is the
venturi_sdk wheel, which installs the importable venturi package.
Neither is published to a public registry: @venturi/sdk is not on the
public npm registry, and the public PyPI project named venturi is
unrelated, so do not install either from a public registry. That public
venturi project also installs a top-level venturi module, so it cannot
share an environment with the SDK: if pip show venturi finds it, run
pip uninstall venturi before you install the venturi_sdk wheel, or
install the SDK into a separate virtual environment. Your bundle manifest
pins each package filename, version, SHA-256 digest, and matching OpenAPI
version.
Generated, never hand-written
The SDKs are regenerated from each released OpenAPI version and pinned for reproducible builds. The generated client cannot drift from the published contract (a mismatch fails CI), so the methods, models, and error types you use are exactly the API’s.
Install¶
Run these commands from the directory that holds the files from your onboarding
bundle. Set VERSION to the version in the bundle manifest first.
Configure the client¶
Set the base URL by the base-URL rule:
https:// on the SaaS tier, or your own instance host when
self-hosted. Supply OAuth client credentials (or an API key) and the client
manages token refresh.
Reading attribution¶
Every record carries the interpretation evidence card (stage_origin,
confidence, confidence_band, evidence_basis, model_version,
degradation_state, freshness, and export_eligibility), fully typed.
Pagination with transparent iterators¶
Paginated resources expose an async iterator that follows cursors for you. You
never construct, sign, or carry a cursor by hand. Filter and sort keys use the
REST field names in both SDKs (cost_usd); the TypeScript SDK exposes response
fields in camelCase (costUsd), and the Python SDK keeps them in snake_case.
The iterator walks next_cursor to exhaustion, returning each record exactly
once. See pagination for the underlying contract.
Ingestion coverage¶
Both SDKs include typed clients for the InvocationEvent and generic
observability ingestion routes (POST /api/v1/invocations and
POST /api/v1/events), including caller-supplied idempotency keys. The REST wire
format on the Ingestion API page remains authoritative.
Automatic idempotency¶
The SDK attaches a fresh Idempotency-Key to every mutating call by default, so
a transient network retry never creates a duplicate. To make a specific
operation safe to retry across process restarts, pass your own key. It must be a
UUID or ULID, like every Idempotency-Key: generate one for the logical
operation, store it with that operation, and reuse it on every retry.
Automatic rate-limit backoff¶
On a 429, the SDK honors Retry-After and retries with jittered backoff. After
exhausting retries it raises a typed RateLimitError rather than a bare HTTP
error, so you can branch deliberately.
Typed errors¶
Errors are deserialized into a typed union derived from the published
error catalog. Branch on the error_code, not on prose.
import { VenturiError } from "@venturi/sdk";
const exportRequest = {
format: "focus",
period: { from: "2026-05-01", to: "2026-05-31" },
};
try {
await venturi.exports.create(exportRequest);
} catch (err) {
if (err instanceof VenturiError && err.errorCode === "INSUFFICIENT_SCOPE") {
// this credential cannot create exports
}
}
Verifying webhooks¶
Each SDK ships a signature-verification helper so you do not reimplement the HMAC
check. The helper throws on a bad signature or timestamp skew, so each example
catches that error and rejects the delivery with 400. Each one also answers the
webhook. challenge, because a new endpoint receives no production
events until it passes ownership verification.
See webhooks.
import express from "express";
import { verifyWebhook } from "@venturi/sdk";
const app = express();
const secret = process.env.VENTURI_WEBHOOK_SECRET ?? "";
// express.raw keeps the exact bytes Venturi signed.
app.post("/venturi", express.raw({ type: "application/json" }), (req, res) => {
let event;
try {
// throws on a bad signature or timestamp skew
event = verifyWebhook(req.body, req.get("Venturi-Signature") ?? "", secret);
} catch {
res.sendStatus(400);
return;
}
if (event.type === "webhook.verification") {
res.json({ challenge: event.data.challenge });
return;
}
handleEvent(event); // your processing
res.sendStatus(200);
});
import os
from flask import Flask, request
from venturi.webhooks import verify_webhook
app = Flask(__name__)
secret = os.environ["VENTURI_WEBHOOK_SECRET"]
@app.post("/venturi")
def handle():
try:
# get_data() returns the exact bytes Venturi signed.
# raises on a bad signature or timestamp skew
event = verify_webhook(request.get_data(), request.headers.get("Venturi-Signature", ""), secret)
except Exception:
return "", 400
if event["type"] == "webhook.verification":
return {"challenge": event["data"]["challenge"]}
process(event) # your processing
return "", 200
Sample apps¶
Each SDK bundle includes runnable reference apps you can point at the sandbox:
- Chargeback exporter: generates a FOCUS export and downloads the result.
- Webhook receiver: verifies signatures and processes events.
- Anomaly-alert forwarder: relays
anomaly.detectedevents to your channel.
Versioning¶
SDK major versions track API major versions. A breaking API change ships alongside a coordinated new SDK major version, and the changelog records the mapping. Within a major version, upgrades are additive and safe. See versioning and rate limits.
Sign in to send feedback. Opens in a new tab.
Copy page details
Docs feedback: SDKs
Page: https://docs.venturi.systems/developers/sdks/