Skip to content

API Reference

Complete REST API documentation for Certana Backend.

Base URL

http://localhost:8000/v1

All endpoints are versioned with /v1 prefix.

Authentication

Bearer Token

Authorization: Bearer <jwt_token>

API Key

X-API-Key: <api_key>

OAuth2

Authorization: Bearer <oauth_token>

Response Format

All responses are JSON:

{
  "data": {},
  "message": "Success message",
  "timestamp": "2024-01-15T10:30:00Z",
  "request_id": "req_xxx"
}

Errors:

{
  "detail": "Error message",
  "error_code": "ERROR_CODE",
  "timestamp": "2024-01-15T10:30:00Z"
}

Authentication Endpoints

Register User

POST /auth/register
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!",
  "full_name": "John Doe"
}

Response (201 Created):

{
  "id": "uuid",
  "email": "user@example.com",
  "full_name": "John Doe",
  "tier": "free",
  "created_at": "2024-01-15T10:30:00Z"
}

Login

POST /auth/login
Content-Type: application/json

{
  "email": "user@example.com",
  "password": "SecurePassword123!"
}

Response (200 OK):

{
  "access_token": "eyJhbGc...",
  "refresh_token": "eyJhbGc...",
  "token_type": "bearer",
  "expires_in": 3600
}

Refresh Token

POST /auth/refresh
Content-Type: application/json

{
  "refresh_token": "eyJhbGc..."
}

Response (200 OK):

{
  "access_token": "eyJhbGc...",
  "token_type": "bearer",
  "expires_in": 3600
}

Logout

POST /auth/logout
Authorization: Bearer <token>

Response (204 No Content)

Assets Endpoints

Upload Asset

POST /assets/
Authorization: Bearer <token>
Content-Type: multipart/form-data

file=<binary>
title=My Image
description=Image description
tags=tag1,tag2
track_a_enabled=true
track_b_enabled=true
track_c_enabled=true
metadata_tracking_enabled=true
blockchain_commit=true

Parameters:

Name Type Required Description
file binary Yes Image file (JPEG, PNG, TIFF, WebP)
title string No Asset title
description string No Asset description
tags string No Comma-separated tags
track_a_enabled boolean No Enable watermark track A
track_b_enabled boolean No Enable watermark track B
track_c_enabled boolean No Enable watermark track C (neural)
metadata_tracking_enabled boolean No Extract and track metadata
blockchain_commit boolean No Create blockchain commitment

Response (201 Created):

{
  "id": "uuid",
  "organization_id": "uuid",
  "cid": "bafyrei...",
  "content_hash": "sha256hash",
  "title": "My Image",
  "mime_type": "image/jpeg",
  "file_size_bytes": 102400,
  "width": 1920,
  "height": 1080,
  "ipfs_cid": "bafyrei...",
  "watermarked_cid": "bafyrei...",
  "processing_status": "completed",
  "created_at": "2024-01-15T10:30:00Z"
}

List Assets

GET /assets/?page=1&page_size=20&order=created_at&sort=desc
Authorization: Bearer <token>

Query Parameters:

Name Type Default Description
page integer 1 Page number
page_size integer 20 Items per page
order string created_at Sort field
sort string desc Sort direction (asc/desc)
tags string - Filter by tags
status string - Filter by processing_status

Response (200 OK):

{
  "items": [
    { "id": "uuid", ... }
  ],
  "total": 42,
  "page": 1,
  "page_size": 20,
  "pages": 3
}

Get Asset Details

GET /assets/{asset_id}
Authorization: Bearer <token>

Response (200 OK):

{
  "id": "uuid",
  "organization_id": "uuid",
  "cid": "bafyrei...",
  "content_hash": "sha256hash",
  "title": "My Image",
  "mime_type": "image/jpeg",
  "file_size_bytes": 102400,
  "width": 1920,
  "height": 1080,
  "ipfs_cid": "bafyrei...",
  "watermarked_cid": "bafyrei...",
  "processing_status": "completed",
  "created_at": "2024-01-15T10:30:00Z"
}

