Skip to content
RealityProof
Menu

Production endpoints

What you store

Store one of these identifiers in your product.

IdentifierBest forLookup
verifyIdUser-facing proof URLs, listings, QR codesGET /v1/verify/{verifyId}
bundleHashFile, 3D object, or artifact verificationGET /v1/verify/hash/{bundleHash}
chainId + contract + tokenIdOptional token lookup when a proof was actually mintedGET /v1/token/{chainId}/{contract}/{tokenId}

For v1 integrations, prefer verifyId for UX and bundleHash for integrity checks.

One-minute integration

curl https://verify.realityproof.app/v1/verify/proof_demo_123

Expected shape:

{
  "verifyId": "proof_demo_123",
  "status": "finalized",
  "verificationLevel": "L1_SERVER_VERIFIED",
  "disclosure": "hashOnly",
  "bundleHash": "0x9d6f8c...",
  "capture": {
    "startedAt": null,
    "endedAt": null
  },
  "checks": [
    {
      "name": "App Attest assertion",
      "ok": true,
      "level": "L1_SERVER_VERIFIED",
      "detail": "App Attest assertion verified for this capture"
    }
  ],
  "artifacts": [
    {
      "kind": "scene",
      "contentType": "model/gltf-binary",
      "bytes": 1842219,
      "sha256": "4d9671..."
    }
  ],
  "assets": []
}

hashOnly means the public can verify the proof commitment without seeing private capture data.

Browser example

type PublicProof = {
  verifyId: string;
  status: "finalized" | "minted" | "failed";
  verificationLevel:
    | "L0_HASHED"
    | "L1_SERVER_VERIFIED"
    | "L2_COSIGNED"
    | "L3_CHAIN_ANCHORED"
    | "L4_FULL_WITNESSES";
  disclosure: "hashOnly" | "timeOnly" | "timeLocation" | "fullProof";
  bundleHash: `0x${string}` | null;
  checks: Array<{ name: string; ok: boolean; level: string; detail: string }>;
  assets?: Array<{ kind: string; href: string; sha256: string; contentType: string }>;
};

export async function verifyRealityProof(verifyId: string): Promise<PublicProof> {
  const response = await fetch(
    `https://verify.realityproof.app/v1/verify/${encodeURIComponent(verifyId)}`,
  );

  if (!response.ok) {
    throw new Error(`Proof lookup failed: ${response.status}`);
  }

  return response.json() as Promise<PublicProof>;
}

Marketplace pattern

  1. Your workflow sends the seller a RealityProof capture request.
  2. Seller receives a verifyId and bundleHash.
  3. Your listing form stores both values.
  4. Your listing page calls GET /v1/verify/{verifyId}.
  5. Show verification level, bundle hash, check count, and only the fields the seller disclosed.

Do not require sellers to expose files by default. The strongest integration is privacy-respecting: the commitment is public, private data remains opt-in.

Artifact verification

If a user later provides a file, 3D object, scan archive, or sensor export, verify it by computing SHA-256 locally and comparing it to the public proof artifact list.

export async function sha256Hex(file: File): Promise<string> {
  const digest = await crypto.subtle.digest("SHA-256", await file.arrayBuffer());
  return [...new Uint8Array(digest)]
    .map((byte) => byte.toString(16).padStart(2, "0"))
    .join("");
}

Then compare the result to proof.artifacts[].sha256.

Disclosure levels

LevelPublic data
hashOnlyverifyId, bundleHash, status, verification level, public checks, artifact hashes
timeOnlyhashOnly plus capture start and end time
timeLocationtimeOnly plus location
fullProofPublic proof assets if retained, plus full public context

Storage and disclosure are separate choices. A proof can expose hashes without retaining the underlying files.

Verification levels

LevelMeaning
L0_HASHEDHash record exists
L1_SERVER_VERIFIEDBackend verified the submitted proof material
L2_COSIGNEDConditional: an optional KMS witness was available and passed
L3_CHAIN_ANCHOREDConditional: the bundle hash was included in actual on-chain state
L4_FULL_WITNESSESConditional: all required witnesses for that policy were present

Production baseline

Current production proofs should be expected to report L1_SERVER_VERIFIED. Higher levels are conditional and must never be inferred from a product plan or an unavailable optional check. Always render the level and checks returned by the API for the specific proof.

Integration checklist

Use the OpenAPI spec from /openapi.json for generated clients.
Store verifyId and bundleHash in your app.
Treat bundleHash as the immutable commitment.
Treat assets as optional. They only appear for fullProof.
Do not scrape private data from screenshots or retained files.
Re-check before high-value actions.
Show a clear state for failed, missing, or disclosure-denied proofs.
Use the MCP guide when an agent needs to verify proofs.

Agent builders can continue with the MCP integration guide.