SYS:ONLINEBase Sepolia · AI Image Registry Protocol v1.0CHAIN:84532
AI
ZORAI

REST API FOR
AI PROVENANCE

ZorAI exposes a REST API that lets AI companies register generated content on Base Sepolia and returns metadata watermark fields they can embed into every file. Social platforms, newsrooms, and fact-checkers can then verify the same asset against the blockchain using either the content hash alone or the embedded watermark payload.

Protocol
REST over JSON
Network
Base Sepolia (84532)
Auth
x-api-key on register
Verifier access
Public verify endpoint

HOW PUBLISHERS SHOULD USE IT

The recommended flow keeps the blockchain record immutable while making the distributed file self-describing through metadata.

01

Generate the asset and compute a SHA-256 hash of the exact bytes you will publish.

02

Call POST /api/register with your API key and immutable storage pointer.

03

Embed the returned watermark and watermarkHash into EXIF or XMP metadata before delivery.

04

Let downstream platforms hash the file and call /api/verify to confirm provenance.

API KEY MODEL

Registration is authenticated because it writes to the blockchain through your platform signer. Verification is public so downstream platforms can query provenance without a wallet or an API key.

x-api-key: YOUR_API_KEY

EXPECTED RESPONSES

All endpoints return JSON responses. Status codes indicate success or failure. Always check the status code before parsing the response body.

200

Success

Request succeeded (most common response)

201

Created

Resource created (registration successful)

400

Bad Request

Invalid parameters, missing fields, or malformed JSON

401

Unauthorized

Missing or invalid API key (POST /api/register only)

429

Too Many Requests

Rate limit exceeded. Retry after 60 seconds

500

Server Error

Internal server error. Check status page or retry later

WHAT IS ACTUALLY VERIFIED

The blockchain-verifiable watermark includes only fields that can be reconstructed from on-chain state and the registration event. Optional publisher metadata can still be embedded, but only the watermark and watermarkHash are considered cryptographically verifiable.

{
  "version": "1.0",
  "zorai": true,
  "imageHash": "8f9d...c1a2",
  "model": "gpt-image-1",
  "registeredAt": "2026-04-21T23:12:10.000Z",
  "chain": "base-sepolia",
  "chainId": 84532,
  "contract": "0xd11eAEA00A92E6eE97DD14e6F97dbBb7971ef549",
  "txHash": "0x8b2d...",
  "blockNumber": 23812345
}

REFERENCE

These endpoints are enough to register assets from an AI generation pipeline and verify them from moderation or newsroom tooling.

POST/api/register

Register AI-generated content on ZorAI and receive a blockchain-backed watermark plus a metadata template you can embed before distribution.

FieldTypeRequiredDescription
imageHashstringrequiredSHA-256 hash of the generated asset (hex string, 64 chars)
modelUsedstringrequiredModel identifier such as "gpt-image-1" or "sdxl"
ipfsHashstringrequiredIPFS CID or immutable storage pointer (recorded on-chain)
companystringoptionalPublisher name for metadata and on-chain record
externalIdstringoptionalYour internal generation or asset tracking ID
sourceUrlstringoptionalCanonical URL where the asset will be served
contentTypestringoptionalAsset type (defaults to "image")
riskLevelnumberoptional0 = low, 1 = medium, 2 = high. Defaults to 0
riskReasonsstring[]optionalArray of policy or moderation flags
curl -X POST https://zorai.vercel.app/api/register \
  -H "Content-Type: application/json" \
  -H "x-api-key: YOUR_API_KEY" \
  -d '{
    "imageHash": "8f9d2f1e...",
    "modelUsed": "gpt-image-1",
    "ipfsHash": "bafybeiexample...",
    "company": "Example AI",
    "externalId": "gen_12345",
    "sourceUrl": "https://cdn.example.ai/assets/gen_12345.png",
    "riskLevel": 0,
    "riskReasons": []
  }'
HTTP/1.1 200 OK
Content-Type: application/json

{
  "success": true,
  "imageId": "8f9d2f1e...",
  "txHash": "0x8b2d4f...",
  "blockNumber": 23812345,
  "chain": "base-sepolia",
  "chainId": 84532,
  "contract": "0xd11eAEA00A92E6eE97DD14e6F97dbBb7971ef549",
  "watermark": {
    "version": "1.0",
    "zorai": true,
    "imageHash": "8f9d2f1e...",
    "model": "gpt-image-1",
    "registeredAt": "2026-04-21T23:12:10.000Z",
    "chain": "base-sepolia",
    "chainId": 84532,
    "contract": "0xd11eAEA00A92E6eE97DD14e6F97dbBb7971ef549",
    "txHash": "0x8b2d4f...",
    "blockNumber": 23812345
  },
  "watermarkHash": "eb02...",
  "metadataTemplate": {
    "aiGenerated": true,
    "zorai": {
      "watermark": { "version": "1.0", "zorai": true },
      "watermarkHash": "eb02..."
    },
    "xmpFields": {
      "XMP:ZorAI": "...full watermark...",
      "XMP:ZorAIHash": "eb02...",
      "XMP:AIGenerated": "true"
    }
  }
}
GET/api/verify?id={imageHash}

