{"service":"6529-zk-api","version":"0.1.0","environment":"production","generatedAt":"2026-07-03T04:44:09.996Z","capabilities":{"proofTypes":["tdh_range","level_range","card_ownership","any_card","n_of_m_cards","vpn_access_v1"],"rootRetentionDays":7},"endpoints":{"health":"/api/health","zk":"/api/zk","artifacts":"/api/artifacts/{path}","meta":"/api/meta","openapi":"/api/openapi","walletChallenge":"/api/auth/wallet/challenge","walletVerify":"/api/auth/wallet/verify","adminPartners":"/api/admin/partners","partnerBillingCheckout":"/api/admin/partners/{partnerId}/billing/checkout","partnerBillingPortal":"/api/admin/partners/{partnerId}/billing/portal","billingPlans":"/api/billing/plans","stripeWebhook":"/api/webhooks/stripe","syncTdh":"/api/sync/tdh","syncLevel":"/api/sync/level","syncCards":"/api/sync/cards"},"proofCatalog":[{"type":"tdh_range","label":"TDH Range","treeProofType":"tdh_range","availability":"live","purpose":"Prove a wallet is inside a TDH bucket without revealing the exact TDH amount.","lookupKey":{"format":"lowercase wallet address","examples":["0xabc0000000000000000000000000000000000001"],"authorization":"wallet_jwt","notes":"Proof lookup is wallet-bound. The bearer JWT must authorize the requested wallet."},"publicSignals":["merkleRoot","bucketMin","bucketMax","nullifierHash","commitmentHash"],"artifacts":{"wasm":"/api/artifacts/tdh-range-proof/tdh_range_proof_js/tdh_range_proof.wasm","zkey":"/api/artifacts/tdh-range-proof/tdh_range_proof_final.zkey"}},{"type":"level_range","label":"6529 Level Range","treeProofType":"level_range","availability":"live","purpose":"Prove a wallet is inside a 6529 profile level bucket without revealing the exact level.","lookupKey":{"format":"lowercase wallet address","examples":["0xabc0000000000000000000000000000000000001"],"authorization":"wallet_jwt","notes":"Proof lookup is wallet-bound. The bearer JWT must authorize the requested wallet."},"publicSignals":["merkleRoot","levelMin","levelMax","nullifierHash","commitmentHash"],"artifacts":{"wasm":"/api/artifacts/tdh-range-proof/tdh_range_proof_js/tdh_range_proof.wasm","zkey":"/api/artifacts/tdh-range-proof/tdh_range_proof_final.zkey"}},{"type":"card_ownership","label":"Card Ownership","treeProofType":"card_ownership","availability":"live","purpose":"Prove ownership of a specific 6529 Meme Card without exposing the full wallet state.","lookupKey":{"format":"lowercase wallet address followed by :cardId","examples":["0xabc0000000000000000000000000000000000001:1"],"authorization":"wallet_jwt","notes":"Proof lookup is wallet-bound. The card id remains part of the lookup key."},"publicSignals":["merkleRoot","cardId","nullifierHash","commitmentHash","batchId"]},{"type":"any_card","label":"Any Card","treeProofType":"card_ownership","availability":"derived","purpose":"Prove a wallet owns at least one 6529 Meme Card without revealing which card.","lookupKey":{"format":"lowercase wallet address","examples":["0xabc0000000000000000000000000000000000001"],"authorization":"wallet_jwt","notes":"Served from the card_ownership tree and resolved to a matching wallet:cardId proof."},"publicSignals":["merkleRoot","nullifierHash","commitmentHash"]},{"type":"n_of_m_cards","label":"N-of-M Cards","treeProofType":"card_ownership","availability":"derived","purpose":"Prove a wallet owns a threshold number of cards from a candidate set.","lookupKey":{"format":"one proof lookup per lowercase wallet address and candidate card id","examples":["0xabc0000000000000000000000000000000000001:1","0xabc0000000000000000000000000000000000001:2"],"authorization":"wallet_jwt","notes":"The browser SDK fetches the underlying card_ownership proofs needed for the set."},"publicSignals":["merkleRoot","threshold","nullifierHash","commitmentHash","batchId"]},{"type":"vpn_access_v1","label":"VPN Access V1","treeProofType":"vpn_access_v1","availability":"dev","purpose":"Prove membership in an anonymous paid-access entitlement set for VPN sessions.","lookupKey":{"format":"identity commitment","examples":["123456789012345678901234567890"],"authorization":"public","notes":"The current entitlement seeding route is for dev/staging issuer flows only."},"publicSignals":["merkleRoot","nullifierHash","challengeHash","sessionKeyHash"],"artifacts":{"wasm":"/api/artifacts/vpn-access-v1-proof/vpn_access_v1_proof_js/vpn_access_v1_proof.wasm","zkey":"/api/artifacts/vpn-access-v1-proof/vpn_access_v1_proof_final.zkey"}}],"limits":{"verify":{"limitPerWindow":30,"windowMs":60000},"artifactMaxBytes":52428800},"sdk":{"npmPackage":"@6529/zk-service","browserImport":"@6529/zk-service/browser","recommendedClientConfig":{"apiUrl":"https://zkyc.solutions","artifactBaseUrl":"https://zkyc.solutions/api/artifacts","timeoutMs":15000,"retries":2,"retryDelayMs":250}},"integration":{"productionBaseUrl":"https://zkyc.solutions","recommendedFlow":["Read /api/meta at app boot and cache the proof catalog.","Ask the wallet to sign a /api/auth/wallet/challenge message and exchange it at /api/auth/wallet/verify for a short-lived proof JWT.","Fetch the latest root for the proof type before starting a gate.","Generate the proof in the browser SDK so private inputs stay client-side.","Submit the proof to POST /api/zk for server-side verification.","Treat stale-root rejections as a refresh-and-retry signal inside the retention window."],"operatorOnlyEndpoints":["/api/sync/tdh","/api/sync/level","/api/sync/cards"]},"commercial":{"partnerApiKeyHeader":"X-ZKYC-API-Key","partnerAccessMode":"optional","directBrowserIntegration":{"defaultAllowedOrigins":["https://zkyc.solutions","https://www.zkyc.solutions","https://*.6529.io","http://localhost:*"],"notes":"Partner browser origins must be added to CORS_ALLOWED_ORIGINS or routed through a same-origin proxy."},"usageMeteredEvents":["root.lookup","proof.lookup","proof.verify","wallet.challenge","wallet.verify","artifact.fetch"],"billing":{"currency":"usd","billableEvent":"successful proof.verify","stripeConfigured":false,"stripeWebhookConfigured":false,"stripeMeterEventName":null,"plans":[{"key":"free","label":"Community","monthlyPriceUsd":0,"includedSuccessfulProofs":1000,"overageUsd":null,"stripePriceEnvVar":null,"selfServe":false},{"key":"starter","label":"Starter","monthlyPriceUsd":99,"includedSuccessfulProofs":10000,"overageUsd":0.02,"stripePriceEnvVar":"STRIPE_PRICE_STARTER","selfServe":false},{"key":"growth","label":"Growth","monthlyPriceUsd":299,"includedSuccessfulProofs":50000,"overageUsd":0.01,"stripePriceEnvVar":"STRIPE_PRICE_GROWTH","selfServe":false},{"key":"pro","label":"Pro","monthlyPriceUsd":999,"includedSuccessfulProofs":250000,"overageUsd":0.005,"stripePriceEnvVar":"STRIPE_PRICE_PRO","selfServe":false},{"key":"enterprise","label":"Enterprise","monthlyPriceUsd":null,"includedSuccessfulProofs":null,"overageUsd":null,"stripePriceEnvVar":"STRIPE_PRICE_ENTERPRISE","selfServe":false}],"notes":"Billing is subscription-first. Successful proof.verify events can be forwarded to a Stripe Billing Meter when STRIPE_METER_EVENT_NAME is configured."}}}