PHP SDK
The certivu/sdk package is a synchronous, thin REST client for signing and verifying AI-generated content from PHP. It targets web apps, CMS plugins, and content pipelines wiring POST /v1/verify into upload and moderation flows — plus generator-side backends.
Like every Certivu SDK, it does no client-side cryptography. Signing happens server-side (org private keys and signing quota live behind the API) and verification goes through the API. The SDK never bundles ML-DSA.
Install
Section titled “Install”The SDK ships from cdn.certivu.ai as a static Composer repository — not from Packagist or a public GitHub repo (the monorepo is private). A static Composer repo is just files over HTTPS, so the CDN serves the whole thing.
Add the repository and requirement to your composer.json:
{ "repositories": [ { "type": "composer", "url": "https://cdn.certivu.ai/sdk/php" } ], "require": { "certivu/sdk": "^1.0" }}Then composer update certivu/sdk.
Requires PHP 8.1+ with the curl and json extensions (both standard). The SDK has zero Composer dependencies. It versions on its own line (starting 1.0.0), independent of the platform version.
Initialize
Section titled “Initialize”$client = new Certivu\Client( 'ctv_key_abc123', // pass '' for verify-only generatorId: 'your-generator-uuid', // required for signing);Constructor signature: new Certivu\Client($apiKey, $baseUrl, $generatorId, $timeout). Use named arguments to skip $baseUrl — point it at the sandbox when needed. $timeout defaults to 60s. sign() and verify() return typed objects; every read endpoint returns a decoded associative array.
Sign content
Section titled “Sign content”$img = file_get_contents('output.png'); // or .mp3, .mp4, .pdf, etc.
$res = $client->sign($img, 'stable-diffusion-xl');
echo $res->token . "\n"; // ctv_7f3kx9mq2...echo $res->recordId . "\n"; // rec-uuidfile_put_contents('output.signed.png', $res->signedContent); // store THIS$res->signedContent is the signed content with the ctv_ token injected into a format-native container (XMP, ID3v2, HTML meta, cerv atom, …) and the watermark embedded — deliver it instead of the original. Pass a fourth argument to override the format: $client->sign($img, 'sdxl', generatorId: null, format: 'image').
When the API recognises identical input bytes it re-uses the existing record without charging a new signature; $res->deduplicated is then true.
$results = $client->signBatch([ ['content' => $a, 'model' => 'sdxl'], ['content' => $b, 'model' => 'sdxl', 'format' => 'image'],]);foreach ($results as $r) { if (isset($r['result'])) { echo $r['result']->token . "\n"; } else { fwrite(STDERR, "item failed: " . $r['error']->getMessage() . "\n"); }}Verify content
Section titled “Verify content”Verification is free, unlimited, and needs no API key — construct a verify-only client with an empty key:
$client = new Certivu\Client('');
$res = $client->verify($contentBytes);echo ($res->authentic ? 'true' : 'false') . " {$res->confidence}\n"; // e.g. true highif ($res->provenance !== null) { echo "signed by {$res->provenance['org']} using {$res->provenance['model']}\n";}Pass a token as the second argument — $client->verify($content, 'ctv_...') — to take the fast path when you already hold it. Verification works on transformed copies (resized, recompressed, reposted) via watermark, pHash, and fingerprint recovery.
Token status (no upload)
Section titled “Token status (no upload)”$status = $client->tokenStatus('ctv_...'); // associative arrayecho "{$status['model']} {$status['generator_status']} {$status['org_name']}\n";This CDN-cacheable lookup powers badges and certificate pages without re-hashing content.
Error handling
Section titled “Error handling”Any non-2xx response throws Certivu\ApiException (a subclass of Certivu\CertivuException). Branch with the predicate helpers:
use Certivu\ApiException;
try { $client->sign($img, 'sdxl');} catch (ApiException $e) { if ($e->isQuota()) { // 402 — free-tier signing limit echo "upgrade at {$e->upgradeUrl()}\n"; } elseif ($e->isAuth()) { // 401 — bad / missing key echo "invalid API key\n"; } elseif ($e->isValidation()) { // 400 echo $e->getMessage() . "\n"; } else { echo "certivu error {$e->status()}: {$e->getMessage()}\n"; }}Analytics, audit, webhooks
Section titled “Analytics, audit, webhooks”Read endpoints return decoded associative arrays:
$overview = $client->analyticsOverview(30); // lookback days (null = default)$page = $client->auditLog(1, 20); // page, limit$rec = $client->recordAnalytics('rec-uuid'); // Growth+
$wh = $client->createWebhook('https://hooks.example/certivu', ['tamper.detected']);echo $wh['secret'] . "\n"; // shown ONCE — store it to verify delivery signaturesEnterprise plans can pull an EU AI Act compliance attestation:
$att = $client->attestation(); // default last-90-days window$html = $client->exportAttestation('html'); // rendered document string- No client crypto. Signing and verification are both API calls; offline verification is not supported.
- Zero Composer dependencies. PHP 8.1+ with
ext-curlandext-json. - Default timeout is 60s (server-side watermarking takes a moment). Override via the
timeout:constructor argument. - Distributed as a static Composer repository at
https://cdn.certivu.ai/sdk/php(no Packagist, no GitHub).