Look up an asset by SHA-256 hash and retrieve the blockchain registration record. Public endpoint, no API key required.

FieldTypeRequiredDescription
idstringrequiredSHA-256 hash of the image or asset to check (hex string, 64 chars)
curl "https://zorai.vercel.app/api/verify?id=8f9d2f1e..."
HTTP/1.1 200 OK
Content-Type: application/json

{
  "found": true,
  "isAiGenerated": true,
  "imageId": "8f9d2f1e...",
  "ipfsHash": "bafybeiexample...",
  "modelUsed": "gpt-image-1",
  "creator": "0xAbC123...",
  "registeredAt": "2026-04-21T23:12:10.000Z",
  "isVerified": false,
  "riskLevel": "low",
  "riskReasons": [],
  "watermark": {
    "onChainHash": "eb02...",
    "matchesBlockchain": null
  }
}
POST/api/verify

Verify a hash and optionally compare embedded ZorAI watermark metadata against the blockchain record. Public endpoint, no API key required.

FieldTypeRequiredDescription
imageHashstringrequiredSHA-256 hash of the asset being inspected (hex string, 64 chars)
watermarkobjectoptionalFull watermark object extracted from file metadata. If provided, will be compared against blockchain.
watermarkHashstringoptionalEmbedded watermark hash to compare (alternative to full watermark object)
curl -X POST https://zorai.vercel.app/api/verify \
  -H "Content-Type: application/json" \
  -d '{
    "imageHash": "8f9d2f1e...",
    "watermark": {
      "version": "1.0",
      "zorai": true,
      "imageHash": "8f9d2f1e...",
      "model": "gpt-image-1",
      "registeredAt": "2026-04-21T23:12:10.000Z",
      "chain": "base-sepolia",
      "chainId": 84532,
      "contract": "0xd11eAEA00A92E6eE97DD14e6F97dbBb7971ef549",
      "txHash": "0x8b2d4f...",
      "blockNumber": 23812345
    }
  }'
HTTP/1.1 200 OK
Content-Type: application/json

{
  "found": true,
  "isAiGenerated": true,
  "imageId": "8f9d2f1e...",
  "watermark": {
    "onChainHash": "eb02...",
    "suppliedHash": "eb02...",
    "matchesBlockchain": true
  }
}

CLIENT IMPLEMENTATIONS

You can consume the ZorAI REST API from any stack. Here are examples for a Python script, a FastAPI backend, and a verifier service.

import hashlib
import json
import requests

BASE_URL = "https://zorai.vercel.app"
API_KEY = "your_api_key"

def sha256_file(path: str) -> str:
    with open(path, "rb") as f:
        return hashlib.sha256(f.read()).hexdigest()

image_hash = sha256_file("output.png")

try:
    response = requests.post(
        f"{BASE_URL}/api/register",
        headers={
            "Content-Type": "application/json",
            "x-api-key": API_KEY,
        },
        json={
            "imageHash": image_hash,
            "modelUsed": "gpt-image-1",
            "ipfsHash": "bafybeigdyrexample...",
            "company": "Example AI",
            "externalId": "gen_12345",
        },
        timeout=30,
    )
    response.raise_for_status()
    payload = response.json()

    print(f"Transaction: {payload['txHash']}")
    print(json.dumps(payload["metadataTemplate"], indent=2))
except requests.exceptions.RequestException as e:
    print(f"Error: {e}")
from fastapi import FastAPI, HTTPException
import hashlib
import requests

app = FastAPI()
ZORAI_BASE_URL = "https://zorai.vercel.app"
ZORAI_API_KEY = "your_api_key"

def sha256_bytes(content: bytes) -> str:
    return hashlib.sha256(content).hexdigest()

@app.post("/publish-generated-image")
async def publish_generated_image(file_bytes: bytes):
    image_hash = sha256_bytes(file_bytes)

    try:
        response = requests.post(
            f"{ZORAI_BASE_URL}/api/register",
            headers={
                "Content-Type": "application/json",
                "x-api-key": ZORAI_API_KEY,
            },
            json={
                "imageHash": image_hash,
                "modelUsed": "gpt-image-1",
                "ipfsHash": "bafybeigdyrexample...",
                "company": "Example AI",
            },
            timeout=30,
        )
        response.raise_for_status()
        return response.json()
    except requests.exceptions.RequestException as e:
        raise HTTPException(status_code=502, detail=str(e))
async function verifyUpload(imageHash, extractedWatermark) {
  const res = await fetch("https://zorai.vercel.app/api/verify", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({
      imageHash,
      watermark: extractedWatermark,
    }),
  });

  const result = await res.json();

  return {
    shouldLabelAsAI: result.found,
    blockchainMatch: result.watermark.matchesBlockchain,
    model: result.modelUsed,
    riskLevel: result.riskLevel,
  };
}

TARGET USERS

The same infrastructure supports first-party publishers and third-party verification partners.

AI companies

Write provenance to-chain and ship every generated asset with reusable metadata watermark fields.

Social networks

Hash uploads, call /api/verify, and label content that maps to a ZorAI registration.

Newsrooms

Validate suspicious images before publication and compare embedded metadata with the blockchain record.

Fact-checkers

Use the public endpoint to retrieve model, timestamp, risk level, and creator address.