Origin verification in your stack.

A REST API for PNG, JPEG and WEBP. Stable decision vocabularies, and Ed25519 response signatures you can check against our public keys whenever the signature headers are present.

See endpoints

API keys are issued with a pilot. No self-serve sign-up yet.

Quick start

Two calls.

API key to register

Registering originals and looking files up in the registry need a key, sent as a Bearer token. Keys are issued per organisation with your pilot.

Response signatures

Decisions are signed with Ed25519 in the Signature and Signature-Input headers. Check them against our public keys — no need to trust us. A response without both headers is unsigned; treat it as such.

Fails closed

An origin stored under a canonicalization profile the verifier does not support is refused, never guessed.

# 1 · register the original once (API key)curl -H "Authorization: Bearer $AIPROOF_KEY" \  -F file=@original.png \  $AIPROOF_API/v1/proof# → { "id": "234fbd75-…", "canon_profile": "IMG-v1", … } # 2 · check any copy against itcurl -i -F file=@copy.webp \  $AIPROOF_API/v1/origins/{id}/verify# → { "origin_id": "234fbd75-…", "decision": "near", … }#   Signature-Input: …;keyid="…"   Signature: …  (Ed25519)

Endpoints

Four endpoints, one version.

Base URL and full reference are shared with your pilot.

MethodPathWhat it doesAccess
POST/v1/proofRegister an originalAccess: API key
POST/v1/origins/{id}/verifyCheck a copy against one origin · Exact, Near or ChangedAccess: Public
POST/v1/verifyLook up a file in the registry · exact_match, near_match or no_matchAccess: API key
GET/.well-known/aiproof-jwks.jsonPublic signing keysAccess: Public

Decision profiles

Read the profile, not the string.

Two questions, two vocabularies — never mix them in your UI.

origin-match

Is this copy related to that known origin?

ExactNearChanged

Show Changed as “doesn’t match closely enough” — never as proof that the copy is fake.

lookup

Does the registry hold an origin for this file?

exact_matchnear_matchno_match

Show no_match as “No registered origin found” — never as proof that no origin exists.