Skip to content

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

Terminal window
npm install @verbitas/sdk
# or
pnpm add @verbitas/sdk
# or
yarn add @verbitas/sdk

Configuration

import { VerbitasClient } from "@verbitas/sdk";
// From environment variable (recommended)
const client = new VerbitasClient(); // reads VERBITAS_API_KEY
// Explicit key
const client = new VerbitasClient({ apiKey: "vb_live_01j..." });
// Custom base URL
const client = new VerbitasClient({ baseUrl: "https://api.verbitas.io" });

Set VERBITAS_API_KEY in your environment:

Terminal window
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 Buffer
const buffer = fs.readFileSync("output.png");
const result = await client.sign(buffer, {
recipe: "image-genai-v1",
filename: "output.png",
});
// From ReadableStream
const 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 path
const result = await client.verify("received_image.jpg");
// By asset ID
const result = await client.verify({ assetId: "a_01j..." });
// By manifest URI
const 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.97
console.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

// List
const { recipes } = await client.recipes.list();
// Get
const 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

VariableDescription
VERBITAS_API_KEYAPI key
VERBITAS_BASE_URLOverride base URL (default: https://api.verbitas.io)
VERBITAS_TIMEOUT_MSHTTP timeout in milliseconds (default: 60000)
VERBITAS_MAX_RETRIESMax retry attempts (default: 3)