API Reference

OCC Protocol API

REST API for committing artifacts and verifying proofs. The commit endpoint runs inside an AWS Nitro Enclave.

Base URL
https://nitro.occproof.com

Authentication

Authentication is optional. If the server is configured with API keys, include a Bearer token:

Authorization header
Authorization: Bearer <your-api-key>

If no API keys are configured on the server, all endpoints are open. The public demo endpoint does not require authentication.

Endpoints

POST/commit

Commit one or more artifact digests. The enclave generates a fresh nonce, increments its monotonic counter, signs with Ed25519, and returns a complete OCC proof for each digest.

Request body

{
  "digests": [
    {
      "digestB64": "jYl9NHJP0VcRVh6OMEIU5VAGva6cu5kdrnPrlNr/RnU=",
      "hashAlg": "sha256"
    }
  ],
  "metadata": {                      // optional, advisory
    "source": "my-app",
    "fileName": "document.pdf"
  }
}

Response (200)

[
  {
    "version": "occ/1",
    "artifact": {
      "hashAlg": "sha256",
      "digestB64": "jYl9NHJP0VcRVh6OMEIU5VAGva6cu5kdrnPrlNr/RnU="
    },
    "commit": {
      "nonceB64": "gTME79qH3fXQ5qXX0JxX6T5oGhFRLLw2BIUoeQai9Z8=",
      "counter": "278",
      "time": 1741496392841,
      "epochId": "a1b2c3d4e5f6..."
    },
    "signer": {
      "publicKeyB64": "...",
      "signatureB64": "..."
    },
    "environment": {
      "enforcement": "measured-tee",
      "measurement": "ac813febd1ac4261...",
      "attestation": {
        "format": "aws-nitro",
        "reportB64": "..."
      }
    },
    "timestamps": {
      "artifact": {
        "authority": "http://freetsa.org/tsr",
        "time": "2026-03-07T12:00:00Z",
        "digestAlg": "sha256",
        "digestB64": "...",
        "tokenB64": "..."
      }
    }
  }
]

Example: curl

DIGEST=$(openssl dgst -sha256 -binary myfile.pdf | base64)

curl -X POST https://nitro.occproof.com/commit \
  -H "Content-Type: application/json" \
  -d '{
    "digests": [{
      "digestB64": "'$DIGEST'",
      "hashAlg": "sha256"
    }]
  }'

Example: TypeScript

const bytes = new Uint8Array(await file.arrayBuffer());
const hashBuf = await crypto.subtle.digest("SHA-256", bytes);
const digestB64 = btoa(String.fromCharCode(...new Uint8Array(hashBuf)));

const resp = await fetch("https://nitro.occproof.com/commit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    digests: [{ digestB64, hashAlg: "sha256" }],
  }),
});

const proofs = await resp.json();
// proofs[0] is a complete OCCProof
GET/key

Returns the enclave's current Ed25519 public key, platform measurement, and enforcement tier. Useful for pinning allowedMeasurements and allowedPublicKeys in verification policy.

Response (200)

{
  "publicKeyB64": "MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAE...",
  "measurement": "ac813febd1ac4261eff4a6c059f78a5ecfc8c577...",
  "enforcement": "measured-tee"
}
POST/verify

Server-side verification of a proof against an optional policy. Note: verification can also be done entirely client-side — no API call required.

Request body

{
  "proof": { ... },                  // complete OCCProof
  "policy": {                        // optional VerificationPolicy
    "requireEnforcement": "measured-tee",
    "allowedMeasurements": ["ac813febd1ac4261..."],
    "requireAttestation": true,
    "minCounter": "100"
  }
}

Response (200)

// Success
{ "valid": true }

// Failure
{ "valid": false, "reason": "measurement not in allowed set" }
GET/health

Health check. Returns 200 if the parent server is running and can communicate with the enclave.

Response (200)

{ "ok": true }

Type definitions

OCCProof

TypeScript
interface OCCProof {
  version: "occ/1";
  artifact: {
    hashAlg: "sha256";
    digestB64: string;
  };
  commit: {
    nonceB64: string;
    counter?: string;          // decimal, monotonic
    time?: number;             // Unix ms
    prevB64?: string;          // chain link
    epochId?: string;          // hex SHA-256
  };
  signer: {
    publicKeyB64: string;      // Ed25519, 32 bytes
    signatureB64: string;      // Ed25519, 64 bytes
  };
  environment: {
    enforcement: "stub" | "hw-key" | "measured-tee";
    measurement: string;
    attestation?: {
      format: string;          // e.g. "aws-nitro"
      reportB64: string;
    };
  };
  agency?: {                         // actor-bound proof
    actor: {
      keyId: string;
      publicKeyB64: string;
      algorithm: "ES256";
      provider: string;              // e.g. "apple-secure-enclave"
    };
    authorization: {
      purpose: "occ/commit-authorize/v1";
      actorKeyId: string;
      artifactHash: string;
      challenge: string;
      timestamp: number;
      signatureB64: string;          // P-256 ECDSA
    };
  };
  timestamps?: {
    artifact?: TsaToken;
    proof?: TsaToken;
  };
  metadata?: Record<string, unknown>;
}

VerificationPolicy

TypeScript
interface VerificationPolicy {
  requireEnforcement?: "stub" | "hw-key" | "measured-tee";
  allowedMeasurements?: string[];
  allowedPublicKeys?: string[];
  requireAttestation?: boolean;
  requireAttestationFormat?: string[];
  minCounter?: string;
  maxCounter?: string;
  minTime?: number;
  maxTime?: number;
  requireEpochId?: boolean;

  // Actor-bound proof policy
  requireActor?: boolean;
  allowedActorKeyIds?: string[];
  allowedActorProviders?: string[];
}

TsaToken

TypeScript
interface TsaToken {
  authority: string;
  time: string;               // ISO 8601
  digestAlg: string;
  digestB64: string;
  tokenB64: string;           // DER-encoded RFC 3161
}

Error responses

StatusCauseBody
400Invalid request body{ "error": "..." }
401Missing or invalid API key{ "error": "unauthorized" }
500Enclave / internal error{ "error": "internal server error" }