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 requiredSign 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"]
}
| Field | Required | Values |
|---|---|---|
contentHash | Yes | sha256: followed by hex-encoded SHA-256 |
headline | Yes | Description of the content |
journalist | No | Name of the person who captured/created the content |
location | No | Where the content was captured |
recordedAt | No | ISO 8601 timestamp of capture |
contentType | No | AUTHENTIC (default), AI_ENHANCED, AI_GENERATED |
captureMode | No | VIDEO (default), PHOTO |
tags | No | Array of string tags |
201:
{
"contentHash": "sha256:e3b0c44...",
"signature": "MEUCIQ...",
"shieldState": "GREEN",
"signedAt": "2026-03-28T15:00:00Z",
"verifyUrl": "https://verify.verimago.io/sha256:e3b0c44..."
}
Shield state mapping:
| contentType | shieldState |
|---|---|
| AUTHENTIC | GREEN |
| AI_ENHANCED | BLUE |
| AI_GENERATED | AMBER |
Verify (Public)
GET /v1/verify/{hash}
Auth: None requiredLook 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 requiredVerify 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 tokenList all active API keys for your account.
Response200:
{
"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 tokenGenerate 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 tokenRevoke an API key. Immediate effect — all requests using this key will fail.
Certificates
GET /v1/certs
Auth: Bearer tokenList certificates associated with your account.
GET /v1/certs/{id}
Auth: Bearer tokenGet certificate details including status, expiry, and public key.
PATCH /v1/certs/{id}/activate
Auth: Bearer tokenActivate a pending certificate.
PATCH /v1/certs/{id}/revoke
Auth: Bearer tokenRevoke 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 requiredSubmit 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.
201:
{
"id": "app_abc123",
"status": "PENDING",
"message": "Application received. You will be contacted within 48 hours."
}
GET /v1/apply/{id}
Auth: None requiredCheck application status.
Watermark
POST /v1/watermark/upload-url
Auth: Bearer tokenGet 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 tokenStart watermark processing for an uploaded video.
{ "jobId": "wm_abc123" }
GET /v1/watermark/status/{jobId}
Auth: NoneCheck 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"
}
| Status | Meaning |
|---|---|
| 400 | Bad request — check your input |
| 401 | Unauthorized — missing or invalid token |
| 404 | Not found |
| 429 | Rate limited |
| 500 | Server error — contact support |
Rate limits
| Endpoint | Limit |
|---|---|
| POST /v1/verify/url | 10 req/IP/min |
| POST /v1/sign | 100 req/key/min |
| GET /v1/verify/{hash} | 1000 req/IP/min |
| All other endpoints | 60 req/key/min |