Update Asset

PATCH /assets/{asset_id}
Authorization: Bearer <token>
Content-Type: application/json

{
  "title": "Updated Title",
  "description": "New description",
  "tags": ["new", "tags"]
}

Response (200 OK):

{ ... updated asset ... }

Delete Asset

DELETE /assets/{asset_id}
Authorization: Bearer <token>

Response (204 No Content)

Verification Endpoints

Verify Image

POST /verify/
Content-Type: multipart/form-data

file=<binary>
include_tamper_map=true

Parameters:

Name Type Required Description
file binary Yes Image to verify
include_tamper_map boolean No Include pixel-level tamper visualization

Authentication: Optional (Bearer token or API key)

Response (200 OK):

{
  "is_authentic": true,
  "confidence": 0.95,
  "watermark": {
    "track_a_detected": true,
    "track_b_detected": true,
    "track_c_detected": true,
    "payload": "base64encoded"
  },
  "fingerprint": {
    "similarity_score": 0.89,
    "match_count": 15,
    "top_matches": [
      {
        "asset_id": "uuid",
        "similarity": 0.95,
        "distance": 0.05
      }
    ]
  },
  "blockchain": {
    "commitment_found": true,
    "tx_hash": "Ax5q...",
    "signature_valid": true,
    "on_chain": true
  },
  "metadata": {
    "exif_intact": true,
    "modifications": []
  },
  "tamper_map": "base64image",
  "verdict": "authentic",
  "details": "Image is authentic with high confidence"
}

Batch Verification

POST /verify/batch
Content-Type: multipart/form-data

files=<binary1>&files=<binary2>&files=<binary3>
include_tamper_map=false

Response (200 OK):

{
  "results": [
    { ... verification result ... },
    { ... verification result ... }
  ],
  "total": 3,
  "successful": 3,
  "failed": 0,
  "processing_time_ms": 5432
}

Get Verification History

GET /verify/history?page=1&page_size=20&verdict=authentic
Authorization: Bearer <token>

Query Parameters:

Name Type Description
page integer Page number
page_size integer Items per page
verdict string Filter by verdict (authentic/forged/unknown)
start_date string ISO 8601 start date
end_date string ISO 8601 end date

Response (200 OK):

{
  "items": [
    {
      "id": "uuid",
      "verified_at": "2024-01-15T10:30:00Z",
      "verdict": "authentic",
      "confidence": 0.95,
      "asset_id": "uuid",
      "matched_asset": { ... }
    }
  ],
  "total": 42,
  "page": 1
}

Organization Endpoints

Create Organization

POST /organizations/
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Acme Corp",
  "slug": "acme-corp",
  "plan": "pro"
}

Response (201 Created):

{
  "id": "uuid",
  "name": "Acme Corp",
  "slug": "acme-corp",
  "owner_id": "uuid",
  "plan": "pro",
  "created_at": "2024-01-15T10:30:00Z"
}

List Organizations

GET /organizations/
Authorization: Bearer <token>

Response (200 OK):

{
  "items": [ { ... } ],
  "total": 5
}

Get Organization Details

GET /organizations/{org_id}
Authorization: Bearer <token>

Response (200 OK):

{
  "id": "uuid",
  "name": "Acme Corp",
  "plan": "pro",
  "members_count": 8,
  "assets_count": 125,
  "created_at": "2024-01-15T10:30:00Z"
}

API Keys Endpoints

Create API Key

POST /api-keys/
Authorization: Bearer <token>
Content-Type: application/json

{
  "name": "Production API Key",
  "scopes": ["read", "verify"],
  "expires_in_days": 90
}

Response (201 Created):

{
  "id": "uuid",
  "key": "cert_pk_...",
  "name": "Production API Key",
  "scopes": ["read", "verify"],
  "expires_at": "2024-04-15T10:30:00Z",
  "created_at": "2024-01-15T10:30:00Z",
  "last_used_at": null
}

