Production endpoints
| Surface | URL |
|---|---|
| API docs | https://verify.realityproof.app |
| OpenAPI spec | https://verify.realityproof.app/openapi.json |
| Latest proofs | https://verify.realityproof.app/v1/proofs |
What you store
Store one of these identifiers in your product.
| Identifier | Best for | Lookup |
|---|---|---|
verifyId | User-facing proof URLs, listings, QR codes | GET /v1/verify/{verifyId} |
bundleHash | File, 3D object, or artifact verification | GET /v1/verify/hash/{bundleHash} |
chainId + contract + tokenId | Optional token lookup when a proof was actually minted | GET /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_123Expected 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
- Your workflow sends the seller a RealityProof capture request.
- Seller receives a
verifyIdandbundleHash. - Your listing form stores both values.
- Your listing page calls
GET /v1/verify/{verifyId}. - 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
| Level | Public data |
|---|---|
hashOnly | verifyId, bundleHash, status, verification level, public checks, artifact hashes |
timeOnly | hashOnly plus capture start and end time |
timeLocation | timeOnly plus location |
fullProof | Public 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
| Level | Meaning |
|---|---|
L0_HASHED | Hash record exists |
L1_SERVER_VERIFIED | Backend verified the submitted proof material |
L2_COSIGNED | Conditional: an optional KMS witness was available and passed |
L3_CHAIN_ANCHORED | Conditional: the bundle hash was included in actual on-chain state |
L4_FULL_WITNESSES | Conditional: 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
Agent builders can continue with the MCP integration guide.