Developers

API Reference

Complete documentation for the OP Protocol REST API v1. Base URL: https://originalpictures.cc/api/v1

Authentication

All API requests can optionally include an API key via the `X-OP-API-Key` header. Without a key, you get lower rate limits (10/day). With a key, you get 100/day.

curl
curl -H "X-OP-API-Key: op_beta_your_key_here" \
  https://originalpictures.cc/api/v1/health

POST /api/v1/sign

Sign a file with C2PA Content Credentials. Accepts multipart form data with a `file` field. Max file size: 50MB. Returns a signed file download URL (valid for 1 hour) and manifest metadata.

curl
curl -X POST \
  -H "X-OP-API-Key: op_beta_..." \
  -F "file=@photo.jpg" \
  https://originalpictures.cc/api/v1/sign

Response

json
{
  "ok": true,
  "data": {
    "signedFileUrl": "/api/v1/download/tmp_abc123",
    "original": { "size": 245000, "hasC2pa": false, "mimeType": "image/jpeg" },
    "signed": { "size": 289000, "hasC2pa": true, "signer": "OP Beta", "timestamp": "2026-03-24T12:00:00Z" },
    "manifest": { "claimGenerator": "OP/0.1", "actions": ["c2pa.created"] },
    "meta": { "signedAt": "2026-03-24T12:00:00Z", "downloadExpiresAt": "2026-03-24T13:00:00Z", "apiVersion": "v1" }
  }
}

POST /api/v1/verify

Verify a file's C2PA provenance. Returns a trust assessment with tier, confidence, and manifest details. Result is cached for 1 hour, accessible via the returned verifyId.

curl
curl -X POST \
  -H "X-OP-API-Key: op_beta_..." \
  -F "file=@photo.jpg" \
  https://originalpictures.cc/api/v1/verify

Response

json
{
  "ok": true,
  "data": {
    "verifyId": "v_abc123",
    "trust": {
      "tier": "verified",
      "label": "Verified Original",
      "description": "Valid C2PA manifest with trusted signer",
      "confidence": "high",
      "edgeCase": null
    },
    "manifest": { "claimGenerator": "Adobe Photoshop", "signerName": "Adobe Inc.", "timestamp": "2026-03-20T10:00:00Z" },
    "meta": { "verifiedAt": "2026-03-24T12:00:00Z", "expiresAt": "2026-03-24T13:00:00Z", "apiVersion": "v1" }
  }
}

GET /api/v1/trust/:verifyId

Retrieve a cached verification result by its verifyId. Returns a lighter payload without the full manifest. Returns 404 if expired or not found.

curl
curl https://originalpictures.cc/api/v1/trust/v_abc123

Response

json
{
  "ok": true,
  "data": {
    "tier": "verified",
    "label": "Verified Original",
    "confidence": "high"
  }
}

GET /api/v1/badge/:verifyId

Get an embeddable trust badge for a verified file. Supports HTML, SVG, and JSON formats. Cached for 1 hour.

curl
# SVG badge
curl "https://originalpictures.cc/api/v1/badge/v_abc123?format=svg&theme=light&size=md"

# HTML embed
curl "https://originalpictures.cc/api/v1/badge/v_abc123?format=html"

# JSON data
curl "https://originalpictures.cc/api/v1/badge/v_abc123?format=json"

Batch Operations

Process multiple files in a single request. Batch operations are async — you receive a batchId immediately and poll for results. Max: 20 files or 200MB total. Each file counts as one operation against rate limits.

curl
# Start batch verify
curl -X POST \
  -H "X-OP-API-Key: op_beta_..." \
  -F "files=@photo1.jpg" \
  -F "files=@photo2.jpg" \
  https://originalpictures.cc/api/v1/batch/verify

# Poll for status
curl https://originalpictures.cc/api/v1/batch/batch_abc123

Response

json
{
  "ok": true,
  "data": {
    "batchId": "batch_abc123",
    "type": "verify",
    "fileCount": 2,
    "completedCount": 2,
    "status": "completed",
    "results": [...]
  }
}

Webhooks

Register webhook URLs to receive real-time notifications when operations complete. Requires an API key. Events: verify.complete, sign.complete, batch.complete.

curl
# Create webhook
curl -X POST \
  -H "X-OP-API-Key: op_beta_..." \
  -H "Content-Type: application/json" \
  -d '{"url":"https://your-app.com/webhook","events":["verify.complete"]}' \
  https://originalpictures.cc/api/v1/webhooks

# List webhooks
curl -H "X-OP-API-Key: op_beta_..." \
  https://originalpictures.cc/api/v1/webhooks

Response

json
// Webhook payload delivered to your URL
{
  "event": "verify.complete",
  "data": { "verifyId": "v_abc123", "trust": { "tier": "verified" } },
  "timestamp": "2026-03-24T12:00:00Z",
  "webhookId": "wh_abc123"
}

Rate Limits

All responses include rate limit headers. Exceeding the limit returns HTTP 429 with a Retry-After header.

TierSign/dayVerify/dayBurst
No API key (per IP)10105 req/min
Beta API key10010020 req/min

Response Headers

X-RateLimit-Limit — maximum requests allowed

X-RateLimit-Remaining — requests remaining in window

X-RateLimit-Reset — Unix timestamp when the window resets

Error Codes

All errors follow a consistent format.

CodeHTTPDescription
invalid_file400Unsupported file type or corrupted file
file_too_large400File exceeds 50MB limit
unauthorized401Invalid or missing API key (for protected endpoints)
rate_limited429Rate limit exceeded
sign_failed500C2PA signing failed
verify_failed500C2PA verification failed
not_found404Resource not found or expired

Response

json
{
  "ok": false,
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Try again in 60 seconds.",
    "details": { "retryAfter": 60 }
  }
}