QUICKSTART
Sign and verify your first manifest
End-to-end in under 5 minutes. You will create an account, get an API key, sign a file via POST /v1/sign, then verify the resulting manifest. Both cURL and TypeScript paths are shown side-by-side.
1. Create an account and an API key
Sign up at hashproof.ai/sign-up (Free tier, no card). Then go to Dashboard / API Keys and create a key. The key is shown once at creation; copy it now.
For local experiments, export the key into your shell:
export HASHPROOF_API_KEY="hpsk_live_xxxxxxxxxxxx"2. Sign a file
The signing endpoint takes a multipart file upload and returns a stored manifest with a unique manifestId. The signature uses ES256 plus a post-quantum hybrid (ML-DSA-65) on every tier.
cURL
curl -X POST https://api.hashproof.ai/v1/sign \
-H "x-api-key: $HASHPROOF_API_KEY" \
-F "file=@./photo.jpg" \
-F "title=Field photo, Reykjavik 2026"
# => {
# "manifestId": "ce29...c4f1",
# "manifest": { … },
# "message": "Asset signed and manifest stored successfully"
# }TypeScript
import { Hashproof } from '@hashproof/sdk';
const client = new Hashproof({ apiKey: process.env.HASHPROOF_API_KEY! });
const file = await fetch('./photo.jpg').then((r) => r.blob());
const result = await client.sign(file, {
title: 'Field photo, Reykjavik 2026',
});
console.log(result.manifestId);3. Verify a file
The verify endpoint is public (no API key required) so any consumer of your content can confirm it. Upload the same file (or a copy) and Hashproof checks embedded C2PA, hard binding (SHA-256), then soft binding (perceptual hash) before returning a structured trust result.
cURL
curl -X POST https://api.hashproof.ai/v1/verify \
-F "file=@./photo.jpg"
# => {
# "hasProvenance": true,
# "source": "embedded",
# "manifest": { … },
# "validation": { "status": "valid", "signerTrusted": true, … },
# "trustStatus": "trusted"
# }TypeScript
import { Hashproof } from '@hashproof/sdk';
const client = new Hashproof();
const file = await fetch('./photo.jpg').then((r) => r.blob());
const result = await client.verify(file);
if (result.trustStatus === 'trusted') {
console.log('Provenance valid. Signed by:', result.manifest?.signatureInfo.subject);
} else {
console.warn('Untrusted or no provenance found.');
}4. Resolve when the file has been re-encoded
Real-world distribution strips C2PA metadata. Resolve takes a file (or pre-computed perceptual hash) and finds the original manifest via soft binding. Useful when content has been re-uploaded, cropped, or transcoded.
cURL
curl -X POST https://api.hashproof.ai/v1/resolve \
-H "x-api-key: $HASHPROOF_API_KEY" \
-F "file=@./photo-reencoded.jpg" \
-F "algorithm=phash-dct-64"
# => {
# "matches": [{ "manifestId": "ce29...c4f1", "similarity": 0.97 }],
# "query": { "algorithm": "phash-dct-64" },
# "c2pa": { "version": "2.1", "resolution_results": [...] }
# }TypeScript
const matches = await client.resolve(file, { algorithm: 'phash-dct-64' });
if (matches.matches.length > 0) {
const top = matches.matches[0];
console.log('Soft-bound to', top.manifestId, 'at similarity', top.similarity);
}Next steps
- Read the manifest concept guide to understand what gets stored on your behalf.
- Subscribe to events with webhooks to keep your downstream systems in sync.
- Browse every endpoint in the API reference.