Skip to main content
Use this endpoint to verify World ID 3.0 (Legacy) or World ID 4.0 proofs. Should be used with IDKit 4.0+.
POST https://developer.world.org/api/v4/verify/{rp_id}
Accepts both rp_id (rp_xxx) and app_id (app_xxx) as the route parameter. The result from a successful pollUntilCompletion() response can be forwarded directly - no transformation needed. During the preview period, users will produce v3 proofs since World ID v4 has not launched yet. The endpoint verifies either format transparently.

Request Body

protocol_version
string
required
The protocol version. Must be "3.0" or "4.0". IDKit sets this automatically.
nonce
string
required
The nonce used in the RP signature, as returned by IDKit.
action
string
required
The action identifier. Must match the action passed to IDKit.request().
action_description
string
default:"\"\""
Human-readable description of the action. Used when creating the action for the first time.
responses
array
required
Array of proof response items (at least one). The shape of each item depends on protocol_version.

Response item fields (protocol 3.0)

responses[].identifier
string
required
Credential type (e.g. "orb").
responses[].proof
string
required
ABI-encoded zero-knowledge proof (hex string).
responses[].merkle_root
string
required
Merkle root hash (hex string).
responses[].nullifier
string
required
Nullifier hash (hex string, optional 0x prefix).
responses[].signal_hash
string
default:"keccak256('')"
Hash of the signal. Defaults to the keccak256 hash of an empty string.
responses[].max_age
number
Maximum age of the Merkle root in seconds. Range: 3600 (1 hour) to 604800 (7 days).

Response item fields (protocol 4.0)

responses[].identifier
string
required
Credential type (e.g. "orb").
responses[].proof
string[5]
required
Array of exactly 5 hex strings: 4 compressed Groth16 proof elements + Merkle root.
responses[].nullifier
string
required
RP-scoped nullifier (hex string, optional 0x prefix).
responses[].issuer_schema_id
number
required
Credential issuer schema ID.
responses[].expires_at_min
number
required
Minimum credential expiration timestamp (unix seconds).
responses[].signal_hash
string
default:"0x0"
Hash of the signal. Defaults to "0x0".
curl -X POST "https://developer.world.org/api/v4/verify/rp_xxxxx" \
    -H "Content-Type: application/json" \
    -d '{
        "protocol_version": "3.0",
        "nonce": "0x1234...",
        "action": "my-action",
        "responses": [
            {
                "identifier": "orb",
                "proof": "0x1aa8b8f3b2d2de5ff452c0e1a83e29d6bf46fb83ef35dc5957121ff3d3698a11...",
                "merkle_root": "0x2264a66d162d7893e12ea8e3c072c51e785bc085ad655f64c10c1a61e00f0bc2",
                "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8",
                "signal_hash": "0x00c5d2460186f7233c927e7db2dcc703c0e500b653ca82273b7bfad8045d85a4"
            }
        ]
    }'

Possible Responses

  • 200 OK - At least one proof was successfully verified.
  • 400 Bad Request - All proofs failed verification, or the user has already verified for this action.
  • 404 Not Found - App not found or no longer active.

Response Examples

{
  "success": true,
  "action": "my-action",
  "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8",
  "created_at": "2025-02-18T11:20:39.530041+00:00",
  "environment": "staging",
  "results": [
    {
      "identifier": "orb",
      "success": true,
      "nullifier": "0x2bf8406809dcefb1486dadc96c0a897db9bab002053054cf64272db512c6fbd8"
    }
  ],
  "message": "Proof verified successfully"
}

Response Fields

success
boolean
Whether at least one proof was verified successfully.
action
string
The action identifier (returned on success).
nullifier
string
The nullifier from the first successful proof (returned on success). Use this to track unique users per action.
created_at
string
ISO 8601 timestamp of when the nullifier was recorded.
environment
string
"production" or "staging". In staging, nullifier reuse is allowed.
results
array
Per-response verification results. Each entry includes identifier, success, and optionally nullifier (on success) or code/detail (on failure).