You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: world-id/SKILL.md
+2-1Lines changed: 2 additions & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -145,7 +145,7 @@ The full code for each step is at [https://docs.world.org/world-id/idkit/integra
145
145
2.**Create or reuse the Portal resources.** Use the MCP when available. Reuse an existing app, RP, and action when they match the requested integration. For a new RP, capture `app_id`, `rp_id`, and `signing_key.private_key` from `configure_world_id`, create the action in the intended environment, and write the signing key to the prepared server-only secret store in the same step. The portal returns it exactly once. **Do not print, log, or return the private key to chat.** If the key is lost, explain that `get_world_id_signing_key` cannot recover it; rotation creates a new key and invalidates the old signer.
146
146
3.**Generate the RP signature in your backend.***Why backend?* The signing key authenticates your app to the protocol. Leaking it lets anyone impersonate your app and forge proof requests. **CRITICAL: never sign on the client. Never expose `RP_SIGNING_KEY` as a `NEXT_PUBLIC_*` var. Never log it.**
147
147
4.**Open the IDKit widget on the client** with the signature your backend returned. The widget hands off to World ID, which produces a zero-knowledge proof.
148
-
5.**Verify the proof in your backend** by POSTing it **as-is** to `https://developer.world.org/api/v4/verify/{rp_id}`.*Why backend?* A client can return any JSON it wants. Only the World verifier — called from a trusted server — confirms the proof is real and tied to a unique credential. Verifying client-side defeats the entire point. **DO NOT mutate, re-encode, or trim the proof JSON before forwarding** — pass exactly what IDKit returned.
148
+
5.**Verify the proof in your backend** by POSTing it **as-is** to `https://developer.world.org/api/v4/verify/{rp_id}` with a descriptive `User-Agent` header (for example, `my-world-id-backend/1.0`).*Why backend?* A client can return any JSON it wants. Only the World verifier — called from a trusted server — confirms the proof is real and tied to a unique credential. Verifying client-side defeats the entire point. **DO NOT mutate, re-encode, or trim the proof JSON before forwarding** — pass exactly what IDKit returned. Requests without a `User-Agent` may be rejected by bot protection.
149
149
6.**Store the nullifier.** Every successful proof returns a `nullifier` — an RP-scoped, action-scoped, non-reversible identifier for that user. *Why store it?* Without uniqueness storage, a user can verify the same proof twice and double-claim a reward, vote, etc. Persist `(action, nullifier)` with a `UNIQUE` constraint and reject duplicates on insert. Column type: **`NUMERIC(78, 0)`** (256-bit field elements). The nullifier reveals nothing about the user — it's safe to store, but it's the *only* anti-replay mechanism, so it's required.
150
150
151
151
## Phase 5 — Match environments end-to-end
@@ -181,6 +181,7 @@ Surface these proactively when you see the corresponding symptom — don't make
181
181
|---|---|---|
182
182
| Face Check appears unresponsive or never starts | The app may not be enabled for Face Check | Read `enable_face_check` through MCP when available or `/api/v1/precheck/{app_id}`. If false, stop and explain how to request access. |
183
183
| World ID shows "action not found" or QR scan does nothing | Action wasn't created in the environment IDKit is pointing at | Create the missing action with `create_world_id_action` (`environment: "production"` for real devices, `"staging"` for simulator). Confirm `NEXT_PUBLIC_WLD_ENVIRONMENT` matches. |
184
+
|`/api/v4/verify/{rp_id}` returns a bot-protection `403`| The backend request has no `User-Agent` header | Add a descriptive `User-Agent`, such as `my-world-id-backend/1.0`, and retry. |
184
185
|`/api/v4/verify/{rp_id}` returns `invalid_proof` or `verification_failed`| Often staging/production env mismatch, or proof was mutated before forward | Re-check Phase 5. Forward the proof JSON byte-for-byte without re-encoding fields. |
185
186
| Verification fails in JS/React and the error code alone isn't enough | Need transport/payload diagnostics | Read `getDebugReport()` (or the `onError``debugReport` arg) — it carries `transport`, `request_id`, request/response payloads, and World App `mini_app` channel info. JS SDKs only. |
186
187
|`/api/v4/verify/{rp_id}` returns `not_registered` or 4xx with `rp` errors | On-chain registration is still `pending`| Poll `get_world_id_registration_status` until the intended environment is `registered`. Production must be registered before launch. |
Copy file name to clipboardExpand all lines: world-id/idkit/integration-prompt.mdx
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -33,7 +33,7 @@ Integrate World ID into my project using IDKit. Here are my app details:
33
33
34
34
4. On success, send the IDKit result to my backend.
35
35
The backend should forward the payload as-is to: POST https://developer.world.org/api/v4/verify/{rp_id}
36
-
No field remapping is needed.
36
+
No field remapping is needed. Include a descriptive User-Agent header (for example, my-world-id-backend/1.0); requests without one may be rejected by bot protection.
0 commit comments