TypeScript SDK
TypeScript SDK
The @verbitas/sdk package is the official TypeScript client for the Verbitas API.
- npm:
@verbitas/sdk - Node: 18+
- Formats: ESM and CJS
- License: MIT
Installation
npm install @verbitas/sdk# orpnpm add @verbitas/sdk# oryarn add @verbitas/sdkConfiguration
import { VerbitasClient } from "@verbitas/sdk";
// From environment variable (recommended)const client = new VerbitasClient(); // reads VERBITAS_API_KEY
// Explicit keyconst client = new VerbitasClient({ apiKey: "vb_live_01j..." });
// Custom base URLconst client = new VerbitasClient({ baseUrl: "https://api.verbitas.io" });Set VERBITAS_API_KEY in your environment:
export VERBITAS_API_KEY=vb_live_01j...TypeScript types
The SDK is written in TypeScript and exports all request/response types:
import type { SignResult, VerificationResult, LookupResult, Recipe, AuditEntry, VerificationStatus, // the 16-code closed enum} from "@verbitas/sdk";Signing
import { VerbitasClient } from "@verbitas/sdk";
const client = new VerbitasClient();
const result = await client.sign("output.png", { recipe: "image-genai-v1", metadata: { generator: "stable-diffusion-xl", model: "sdxl-1.0", },});
console.log(result.assetId); // "a_01j..."console.log(result.verifierUrl); // "https://v.verbitas.io/v/a_01j..."console.log(result.manifestUri); // "https://m.verbitas.io/manifests/..."Sign from Buffer or ReadableStream
import fs from "fs";
// From Bufferconst buffer = fs.readFileSync("output.png");const result = await client.sign(buffer, { recipe: "image-genai-v1", filename: "output.png",});
// From ReadableStreamconst stream = fs.createReadStream("large_video.mp4");const result = await client.sign(stream, { recipe: "video-genai-v1", filename: "large_video.mp4",});Large files (async)
Files > ~5 MB return a job. The SDK handles polling automatically:
const result = await client.sign("large_video.mp4", { recipe: "video-genai-v1", // SDK polls until done; default timeout: 300s timeout: 600,});Verifying
// By file pathconst result = await client.verify("received_image.jpg");
// By asset IDconst result = await client.verify({ assetId: "a_01j..." });
// By manifest URIconst result = await client.verify({ manifestUri: "https://m.verbitas.io/manifests/a_01j.../manifest.c2pa",});
console.log(result.status); // "verified_manifest_and_watermark_match"console.log(result.confidence); // 0.97console.log(result.proves); // string[]console.log(result.doesNotProve); // string[]Type-safe status checks
import type { VerificationStatus } from "@verbitas/sdk";
const result = await client.verify({ assetId: "a_01j..." });
switch (result.status as VerificationStatus) { case "verified_manifest_and_watermark_match": case "verified_manifest_intact": // proceed break; case "manifest_tampered": throw new Error(`Tampered: ${result.developerExplanation}`); case "no_provenance": // no record found; handle per policy break; default: console.warn("Unhandled state:", result.status);}Lookup
const result = await client.lookup("cropped_image.jpg");
for (const match of result.matches) { console.log(match.assetId, match.matchType, match.confidence);}Recipes
// Listconst { recipes } = await client.recipes.list();
// Getconst recipe = await client.recipes.get("image-genai-v1");
// Create (requires admin key)const created = await client.recipes.create(yamlString);Webhooks
import express from "express";
const app = express();app.use("/webhook", express.raw({ type: "application/json" }));
app.post("/webhook", (req, res) => { const signature = req.headers["verbitas-signature"] as string;
const event = client.webhooks.constructEvent( req.body, signature, process.env.VERBITAS_WEBHOOK_SECRET! );
if (event.type === "job.completed") { const assetId = event.data.assetId; // update your records }
res.sendStatus(200);});Error handling
import { VerbitasAPIError, AuthError, QuotaExceededError, RateLimitError, SignerUnavailableError,} from "@verbitas/sdk";
try { const result = await client.sign("image.png", { recipe: "image-genai-v1" });} catch (e) { if (e instanceof AuthError) { console.error("Invalid or revoked key"); } else if (e instanceof QuotaExceededError) { console.error("Monthly quota exceeded"); } else if (e instanceof RateLimitError) { console.error(`Rate limited; retry after ${e.retryAfter}s`); } else if (e instanceof SignerUnavailableError) { console.error("Signer unavailable after retries"); } else if (e instanceof VerbitasAPIError) { console.error(`${e.code}: ${e.detail} (requestId=${e.requestId})`); } else { throw e; }}ESM and CJS
The package ships both ESM and CJS builds. With bundlers (Vite, webpack, esbuild) and Node.js with "type": "module", ESM is used automatically.
For CommonJS:
const { VerbitasClient } = require("@verbitas/sdk");Environment variables
| Variable | Description |
|---|---|
VERBITAS_API_KEY | API key |
VERBITAS_BASE_URL | Override base URL (default: https://api.verbitas.io) |
VERBITAS_TIMEOUT_MS | HTTP timeout in milliseconds (default: 60000) |
VERBITAS_MAX_RETRIES | Max retry attempts (default: 3) |