{ "openapi": "3.0.3", "info": { "title": "Developer Portal API", "version": "1.0.0", "description": "OpenAPI reference for Developer Portal endpoints used across Mini Apps and World ID." }, "servers": [ { "url": "https://developer.world.org", "description": "Primary" }, { "url": "https://developer.worldcoin.org", "description": "Legacy domain" }, { "url": "https://staging-developer.worldcoin.org", "description": "Staging domain" } ], "paths": { "/api/v2/verify/{app_id}": { "post": { "summary": "Verify (Legacy)", "description": "Verify a World ID proof for a Cloud action.", "x-mint": { "href": "/api-reference/developer-portal/verify-legacy" }, "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Your app ID from the Developer Portal" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyProofRequest" }, "example": { "nullifier_hash": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "merkle_root": "0x2264a66d162d7893e12ea8e3c072c51e785bc085ad655f64c10c1a61e00f0bc2", "proof": "0x1aa8b8f3b2d2de5ff452c0e1a83e29d6bf46fb83ef35dc5957121ff3d3698a1119090fb...", "verification_level": "orb", "action": "my_action", "signal_hash": "0x00c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4", "max_age": 3600 } } } }, "responses": { "200": { "description": "Verified", "content": { "application/json": { "example": { "success": true, "action": "my_action", "nullifier_hash": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "created_at": "2023-02-18T11:20:39.530041+00:00" } } } }, "400": { "description": "Invalid or already verified", "content": { "application/json": { "examples": { "invalid_proof": { "value": { "code": "invalid_proof", "detail": "The provided proof is invalid and it cannot be verified. Please check all inputs and try again.", "attribute": null } }, "invalid_merkle_root": { "value": { "code": "invalid_merkle_root", "detail": "The provided Merkle root is invalid. User appears to be unverified.", "attribute": null } }, "root_too_old": { "value": { "code": "root_too_old", "detail": "The provided merkle root is too old. Please generate a new proof and try again.", "attribute": null } }, "invalid_credential_type": { "value": { "code": "invalid", "detail": "Invalid credential type.", "attribute": "credential_type" } }, "exceeded_max_verifications": { "value": { "code": "exceeded_max_verifications", "detail": "This user has exceeded the maximum number of verifications allowed for this proof.", "attribute": null } }, "already_verified": { "value": { "code": "already_verified", "detail": "This person has already verified for this action.", "attribute": null } } } } } } } } }, "/api/v2/minikit/send-notification": { "post": { "summary": "Send Notification", "description": "Send notifications to users of your mini app.", "x-mint": { "href": "/api-reference/developer-portal/send-notification" }, "security": [{ "bearerAuth": [] }], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendNotificationRequest" }, "example": { "app_id": "app_id", "wallet_addresses": [ "0x1234567890123456789012345678901234567890", "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" ], "title": "title", "message": "Hello ${username}, your transaction is complete!", "mini_app_path": "worldapp://mini-app?app_id=app_id" } } } }, "responses": { "200": { "description": "Notification send status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendNotificationResponse" } } } }, "400": { "description": "Invalid request, inactive API key, or the app can't send notifications (`validation_error`, `api_key_inactive`, `external_app_not_allowed`, `unverified_app_limit_reached`, `not_allowed`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "api_key_inactive": { "value": { "code": "api_key_inactive", "detail": "API key is inactive.", "attribute": "api_key" } }, "unverified_app_limit_reached": { "value": { "code": "unverified_app_limit_reached", "detail": "Unverified app limit reached", "attribute": "notifications" } } } } } }, "401": { "description": "Missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "unauthorized", "detail": "API key is required.", "attribute": "api_key" } } } }, "403": { "description": "API key rejected: `invalid_app` when the key's team doesn't own `app_id`, `invalid_api_key` when the secret doesn't match.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_app": { "value": { "code": "invalid_app", "detail": "API key is not valid for this app.", "attribute": "api_key" } }, "invalid_api_key": { "value": { "code": "invalid_api_key", "detail": "API key is not valid.", "attribute": "api_key" } } } } } }, "404": { "description": "API key not found (`not_found`), or the app is banned or has no metadata (`app_not_found`, attribute `app`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "not_found", "detail": "API key not found.", "attribute": "api_key" } } } } } } }, "/api/v2/minikit/transaction/{transaction_id}": { "get": { "summary": "Get Transaction", "description": "Query transactions for their current status.", "x-mint": { "href": "/api-reference/developer-portal/get-transaction" }, "parameters": [ { "name": "transaction_id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "The transaction identifier returned by the API" }, { "name": "app_id", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Your app ID from the Developer Portal" }, { "name": "type", "in": "query", "required": false, "schema": { "type": "string", "enum": ["payment", "transaction"] }, "description": "Optional. `payment` (default) or `transaction` depending on the command you used." } ], "responses": { "200": { "description": "Transaction status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetTransactionResponse" } } } }, "400": { "description": "Invalid transaction ID", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "invalid_parameter", "detail": "Invalid transaction ID", "attribute": "transaction_id" } } } } } } }, "/api/v2/minikit/userop/{user_op_hash}": { "get": { "summary": "Get User Operation", "description": "Query a MiniKit user operation by `userOpHash` and resolve the final on-chain transaction hash when it becomes available.", "x-mint": { "href": "/api-reference/developer-portal/get-user-operation" }, "parameters": [ { "name": "user_op_hash", "in": "path", "required": true, "schema": { "type": "string", "pattern": "^0x[a-fA-F0-9]{64}$" }, "description": "The MiniKit `userOpHash` returned by `MiniKit.sendTransaction()` or `eth_sendTransaction` through the World App provider." } ], "responses": { "200": { "description": "User operation status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetUserOperationResponse" }, "examples": { "pending": { "value": { "status": "pending", "userOpHash": "0x8004b63530b968a2a2c9ff414e01fc06a3ec5e4068d36d923df6aa4334744369", "sender": null, "transaction_hash": null, "nonce": null } }, "success": { "value": { "status": "success", "userOpHash": "0x8004b63530b968a2a2c9ff414e01fc06a3ec5e4068d36d923df6aa4334744369", "sender": "0x1234567890123456789012345678901234567890", "transaction_hash": "0x1111111111111111111111111111111111111111111111111111111111111111", "nonce": "0x2a" } }, "failed": { "value": { "status": "failed", "userOpHash": "0x8004b63530b968a2a2c9ff414e01fc06a3ec5e4068d36d923df6aa4334744369", "sender": "0x1234567890123456789012345678901234567890", "transaction_hash": "0x2222222222222222222222222222222222222222222222222222222222222222", "nonce": "0x2a" } } } } } }, "400": { "description": "Invalid user operation hash", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "invalid_parameter", "detail": "Invalid user operation hash", "attribute": "user_op_hash" } } } }, "500": { "description": "Failed to fetch user operation status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "internal_api_error", "detail": "Failed to fetch user operation status", "attribute": "user_op_hash" } } } } } } }, "/api/v2/minikit/transaction/debug": { "get": { "summary": "Get Transaction Debug URL", "description": "Debug transactions that failed during the prepare stage. Returns Tenderly URLs when applicable.", "x-mint": { "href": "/api-reference/developer-portal/get-transaction-debug-url" }, "security": [{ "bearerAuth": [] }], "parameters": [ { "name": "app_id", "in": "query", "required": true, "schema": { "type": "string" }, "description": "The `app_id` corresponding to the transaction that is being queried." } ], "responses": { "200": { "description": "Debug information list", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetDebugUrlResponse" }, "example": { "transactions": [ { "debugUrl": "https://dashboard.tenderly.co/tx/...", "createdAt": "2024-03-21T10:30:00.000Z", "block": 12345678, "simulationRequestId": "sim_abc123def456", "simulationError": "Permit signature expired", "walletAddress": "0x1234..." } ] } } } }, "400": { "description": "Invalid `app_id` (`validation_error`) or inactive API key (`api_key_inactive`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "api_key_inactive", "detail": "API key is inactive.", "attribute": "api_key" } } } }, "401": { "description": "Missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "unauthorized", "detail": "API key is required.", "attribute": "api_key" } } } }, "403": { "description": "API key rejected: `invalid_app` when the key's team doesn't own `app_id`, `invalid_api_key` when the secret doesn't match.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_app": { "value": { "code": "invalid_app", "detail": "API key is not valid for this app.", "attribute": "api_key" } }, "invalid_api_key": { "value": { "code": "invalid_api_key", "detail": "API key is not valid.", "attribute": "api_key" } } } } } }, "404": { "description": "API key not found (`not_found`), or no debug URL is available yet (`debug_url_not_available`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "not_found": { "value": { "code": "not_found", "detail": "API key not found.", "attribute": "api_key" } }, "debug_url_not_available": { "value": { "code": "debug_url_not_available", "detail": "Debug URL is not yet available. Please try again later.", "attribute": "debug" } } } } } } } } }, "/public/v1/miniapps/prices": { "get": { "summary": "Get Prices", "description": "Query latest prices of tokens in various fiat currencies.", "x-mint": { "href": "/api-reference/developer-portal/get-prices" }, "servers": [ { "url": "https://app-backend.toolsforhumanity.com" } ], "parameters": [ { "name": "fiatCurrencies", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Comma-separated ISO4217 fiat codes, e.g. USD,EUR,JPY" }, { "name": "cryptoCurrencies", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Comma-separated crypto codes, e.g. USDC,WLD" } ], "responses": { "200": { "description": "Prices response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GetPricesResponse" } } } }, "426": { "description": "Rejected by an app-version/client gate. Expects an approved client (e.g. World App); required header(s) aren't publicly documented.", "content": { "application/json": { "example": { "allowRetry": false, "error": { "success": false, "code": "AU-001", "message": "App update required" } } } } } } } }, "/api/v2/minikit/user-grant-cycle": { "get": { "summary": "Get User Grant Cycle", "description": "Retrieve the next grant claim date for a user of your mini app. Returns the user's humanity (orb-verified) grant cycle date if available, otherwise falls back to their document (passport-verified) grant cycle date.", "x-mint": { "href": "/api-reference/developer-portal/get-user-grant-cycle" }, "security": [{ "bearerAuth": [] }], "parameters": [ { "name": "wallet_address", "in": "query", "required": true, "schema": { "type": "string", "minLength": 42, "maxLength": 42 }, "description": "The `wallet_address` of the user to query. Must be exactly 42 characters long." }, { "name": "app_id", "in": "query", "required": true, "schema": { "type": "string" }, "description": "The `app_id` of your mini app." } ], "responses": { "200": { "description": "Next grant date", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserGrantCycleResponse" } } } }, "400": { "description": "Invalid query (`validation_error`), inactive API key (`api_key_inactive`), or user not found / app not installed / no active cycles (`user_not_found_for_wallet_address`, `app_not_installed`, `no_active_grant_cycles`, attribute `user_grant_cycle`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "validation_error": { "value": { "code": "validation_error", "detail": "app_id is required", "attribute": "app_id" } }, "api_key_inactive": { "value": { "code": "api_key_inactive", "detail": "API key is inactive.", "attribute": "api_key" } } } } } }, "401": { "description": "Missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "unauthorized", "detail": "API key is required.", "attribute": "api_key" } } } }, "403": { "description": "API key rejected: `invalid_app` when the key's team doesn't own `app_id`, `invalid_api_key` when the secret doesn't match.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_app": { "value": { "code": "invalid_app", "detail": "API key is not valid for this app.", "attribute": "api_key" } }, "invalid_api_key": { "value": { "code": "invalid_api_key", "detail": "API key is not valid.", "attribute": "api_key" } } } } } }, "404": { "description": "API key not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "not_found", "detail": "API key not found.", "attribute": "api_key" } } } } } } }, "/api/v2/create-action/{app_id}": { "post": { "summary": "Create Incognito Action", "description": "Create an incognito action for your app.", "x-mint": { "href": "/api-reference/developer-portal/create-incognito-action" }, "security": [{ "bearerAuth": [] }], "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string" } } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateActionRequest" } } } }, "responses": { "200": { "description": "Action created", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateActionResponse" } } } }, "400": { "description": "Invalid request (`validation_error`), inactive API key (`api_key_inactive`), or the action already exists (`constraint-violation`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "api_key_inactive": { "value": { "code": "api_key_inactive", "detail": "API key is inactive.", "attribute": "api_key" } }, "constraint-violation": { "value": { "code": "constraint-violation", "detail": "Action already exists.", "attribute": "action" } } } } } }, "401": { "description": "Missing API key", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "unauthorized", "detail": "API key is required.", "attribute": "api_key" } } } }, "403": { "description": "API key rejected: `invalid_app` when the key's team doesn't own `app_id`, `invalid_api_key` when the secret doesn't match.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_app": { "value": { "code": "invalid_app", "detail": "API key is not valid for this app.", "attribute": "api_key" } }, "invalid_api_key": { "value": { "code": "invalid_api_key", "detail": "API key is not valid.", "attribute": "api_key" } } } } } }, "404": { "description": "API key not found.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "not_found", "detail": "API key not found.", "attribute": "api_key" } } } } } } }, "/api/v1/precheck/{app_id}": { "post": { "summary": "Get Action Metadata", "description": "Fetch information about a particular app/action to determine eligibility for verification.", "x-mint": { "href": "/api-reference/developer-portal/get-action-metadata" }, "parameters": [ { "name": "app_id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "Your app ID from the Developer Portal" } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "type": "object", "properties": { "action": { "type": "string", "description": "Action identifier passed to IDKit." }, "nullifier_hash": { "type": "string", "description": "ZKP's nullifier hash, as provided by IDKit" }, "external_nullifier": { "type": "string", "description": "Deprecated. Use action instead." } } }, "example": { "action": "my_custom_action", "nullifier_hash": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "external_nullifier": "0x00949dd9a8c5b600304d010ce3a3cf012352070ae4b77504e17af77ee894cda" } } } }, "responses": { "200": { "description": "OK. The `app_id` in the example is illustrative; a nonexistent or inactive app_id returns 404.", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": true }, "example": { "id": "app_staging_4cfd049031b0da1e8b62084b09a9f430", "is_staging": true, "is_verified": false, "name": "Default App", "verified_app_logo": "", "engine": "cloud", "__typename": "app", "sign_in_with_world_id": true, "can_user_verify": "yes", "action": { "external_nullifier": "0x00949dd9a8c5b600304d010ce3a3cf012352070ae4b77504e17af77ee894cda", "name": "My action", "action": "my_custom_action", "description": "My action", "max_verifications": 0, "max_accounts_per_user": 1, "__typename": "action" } } } } }, "400": { "description": "Bad Request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "required", "detail": "No action found for this app.", "attribute": "action" } } } }, "404": { "description": "App not found or inactive", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "example": { "code": "not_found", "detail": "We couldn't find an app with this ID. Action may be inactive.", "attribute": null } } } } } } }, "/api/v1/jwks": { "get": { "summary": "Get JWK Keys", "description": "Retrieve JWKs (public keys) used to verify JWT signatures for verification requests. Responses aren't cached at the edge, so cache keys client-side: refetch when a token's `kid` is unknown, and expire the cache after a bounded TTL (e.g. 1 hour) so removed keys stop being trusted.", "x-mint": { "href": "/api-reference/developer-portal/get-jwk-keys" }, "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "type": "object", "properties": { "keys": { "type": "array", "items": { "type": "object", "properties": { "e": { "type": "string" }, "n": { "type": "string" }, "kty": { "type": "string" }, "kid": { "type": "string" } } } } } } } } } } } }, "/api/v1/graphql": { "post": { "summary": "GraphQL Proxy", "description": "Proxy endpoint for Developer Portal GraphQL queries and mutations. Supports user JWTs and API keys. The example query requires authentication; an unauthenticated request returns HTTP 200 with a GraphQL `validation-failed` error (`field 'app' not found in type: 'query_root'`), not a 401.", "x-mint": { "href": "/api-reference/developer-portal/graphql-proxy" }, "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GraphQLProxyRequest" }, "example": { "query": "query MyApps { app { id name } }", "variables": {}, "operationName": "MyApps" } } } }, "responses": { "200": { "description": "GraphQL response payload", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GraphQLProxyResponse" } } } }, "400": { "description": "Body isn't JSON: wrong `Content-Type` (`invalid_content_type`) or malformed JSON (`invalid_json`).", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_content_type": { "value": { "code": "invalid_content_type", "detail": "Content-Type must be application/json.", "attribute": "content-type" } }, "invalid_json": { "value": { "code": "invalid_json", "detail": "Request body must be valid JSON.", "attribute": null } } } } } }, "401": { "description": "Rejected `api_` API key: not found, inactive, or wrong secret.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" }, "examples": { "invalid_or_inactive": { "value": { "code": "unauthenticated", "detail": "Invalid or inactive API key.", "attribute": null } }, "invalid_secret": { "value": { "code": "unauthenticated", "detail": "Invalid API key secret.", "attribute": null } } } } } } } } }, "/api/v4/verify/{rp_id}": { "post": { "summary": "Verify", "description": "Verifies World ID 4.0 proofs and legacy 3.0 proofs. Forward the complete IDKit result without remapping response identifiers or constructing a legacy `verification_level`. Use `rp_id` (`rp_...`) when possible; `app_id` (`app_...`) is still accepted for backward compatibility.", "x-mint": { "href": "/api-reference/developer-portal/verify" }, "parameters": [ { "name": "rp_id", "in": "path", "required": true, "schema": { "type": "string" }, "description": "RP ID (`rp_...`) is recommended. App ID (`app_...`) is also accepted for backward compatibility." } ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyV4Request" }, "examples": { "uniqueness_v3": { "summary": "Uniqueness proof (protocol 3.0)", "value": { "protocol_version": "3.0", "nonce": "0xabc123", "action": "my_action", "responses": [ { "identifier": "orb", "merkle_root": "0x2264a66d162d7893e12ea8e3c072c51e785bc085ad655f64c10c1a61e00f0bc2", "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "proof": "0x1aa8b8f3b2d2de5ff452c0e1a83e29d6bf46fb83ef35dc5957121ff3d3698a1119090fb...", "signal_hash": "0x00c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4", "max_age": 304200 } ], "environment": "production" } }, "uniqueness_v4": { "summary": "Uniqueness proof (protocol 4.0)", "value": { "protocol_version": "4.0", "nonce": "0xabc123", "action": "my_action", "responses": [ { "identifier": "proof_of_human", "issuer_schema_id": 1, "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "expires_at_min": 49012345, "proof": ["0x111", "0x222", "0x333", "0x444", "0x555"], "signal_hash": "0x0" } ] } }, "selfie_check_v4": { "summary": "Selfie Check", "value": { "protocol_version": "4.0", "nonce": "0xabc123", "action": "selfie-check-2026-09-02", "integrity_bundle": { "version": 2, "signature_format": "apple_app_attest", "timestamp": 1788302923, "signature": "a1b2c3d4", "jwt": "eyJ..." }, "responses": [ { "identifier": "selfie", "issuer_schema_id": 11, "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8", "expires_at_min": 1788302888, "proof": ["0x111", "0x222", "0x333", "0x444", "0x555"], "signal_hash": "0x0", "sybil_score": 10 } ] } }, "session_v4": { "summary": "Session proof (protocol 4.0)", "value": { "protocol_version": "4.0", "nonce": "0xabc123", "session_id": "session_5f3a9c2e...8d1b0a", "responses": [ { "identifier": "proof_of_human", "issuer_schema_id": 1, "session_nullifier": ["0xaaa", "0xbbb"], "expires_at_min": 49012345, "proof": ["0x111", "0x222", "0x333", "0x444", "0x555"] } ] } } } } } }, "responses": { "200": { "description": "At least one proof verified successfully", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyV4SuccessResponse" } } } }, "400": { "description": "Validation or verification error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyV4ErrorResponse" }, "examples": { "app_not_migrated": { "value": { "success": false, "code": "app_not_migrated", "detail": "This app has not been migrated to World ID 4.0. Please use the v2 verify endpoint." } }, "all_verifications_failed": { "value": { "success": false, "code": "all_verifications_failed", "detail": "All proof verifications failed.", "results": [ { "identifier": "orb", "success": false, "code": "verification_error", "detail": "On-chain proof verification failed." } ] } } } } } }, "404": { "description": "App not found or no longer active", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/VerifyV4ErrorResponse" } } } } } } } }, "components": { "securitySchemes": { "bearerAuth": { "type": "http", "scheme": "bearer" } }, "schemas": { "VerifyProofRequest": { "type": "object", "required": [ "nullifier_hash", "proof", "merkle_root", "verification_level", "action" ], "properties": { "nullifier_hash": { "type": "string", "description": "The unique user identifier (called the nullifier hash in the ZKP), as provided by [IDKit](/world-id/idkit/integrate)." }, "proof": { "type": "string", "description": "The zero-knowledge proof, as provided by [IDKit](/world-id/idkit/integrate)." }, "merkle_root": { "type": "string", "description": "Part of the ZKP, the hash of the Merkle root that proves membership to the set of credentials. As provided by [IDKit](/world-id/idkit/integrate)." }, "verification_level": { "type": "string", "enum": [ "orb", "secure_document", "document", "device", "face", "selfie" ], "description": "The legacy verification level. Use `selfie` for Selfie Check. The historical `face` value remains accepted for backward compatibility and behaves the same as `selfie`." }, "action": { "type": "string", "description": "Same action identifier as passed to [IDKit](/world-id/idkit/integrate)." }, "signal_hash": { "type": "string", "description": "The hash of the signal that was used to generate the proof. Defaults to the hash of an empty string." }, "max_age": { "type": "integer", "minimum": 3600, "maximum": 604800, "default": 7200, "description": "The maximum age of the root in seconds. This parameter controls how old the Merkle root used in the proof can be. Minimum value is 3600 (1 hour) and maximum value is 604800 (7 days). Defaults to 7200 (2 hours)." } } }, "SendNotificationRequest": { "oneOf": [ { "type": "object", "required": [ "wallet_addresses", "title", "message", "mini_app_path", "app_id" ], "properties": { "wallet_addresses": { "type": "array", "items": { "type": "string" }, "description": "Array of wallet addresses to notify. Users must have opted in. Max 1000 per call." }, "title": { "type": "string", "maxLength": 30 }, "message": { "type": "string", "maxLength": 200 }, "mini_app_path": { "type": "string", "description": "Deeplink to open when the user taps the notification: a WorldApp/World ID mini app deeplink (`worldapp://mini-app?app_id=...` or `worldid://mini-app?app_id=...`, where `app_id` must match the request's `app_id`), a Deep Face Universal Link (`https://world.org/verify?t=deepface`), or a Deep Face deeplink (`worldapp://verify?t=deepface`, `worldid://verify?t=deepface`, `worldidstg://verify?t=deepface`)." }, "app_id": { "type": "string" } }, "not": { "required": ["localisations"] } }, { "type": "object", "required": [ "wallet_addresses", "localisations", "mini_app_path", "app_id" ], "properties": { "wallet_addresses": { "type": "array", "items": { "type": "string" }, "description": "Array of wallet addresses to notify. Users must have opted in. Max 1000 per call." }, "localisations": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/SendNotificationLocalisation" }, "description": "Localized notification content. Include at least `en`." }, "mini_app_path": { "type": "string", "description": "Deeplink to open when the user taps the notification: a WorldApp/World ID mini app deeplink (`worldapp://mini-app?app_id=...` or `worldid://mini-app?app_id=...`, where `app_id` must match the request's `app_id`), a Deep Face Universal Link (`https://world.org/verify?t=deepface`), or a Deep Face deeplink (`worldapp://verify?t=deepface`, `worldid://verify?t=deepface`, `worldidstg://verify?t=deepface`)." }, "app_id": { "type": "string" } } } ], "description": "Supports legacy payload (`title` + `message`) and localized payload (`localisations`). If `localisations` is present, the localized payload is used and `title`/`message` are ignored." }, "SendNotificationResultItem": { "type": "object", "properties": { "walletAddress": { "type": "string" }, "sent": { "type": "boolean" }, "reason": { "type": "string" } } }, "SendNotificationResponse": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "type": "integer" }, "result": { "type": "array", "items": { "$ref": "#/components/schemas/SendNotificationResultItem" } } } }, "GetTransactionResponse": { "type": "object", "properties": { "reference": { "type": "string", "description": "Your unique reference for the transaction" }, "transaction_hash": { "type": "string", "description": "On-chain transaction hash" }, "transaction_status": { "type": "string", "enum": ["pending", "mined", "failed"], "description": "Current status of the transaction" }, "from": { "type": "string", "description": "Sender address" }, "chain": { "type": "string", "description": "Blockchain network name" }, "timestamp": { "type": "string", "format": "date-time", "description": "ISO 8601 timestamp when created" }, "token_amount": { "type": "string", "description": "Amount transferred (BigInt with 6 decimals)" }, "token": { "type": "string", "description": "Token symbol" }, "to": { "type": "string", "description": "Receiver address" }, "app_id": { "type": "string", "description": "Your app ID" } } }, "GetUserOperationResponse": { "type": "object", "properties": { "status": { "type": "string", "enum": ["pending", "success", "failed"], "description": "Current user operation status." }, "userOpHash": { "type": "string", "description": "The MiniKit user operation hash." }, "sender": { "type": "string", "nullable": true, "description": "The sender address when known." }, "transaction_hash": { "type": "string", "nullable": true, "description": "Final on-chain transaction hash, if available." }, "nonce": { "type": "string", "nullable": true, "description": "User operation nonce, if available." } } }, "GetDebugUrlItem": { "type": "object", "properties": { "debugUrl": { "type": "string", "description": "Tenderly URL for debugging" }, "createdAt": { "type": "string", "format": "date-time", "description": "Creation timestamp" }, "block": { "type": "integer", "description": "Block number" }, "simulationRequestId": { "type": "string", "description": "Simulation request ID" }, "simulationError": { "type": "string", "description": "Simulation error message if any" }, "walletAddress": { "type": "string", "description": "Associated wallet address" } } }, "GetDebugUrlResponse": { "type": "object", "properties": { "transactions": { "type": "array", "items": { "$ref": "#/components/schemas/GetDebugUrlItem" } } } }, "GetPricesResponse": { "type": "object", "properties": { "result": { "type": "object", "properties": { "prices": { "type": "object", "description": "Nested object keyed by currency codes with price details" } } } } }, "UserGrantCycleResponse": { "type": "object", "properties": { "success": { "type": "boolean" }, "status": { "type": "integer" }, "result": { "type": "object", "properties": { "nextGrantClaimUTCDate": { "type": "string", "format": "date-time" } } } } }, "CreateActionRequest": { "type": "object", "required": ["action"], "properties": { "action": { "type": "string", "description": "Identifier for the incognito action" }, "name": { "type": "string", "description": "Human-readable name for the action" }, "description": { "type": "string", "description": "Description for the action" }, "max_verifications": { "type": "integer", "default": 1, "description": "Maximum number of verifications allowed for this action" } } }, "CreateActionResponse": { "type": "object", "properties": { "action": { "type": "object", "properties": { "action": { "type": "string", "description": "Action identifier" }, "name": { "type": "string", "description": "Action name" }, "description": { "type": "string", "description": "Action description" }, "max_verifications": { "type": "integer", "description": "Max verifications for the action" }, "external_nullifier": { "type": "string", "description": "External nullifier derived from action and app_id" } } } } }, "ErrorResponse": { "type": "object", "properties": { "code": { "type": "string" }, "detail": { "type": "string" }, "attribute": { "type": "string", "nullable": true }, "app_id": { "type": "string", "description": "Included when the request identifies an app." }, "team_id": { "type": "string", "description": "Included when the route has resolved the app's team." } } }, "GraphQLProxyRequest": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string", "description": "GraphQL query or mutation string." }, "variables": { "type": "object", "additionalProperties": true, "description": "Optional GraphQL variables object." }, "operationName": { "type": "string", "description": "Optional operation name." } } }, "GraphQLProxyResponse": { "type": "object", "additionalProperties": true, "description": "Pass-through GraphQL response. Usually includes `data` and optionally `errors`." }, "IntegrityBundle": { "type": "object", "required": ["version", "signature_format", "timestamp", "signature", "jwt"], "description": "World ID App integrity attestation. Selfie Check responses with `issuer_schema_id: 11` require version 2, which covers the disclosed `sybil_score`.", "properties": { "version": { "type": "integer", "enum": [1, 2] }, "signature_format": { "type": "string", "enum": ["apple_app_attest", "android_keystore"] }, "timestamp": { "type": "integer", "minimum": 0 }, "signature": { "type": "string", "description": "Hex-encoded device signature." }, "jwt": { "type": "string", "description": "Attestation Gateway JWT used to verify the signing key." } } }, "VerifyV4Request": { "description": "Choose one request type.", "oneOf": [ { "title": "Legacy Proofs (v3)", "allOf": [ { "$ref": "#/components/schemas/VerifyV4LegacyProofRequest" } ] }, { "title": "Uniqueness Proofs", "allOf": [ { "$ref": "#/components/schemas/VerifyV4UniquenessProofRequest" } ] }, { "title": "Session Proofs", "allOf": [ { "$ref": "#/components/schemas/VerifyV4SessionProofRequest" } ] } ] }, "VerifyV4LegacyProofRequest": { "title": "Legacy Proofs (v3)", "type": "object", "required": ["protocol_version", "nonce", "action", "responses"], "description": "Legacy uniqueness proof format (protocol 3.0).", "properties": { "protocol_version": { "type": "string", "enum": ["3.0"] }, "nonce": { "type": "string" }, "action": { "type": "string" }, "action_description": { "type": "string" }, "environment": { "type": "string", "enum": ["production", "staging", "sandbox"], "default": "production" }, "integrity_bundle": { "$ref": "#/components/schemas/IntegrityBundle" }, "responses": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/VerifyV4ResponseItemV3" } }, "user_presence_completed": { "type": "boolean", "description": "Whether World App completed the requested user-presence check. IDKit includes this field only when `require_user_presence` was true in the request." } } }, "VerifyV4UniquenessProofRequest": { "title": "Uniqueness Proofs", "type": "object", "required": ["protocol_version", "nonce", "action", "responses"], "description": "Standard uniqueness proof format (protocol 4.0).", "properties": { "protocol_version": { "type": "string", "enum": ["4.0"] }, "nonce": { "type": "string" }, "action": { "type": "string" }, "action_description": { "type": "string" }, "environment": { "type": "string", "enum": ["production", "staging", "sandbox"], "default": "production" }, "integrity_bundle": { "description": "Required with version 2 when any response item is a Selfie Check credential (`issuer_schema_id: 11`).", "allOf": [ { "$ref": "#/components/schemas/IntegrityBundle" } ] }, "responses": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/VerifyV4ResponseItemV4" } }, "user_presence_completed": { "type": "boolean", "description": "Whether World App completed the requested user-presence check. IDKit includes this field only when `require_user_presence` was true in the request." } } }, "VerifyV4SessionProofRequest": { "title": "Session Proofs", "type": "object", "required": ["protocol_version", "nonce", "session_id", "responses"], "description": "Session proof format (protocol 4.0).", "properties": { "protocol_version": { "type": "string", "enum": ["4.0"] }, "nonce": { "type": "string" }, "session_id": { "type": "string", "description": "Opaque session ID in the format session_<128 hex characters>.", "example": "session_5f3a9c2e...8d1b0a" }, "environment": { "type": "string", "enum": ["production", "staging", "sandbox"], "default": "production" }, "integrity_bundle": { "description": "Required with version 2 when any response item is a Selfie Check credential (`issuer_schema_id: 11`).", "allOf": [ { "$ref": "#/components/schemas/IntegrityBundle" } ] }, "responses": { "type": "array", "minItems": 1, "items": { "$ref": "#/components/schemas/VerifyV4SessionResponseItem" } }, "user_presence_completed": { "type": "boolean", "description": "Whether World App completed the requested user-presence check. IDKit includes this field only when `require_user_presence` was true in the request." } } }, "VerifyV4ResponseItemV3": { "type": "object", "required": ["identifier", "proof", "merkle_root", "nullifier"], "properties": { "identifier": { "type": "string", "description": "Credential identifier returned by IDKit (for example, `orb` or `selfie`). Use `selfie` for Selfie Check; the historical `face` value remains accepted as a backward-compatible alias." }, "signal_hash": { "type": "string", "default": "0x00c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4" }, "merkle_root": { "type": "string" }, "nullifier": { "type": "string" }, "proof": { "type": "string" }, "max_age": { "type": "integer", "minimum": 3600, "maximum": 604800 } } }, "VerifyV4ResponseItemV4": { "type": "object", "required": [ "identifier", "issuer_schema_id", "nullifier", "expires_at_min", "proof" ], "properties": { "identifier": { "type": "string" }, "signal_hash": { "type": "string", "default": "0x0" }, "issuer_schema_id": { "type": "integer" }, "nullifier": { "type": "string" }, "expires_at_min": { "type": "integer" }, "proof": { "type": "array", "minItems": 5, "maxItems": 5, "items": { "type": "string" }, "description": "Exactly 5 hex elements (4 compressed proof elements + Merkle root)." }, "sybil_score": { "type": "integer", "minimum": 0, "description": "Versioned Selfie Check risk signal represented as an integer. Required only when `issuer_schema_id` is 11." } } }, "VerifyV4SessionResponseItem": { "type": "object", "required": [ "identifier", "issuer_schema_id", "session_nullifier", "expires_at_min", "proof" ], "properties": { "identifier": { "type": "string" }, "signal_hash": { "type": "string", "default": "0x0" }, "issuer_schema_id": { "type": "integer" }, "session_nullifier": { "type": "array", "minItems": 2, "maxItems": 2, "items": { "type": "string" }, "description": "Tuple `[nullifier, action]`." }, "expires_at_min": { "type": "integer" }, "proof": { "type": "array", "minItems": 5, "maxItems": 5, "items": { "type": "string" } }, "sybil_score": { "type": "integer", "minimum": 0, "description": "Versioned Selfie Check risk signal represented as an integer. Required only when `issuer_schema_id` is 11." } } }, "VerifyV4Result": { "type": "object", "properties": { "identifier": { "type": "string" }, "success": { "type": "boolean" }, "nullifier": { "type": "string" }, "code": { "type": "string" }, "detail": { "type": "string" } } }, "VerifyV4SuccessResponse": { "type": "object", "required": ["success", "results"], "properties": { "success": { "type": "boolean", "enum": [true] }, "action": { "type": "string" }, "nullifier": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "environment": { "type": "string", "enum": ["production", "staging", "sandbox"] }, "session_id": { "type": "string", "description": "Opaque session ID in the format session_<128 hex characters>.", "example": "session_5f3a9c2e...8d1b0a" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/VerifyV4Result" } }, "message": { "type": "string" } } }, "VerifyV4ErrorResponse": { "type": "object", "required": ["success", "code", "detail"], "properties": { "success": { "type": "boolean", "enum": [false] }, "code": { "type": "string" }, "detail": { "type": "string" }, "results": { "type": "array", "items": { "$ref": "#/components/schemas/VerifyV4Result" } } } }, "SendNotificationLocalisation": { "type": "object", "required": ["language", "title", "message"], "properties": { "language": { "type": "string" }, "title": { "type": "string", "maxLength": 30 }, "message": { "type": "string", "maxLength": 200 } } } } } }