@hashproof/sdk
v0.2.0
Published
Official JavaScript/TypeScript SDK for the Hashproof Content Provenance API
Maintainers
Readme
@hashproof/sdk
Published as
@hashproof/sdkon npm. The source directory ispackages/sdk-js(legacy name).
Official JavaScript/TypeScript SDK for the Hashproof Content Provenance API.
Hashproof provides content provenance infrastructure built on the C2PA standard. This SDK wraps the REST API with a type-safe client for storing, resolving, verifying, and signing digital assets.
Installation
npm install @hashproof/sdk
# or
pnpm add @hashproof/sdk
# or
yarn add @hashproof/sdkQuick Start
import { HashproofClient } from '@hashproof/sdk';
import { readFileSync } from 'node:fs';
const client = new HashproofClient({ apiKey: 'hpsk_...' });
// Verify a file's provenance
const file = readFileSync('photo.jpg');
const result = await client.verify(file);
if (result.hasProvenance) {
console.log(`Provenance found via: ${result.source}`);
console.log(`Trust status: ${result.trustStatus}`);
console.log(`Signer: ${result.manifest?.signatureInfo.subject}`);
} else {
console.log('No provenance found for this file.');
}Configuration
const client = new HashproofClient({
apiKey: 'hpsk_...', // Required. Your Hashproof API key.
baseUrl: 'https://api.hashproof.ai', // Optional. Defaults to production.
timeout: 30000, // Optional. Request timeout in ms.
});API Reference
store(file, options?)
Upload a digital asset and extract/store its C2PA manifest. Perceptual fingerprints are computed automatically.
const result = await client.store(fileBuffer, { title: 'Press Photo' });
console.log(result.manifestId);
console.log(result.softBindings); // computed perceptual hashesParameters:
| Name | Type | Description |
|------|------|-------------|
| file | Buffer \| Blob | The digital asset to store |
| options.title | string | Optional human-readable title |
Returns: Promise<StoreResult>
resolve(file) / resolve(fingerprint, algorithm?)
Resolve provenance for a file or pre-computed fingerprint. Finds matching manifests via perceptual hashing (soft binding).
// By file upload
const result = await client.resolve(imageBuffer);
// By pre-computed fingerprint (no upload needed)
const result = await client.resolve('a1b2c3d4...', 'phash-dct-64');
for (const match of result.matches) {
console.log(`${match.similarity * 100}% similar — ${match.manifest.title}`);
}Parameters (file overload):
| Name | Type | Description |
|------|------|-------------|
| file | Buffer \| Blob | The file to resolve |
Parameters (fingerprint overload):
| Name | Type | Description |
|------|------|-------------|
| fingerprint | string | Hex-encoded perceptual hash |
| algorithm | string | Algorithm name (default: phash-dct-64) |
Returns: Promise<ResolveResult>
verify(file)
One-call provenance verification. Checks embedded C2PA manifests, hard binding (hash match), and soft binding (perceptual hash resolution).
const result = await client.verify(imageBuffer);
console.log(result.hasProvenance); // boolean
console.log(result.source); // 'embedded' | 'resolved' | 'none'
console.log(result.trustStatus); // 'trusted' | 'untrusted' | 'unknown'Parameters:
| Name | Type | Description |
|------|------|-------------|
| file | Buffer \| Blob | The file to verify |
Returns: Promise<VerifyResult>
getManifest(id)
Retrieve a manifest by its UUID.
const manifest = await client.getManifest('550e8400-...');Returns: Promise<ManifestData>
getManifestByHash(hash)
Retrieve a manifest by its hard binding hash (SHA-256 of the original asset).
const manifest = await client.getManifestByHash('e3b0c44298fc...');Returns: Promise<ManifestData>
listManifests(options?)
List manifests with pagination and search.
const page = await client.listManifests({ page: 1, perPage: 50, search: 'photo' });
console.log(`${page.total} total manifests`);Parameters:
| Name | Type | Description |
|------|------|-------------|
| options.page | number | Page number (default: 1) |
| options.perPage | number | Results per page (default: 20) |
| options.search | string | Filter by title |
Returns: Promise<PaginatedResponse<ManifestData>>
sign(file, options?)
Sign a digital asset with a C2PA manifest using Hashproof managed signing. Requires the sign scope on your API key.
const result = await client.sign(imageBuffer, { title: 'Press Photo' });
console.log(result.manifestId);Parameters:
| Name | Type | Description |
|------|------|-------------|
| file | Buffer \| Blob | The file to sign |
| options.title | string | Optional title |
Returns: Promise<SignResult>
computeFingerprint(file, algorithm?)
Compute a perceptual fingerprint without resolving. Useful for offline computation followed by later resolution.
const fp = await client.computeFingerprint(imageBuffer);
console.log(fp.fingerprint); // hex string
console.log(fp.algorithm); // 'phash-dct-64'
// Later, resolve without re-uploading:
const matches = await client.resolve(fp.fingerprint, fp.algorithm);Parameters:
| Name | Type | Description |
|------|------|-------------|
| file | Buffer \| Blob | The file to fingerprint |
| algorithm | string | Algorithm (default: phash-dct-64) |
Returns: Promise<FingerprintResult>
Error Handling
All API errors are thrown as HashproofApiError instances:
import { HashproofClient, HashproofApiError } from '@hashproof/sdk';
try {
await client.getManifest('nonexistent');
} catch (err) {
if (err instanceof HashproofApiError) {
console.error(err.message); // "Manifest not found"
console.error(err.statusCode); // 404
console.error(err.code); // "NOT_FOUND"
}
}TypeScript
All types are exported from the package for full type safety:
import type {
ManifestData,
VerifyResult,
ResolveResult,
ValidationStatus,
PaginatedResponse,
} from '@hashproof/sdk';Supported Runtimes
- Node.js 18+ (uses native
fetch) - Deno
- Bun
- Modern browsers (via bundler)
License
MIT
