Skip to content

Python SDK

Python SDK

The verbitas package is the official Python client for the Verbitas API.

  • PyPI: verbitas
  • Python: 3.10+
  • License: MIT

Installation

Terminal window
pip install verbitas

Or with uv:

Terminal window
uv add verbitas

Configuration

import verbitas
# From environment variable (recommended)
client = verbitas.Client() # reads VERBITAS_API_KEY
# Explicit key
client = verbitas.Client(api_key="vb_live_01j...")
# Custom base URL (e.g. for a self-hosted instance or sandbox)
client = verbitas.Client(base_url="https://api.verbitas.io")

Set VERBITAS_API_KEY in your environment:

Terminal window
export VERBITAS_API_KEY=vb_live_01j...

Signing

Synchronous (small files)

result = client.sign(
"output.png",
recipe="image-genai-v1",
metadata={
"generator": "stable-diffusion-xl",
"model": "sdxl-1.0",
}
)
print(result.asset_id) # "a_01j..."
print(result.verifier_url) # "https://v.verbitas.io/v/a_01j..."
print(result.manifest_uri) # "https://m.verbitas.io/manifests/..."

Asynchronous (large files, > ~5 MB)

For large files, client.sign() returns a Job object. Call .wait() to block until complete:

result = client.sign("large_video.mp4", recipe="video-genai-v1")
if result.is_async:
result = result.wait(timeout=300) # seconds; raises TimeoutError if exceeded
print(result.asset_id)

Sign from bytes or file-like object

import io
with open("output.png", "rb") as f:
result = client.sign(f, recipe="image-genai-v1", filename="output.png")
image_bytes = generate_image(prompt) # your generation function
result = client.sign(
io.BytesIO(image_bytes),
recipe="image-genai-v1",
filename="generated.png",
metadata={"generator": "my-diffusion-model"}
)

Idempotency key

The SDK generates a UUIDv7 idempotency key automatically for each sign call. To provide your own (for deterministic deduplication):

result = client.sign(
"output.png",
recipe="image-genai-v1",
idempotency_key="01926e7a-f2b3-7abc-8def-0123456789ab"
)

Verifying

# By file
result = client.verify("received_image.jpg")
# By asset_id
result = client.verify(asset_id="a_01j...")
# By manifest URI
result = client.verify(manifest_uri="https://m.verbitas.io/manifests/a_01j.../manifest.c2pa")
print(result.status) # "verified_manifest_and_watermark_match"
print(result.confidence) # 0.97
print(result.developer_explanation)
print(result.proves) # list of strings
print(result.does_not_prove) # list of strings

Lookup

result = client.lookup("cropped_image.jpg")
for match in result.matches:
print(match.asset_id, match.match_type, match.confidence)
# a_01j... perceptual_hash 0.81

Recipes

# List
recipes = client.recipes.list()
# Get by ID
recipe = client.recipes.get("image-genai-v1")
print(recipe.recipe_yaml)
# Create custom recipe (requires admin key)
with open("my-recipe-v1.yaml") as f:
result = client.recipes.create(f.read())
print(result.recipe_id)

Audit log

from datetime import datetime, timezone
entries = client.audit.list(
from_dt=datetime(2026, 5, 1, tzinfo=timezone.utc),
to_dt=datetime(2026, 5, 9, tzinfo=timezone.utc),
event_type="asset.signed",
)
for entry in entries:
print(entry.timestamp, entry.event_type, entry.data)

Webhook event construction

from fastapi import Request
async def webhook_handler(request: Request):
payload = await request.body()
signature = request.headers.get("Verbitas-Signature")
event = client.webhooks.construct_event(
payload=payload,
signature=signature,
secret="whsec_..."
)
if event.type == "job.completed":
asset_id = event.data["asset_id"]
# update your records

Async support

The SDK includes a native async client:

import verbitas.aio
async def sign_image():
async with verbitas.aio.Client() as client:
result = await client.sign("output.png", recipe="image-genai-v1")
return result.asset_id

Error handling

from verbitas.exceptions import (
AuthError,
QuotaExceededError,
RateLimitError,
SignerUnavailableError,
VerbtiasAPIError,
)
try:
result = client.sign("image.png", recipe="image-genai-v1")
except AuthError as e:
print(f"Invalid key: {e.message}")
except QuotaExceededError:
print("Monthly quota exceeded; upgrade plan")
except RateLimitError as e:
print(f"Rate limited; retry after {e.retry_after}s")
except SignerUnavailableError:
# SDK retries automatically (3 attempts); this is raised after all retries fail
print("Signer unavailable after retries")
except VerbtiasAPIError as e:
print(f"API error {e.code}: {e.detail}")
print(f"Request ID for support: {e.request_id}")

Environment variables

VariableDescription
VERBITAS_API_KEYAPI key (required unless passed to Client())
VERBITAS_BASE_URLOverride base URL (default: https://api.verbitas.io)
VERBITAS_TIMEOUTHTTP timeout in seconds (default: 60)
VERBITAS_MAX_RETRIESMax retry attempts for 429 and 5xx (default: 3)