Docs

API Reference

Base URL: https://api.verimago.io

All requests use JSON. All responses return JSON. CORS is enabled for all origins.

Authentication

Most endpoints require a Bearer token. Obtain one by logging in or using a persistent API key.

Authorization: Bearer <token-or-api-key>

Auth

POST /v1/auth/register

Create a new account.

{

"email": "user@example.com",

"password": "min-8-characters",

"name": "Jane Smith"

}

Response 201:
{

"message": "Verification email sent",

"userId": "usr_abc123"

}

POST /v1/auth/verify-email

Verify email address using the code sent during registration.

{

"email": "user@example.com",

"code": "123456"

}

POST /v1/auth/login

{

"email": "user@example.com",

"password": "your-password"

}

Response 200:
{

"token": "eyJhbG...",

"user": {

"email": "user@example.com",

"role": "publisher"

}

}

POST /v1/auth/forgot-password

{ "email": "user@example.com" }

POST /v1/auth/reset-password

{

"email": "user@example.com",

"code": "123456",

"newPassword": "new-password"

}


Sign (Server-Side)

POST /v1/sign

Auth: Bearer token required

Sign a content hash using the Verimago CA. The video/photo file is never uploaded — only the SHA-256 hash.

Request:
{

"contentHash": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",

"headline": "Breaking: City council vote",

"journalist": "Jane Smith",

"location": "Portland, OR",

"recordedAt": "2026-03-28T14:30:00Z",

"contentType": "AUTHENTIC",

"captureMode": "VIDEO",

"tags": ["politics", "local"]

}

FieldRequiredValues
contentHashYessha256: followed by hex-encoded SHA-256
headlineYesDescription of the content
journalistNoName of the person who captured/created the content
locationNoWhere the content was captured
recordedAtNoISO 8601 timestamp of capture
contentTypeNoAUTHENTIC (default), AI_ENHANCED, AI_GENERATED
captureModeNoVIDEO (default), PHOTO
tagsNoArray of string tags
Response 201:
{

"contentHash": "sha256:e3b0c44...",

"signature": "MEUCIQ...",

"shieldState": "GREEN",

"signedAt": "2026-03-28T15:00:00Z",

"verifyUrl": "https://verify.verimago.io/sha256:e3b0c44..."

}

Shield state mapping:
contentTypeshieldState
AUTHENTICGREEN
AI_ENHANCEDBLUE
AI_GENERATEDAMBER

Verify (Public)

GET /v1/verify/{hash}

Auth: None required

Look up a certificate by content hash.

GET /v1/verify/sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855
Response 200 (found):
{

"verified": true,

"shieldState": "GREEN",

"publisher": "Reuters",

"journalist": "Jane Smith",

"headline": "Breaking: City council vote",

"location": "Portland, OR",

"signedAt": "2026-03-28T15:00:00Z",

"recordedAt": "2026-03-28T14:30:00Z",

"contentType": "AUTHENTIC",

"certStatus": "ACTIVE"

}

Response 404 (not found):
{

"verified": false,

"shieldState": "GREY"

}

POST /v1/verify/url

Auth: None required

Verify content by URL. The server fetches the file, computes the hash, and looks it up.

{

"url": "https://example.com/video.mp4"

}

Rate limited to 10 requests per IP per minute. Maximum file size: 500 MB. Timeout: 25 seconds.


API Keys

GET /v1/keys

Auth: Bearer token

List all active API keys for your account.

Response 200:
{

"items": [

{

"id": "key_abc123",

"name": "CMS Production",

"keyPrefix": "veri_live_abc",

"createdAt": "2026-03-28T12:00:00Z",

"lastUsedAt": "2026-03-28T15:00:00Z"

}

],

"total": 1

}

POST /v1/keys

Auth: Bearer token

Generate a new API key. The full key is returned only once.

{ "name": "CMS Production" }
Response 201:
{

"id": "key_abc123",

"name": "CMS Production",

"apiKey": "veri_live_abc123def456ghi789...",

"keyPrefix": "veri_live_abc"

}

POST /v1/keys/{id}/revoke

Auth: Bearer token

Revoke an API key. Immediate effect — all requests using this key will fail.


Certificates

GET /v1/certs

Auth: Bearer token

List certificates associated with your account.

GET /v1/certs/{id}

Auth: Bearer token

Get certificate details including status, expiry, and public key.

PATCH /v1/certs/{id}/activate

Auth: Bearer token

Activate a pending certificate.

PATCH /v1/certs/{id}/revoke

Auth: Bearer token

Revoke a certificate. All manifests signed with this certificate will show the certificate as revoked during verification, though the signature remains valid.


Applications

POST /v1/apply

Auth: None required

Submit a publisher or creator application.

{

"organizationName": "Portland Herald",

"contactEmail": "editor@portlandherald.com",

"contactName": "Jane Smith",

"domain": "portlandherald.com",

"jurisdiction": "US-OR",

"description": "Daily newspaper covering Portland metro area, 50,000 daily readers"

}

For creator applications, omit domain and organizationName.

Response 201:
{

"id": "app_abc123",

"status": "PENDING",

"message": "Application received. You will be contacted within 48 hours."

}

GET /v1/apply/{id}

Auth: None required

Check application status.


Watermark

POST /v1/watermark/upload-url

Auth: Bearer token

Get a presigned S3 URL to upload a video for watermarking.

{

"filename": "my-video.mp4",

"contentType": "video/mp4"

}

Response 200:
{

"jobId": "wm_abc123",

"uploadUrl": "https://s3.amazonaws.com/...",

"expiresIn": 3600

}

POST /v1/watermark/process

Auth: Bearer token

Start watermark processing for an uploaded video.

{ "jobId": "wm_abc123" }

GET /v1/watermark/status/{jobId}

Auth: None

Check watermark processing status and get download URL when complete.


OCSP

GET /v1/ocsp/status

Health check for the OCSP responder.

GET /v1/ocsp/{certId}

Check certificate revocation status (OCSP protocol).


TSA (Timestamp Authority)

GET /v1/tsa/status

Health check for the TSA proxy.

POST /v1/tsa

Timestamp authority proxy used by the camera apps during capture. Returns an RFC 3161 timestamp token.


Errors

All errors follow this format:

{

"error": "Human-readable error message"

}

StatusMeaning
400Bad request — check your input
401Unauthorized — missing or invalid token
404Not found
429Rate limited
500Server error — contact support

Rate limits

EndpointLimit
POST /v1/verify/url10 req/IP/min
POST /v1/sign100 req/key/min
GET /v1/verify/{hash}1000 req/IP/min
All other endpoints60 req/key/min