List API Keys

GET /api-keys/
Authorization: Bearer <token>

Response (200 OK):

{
  "items": [
    {
      "id": "uuid",
      "key": "cert_pk_...",
      "name": "Production API Key",
      "scopes": ["read", "verify"],
      "expires_at": "2024-04-15T10:30:00Z",
      "last_used_at": "2024-01-14T15:22:00Z",
      "is_active": true
    }
  ],
  "total": 3
}

Validate API Key

POST /api-keys/validate
X-API-Key: <api_key>

Response (200 OK):

{
  "valid": true,
  "scopes": ["read", "verify"],
  "key_id": "uuid",
  "name": "Production API Key",
  "is_active": true,
  "expires_at": "2024-04-15T10:30:00Z",
  "rate_limit": {
    "per_hour": 5000,
    "per_day": 50000
  }
}

Revoke API Key

DELETE /api-keys/{key_id}
Authorization: Bearer <token>

Response (204 No Content)

Blockchain Endpoints

Create Commitment

POST /blockchain/commit
Authorization: Bearer <token>
Content-Type: application/json

{
  "asset_id": "uuid",
  "watermark_hash": "sha256hash",
  "metadata": { ... }
}

Response (201 Created):

{
  "commitment_id": "uuid",
  "tx_hash": "Ax5q7n...",
  "signature": "base64sig",
  "commitment_hash": "sha256hash",
  "on_chain_at": "2024-01-15T10:30:05Z",
  "confirmation_status": "finalized"
}

Get Commitment Details

GET /blockchain/commitment/{commitment_id}

Response (200 OK):

{
  "commitment_id": "uuid",
  "asset_id": "uuid",
  "tx_hash": "Ax5q7n...",
  "commitment_hash": "sha256hash",
  "on_chain_at": "2024-01-15T10:30:05Z",
  "confirmation_status": "finalized",
  "verified": true
}

Error Codes

Code HTTP Description
INVALID_CREDENTIALS 401 Invalid email or password
TOKEN_EXPIRED 401 JWT token has expired
INVALID_API_KEY 401 API key is invalid or revoked
QUOTA_EXCEEDED 403 Usage quota exceeded
ASSET_NOT_FOUND 404 Asset does not exist
FILE_TOO_LARGE 400 File exceeds size limit
INVALID_FILE_TYPE 400 Unsupported file type
PROCESSING_FAILED 500 Asset processing error
BLOCKCHAIN_ERROR 500 Blockchain operation failed
RATE_LIMITED 429 Too many requests

Rate Limits

  • Free tier: 10 verifications/day, 100 uploads/month
  • Pro tier: 1000 verifications/day, 10000 uploads/month
  • Enterprise: Custom limits

Rate limit headers:

X-RateLimit-Limit: 1000
X-RateLimit-Remaining: 999
X-RateLimit-Reset: 1705334400

Pagination

All list endpoints support pagination:

?page=1&page_size=20

Response includes:

{
  "items": [...],
  "total": 100,
  "page": 1,
  "page_size": 20,
  "pages": 5
}

Webhooks

Create webhooks to receive events:

POST /webhooks/
Authorization: Bearer <token>
Content-Type: application/json

{
  "url": "https://your-domain.com/webhook",
  "events": ["asset.processed", "verification.completed"],
  "active": true
}

Webhook Payload:

{
  "event": "asset.processed",
  "timestamp": "2024-01-15T10:30:00Z",
  "data": {
    "asset_id": "uuid",
    "status": "completed"
  }
}

Pagination Examples

Get second page of assets

curl "http://localhost:8000/v1/assets/?page=2&page_size=50" \
  -H "Authorization: Bearer <token>"

Search with pagination

curl "http://localhost:8000/v1/assets/search/?q=logo&page=1&page_size=10" \
  -H "Authorization: Bearer <token>"

Next Steps