Skip to main content

Verify a file now

Public, no login, no upload. Drop in a file and read its record.

What a receipt is

Every generated asset carries a manifest: a canonical, SHA-256-bound record of how it was made — provider, model, prompt, seed, per-step cost, retries and lineage — embedded directly into the delivered file. The cost on that record is not an estimate. It comes from the same cost model that bills customers, exported from TypeScript into the Python pipeline and drift-guarded in CI, so a manifest line and an invoice line are the same number.

Verifying without uploading

The file never leaves your browser. It is parsed locally, and only the few-kB record is sent for the hash check — so a 4 GB master and a thumbnail cost the same to verify.
The browser reader parses PNG and MP4. The pipeline can also embed into MP3, WAV, AAC, JPEG and WebP; those verify through the service endpoint rather than in-page.
Hash verification is deliberately not reimplemented in TypeScript. Genblaze’s canonical hash is version-aware and canonicalises through Pydantic’s dump semantics, so a second implementation would drift — and would drift by declaring genuine assets tampered. The browser extracts; the reference implementation judges. A tampered record returns 422 with a verdict about the file, not a generic error.

Providers and models

The brief → video pipeline is one Genblaze Pipeline across three modalities. Model ids are checked against each adapter’s live registry — a slug that leaves a vendor’s catalogue fails the build rather than silently routing to something older. Two steps carry a vendor switch rather than a single vendor, because both have failed in production for reasons that were not bugs: narration on an exhausted character quota, video on a credential the service did not hold. videoProvider and narrationProvider pick per request; VC_GENBLAZE_VIDEO and VC_GENBLAZE_TTS set the box default.
Fallbacks are same-vendor by design — one that also changes vendor changes the auth, the parameter shape and the price at the same time, which is a worse thing to discover mid-incident. The two cross-vendor switches above are explicit, quoted and preflighted instead.

Keeping up with the catalogue

Pinned model ids rot, and in generative media a stale pin is not a stale constant — it is a standing decision to ship last season’s output quality. Two things prevent that here:
  • Pattern-keyed registries. The Veo family is matched on ^veo-, so a new generation resolves without a code change and a liveness probe decides whether it is real.
  • A retirement guard in CI. Superseded ids are deleted rather than demoted to fallbacks, and a test fails if one reappears in either the pipeline pins or the price map.

Where the bytes live

Generated media is stored on Backblaze B2 and served through Cloudflare under the Bandwidth Alliance, so delivery costs $0 in egress. Uploads go direct to the bucket: the app server mints a presigned URL and the browser PUTs straight to B2, in 5 parallel parts with per-part retry, so no generated byte transits our compute. Provenance records are written to a separate Object-Locked bucket. Manifests are immutable by construction — the retention mode is GOVERNANCE rather than COMPLIANCE deliberately, so the record is tamper-evident without making a deletion request impossible to honour.