diff --git a/world-id/4-0-migration.mdx b/world-id/4-0-migration.mdx index a404486..a68a4b5 100644 --- a/world-id/4-0-migration.mdx +++ b/world-id/4-0-migration.mdx @@ -47,12 +47,12 @@ Use these dates as the default migration timeline for planning: - **Phase 1 (Migration):** through **June 1, 2026** - Upgrade SDKs/contracts, register your RP, and create v4 actions. - - New World App users will have v3 and v4 credentials + - New World ID users will have v3 and v4 credentials - **Phase 2 (Transition):** **June 1, 2026** to **March 31, 2027** - New users from this date will only be able to create 4.0 proofs. - All users migrated to 4.0 - **Phase 3 (v3 Cut-off):** from **April 1, 2027** onward - - v3 Proofs will no longer be generated by World App + - v3 Proofs will no longer be generated by World ID If your rollout needs more time, extend Phase 2 and move `CD` later. @@ -125,7 +125,7 @@ sequenceDiagram 1. **Update SDKs and Contracts:** RPs upgrade SDKs, contracts, and API calls to enable baseline support for the upgraded protocol. This is backwards compatible. 2. **Register in Developer Portal:** RPs generate their new RP registration and relevant actions for the v4 protocol in the Developer Portal. 3. **For long-running actions:** - - RP decides a transition date (`TD`) to start accepting v4 proofs. They specify a minimum `genesis_issued_at = TD` timestamp in the IDKit request with `allow_legacy_proofs: true` as a temporary compatibility mode. This means only users who get their Orb credential (or document credentials) from this point forward can generate v4 proofs. Users who have not upgraded their World App can still issue v3 proofs during this window. RPs should keep track of both nullifiers. + - RP decides a transition date (`TD`) to start accepting v4 proofs. They specify a minimum `genesis_issued_at = TD` timestamp in the IDKit request with `allow_legacy_proofs: true` as a temporary compatibility mode. This means only users who get their Orb credential (or document credentials) from this point forward can generate v4 proofs. Users who have not upgraded their World ID can still issue v3 proofs during this window. RPs should keep track of both nullifiers. - At a future cut-off date (`CD > TD`), the RP should switch their IDKit request to `allow_legacy_proofs: false` to stop accepting v3 proofs and only accept v4 proofs. 4. **For limited-time actions** (for example, recurring grant drops): The transition can be made at the action level. Short-running actions have a simpler migration path. diff --git a/world-id/SKILL.md b/world-id/SKILL.md index f8a83cf..9f6b801 100644 --- a/world-id/SKILL.md +++ b/world-id/SKILL.md @@ -1,7 +1,7 @@ --- name: world-id-integration description: | - Use this skill when adding, upgrading, debugging, or testing World ID verification with IDKit in a new or existing web or mobile app. Covers Proof of Human, passport/document, Face Check, and session/sign-in flows; Developer Portal app, RP, and action setup; server-side signing and proof verification; environment matching; nullifier replay protection; and launch testing. Trigger when the user asks to add World ID, verify humans, stop bots or multi-accounting, add Sybil resistance, or mentions IDKit, Orb, World App proof flows, @worldcoin/idkit, signing keys, rp_id, or app_id. + Use this skill when adding, upgrading, debugging, or testing World ID verification with IDKit in a new or existing web or mobile app. Covers Proof of Human, passport/document, Face Check, and session/sign-in flows; Developer Portal app, RP, and action setup; server-side signing and proof verification; environment matching; nullifier replay protection; and launch testing. Trigger when the user asks to add World ID, verify humans, stop bots or multi-accounting, add Sybil resistance, or mentions IDKit, Orb, World ID proof flows, World App proof flows, @worldcoin/idkit, signing keys, rp_id, or app_id. version: 0.1.0 metadata: author: worldcoin @@ -35,7 +35,7 @@ Before changing code or creating Portal resources: - integration goal and credential preset - new or existing project; client, backend, package manager, and persistence layer - Developer Portal account/team, `app_id`, `rp_id`, and action - - target environment and test path: staging simulator, production World App, or both + - target environment and test path: staging simulator, production World ID, or both - Developer Portal MCP connection - whether an RP signing key already exists in a server-side secret store - credential access, especially Face Check @@ -144,17 +144,17 @@ The full code for each step is at [https://docs.world.org/world-id/idkit/integra 1. **Install IDKit** — `^4.x`, the right package for the platform (table in Phase 2). 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. 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.** -4. **Open the IDKit widget on the client** with the signature your backend returned. The widget hands off to the World App, which produces a zero-knowledge proof. +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. 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. 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. ## Phase 5 — Match environments end-to-end -- The **production** World App only signs **production** proofs. -- A **staging** action only verifies against the World App **simulator** ([https://simulator.worldcoin.org](https://simulator.worldcoin.org)). +- The **production** World ID app only signs **production** proofs. +- A **staging** action only verifies against the World ID **Simulator** ([https://simulator.worldcoin.org](https://simulator.worldcoin.org)). - The IDKit `environment` prop, the action's `environment`, and the simulator-vs-real-app choice **must all match.** -**CRITICAL: if real users will scan with their phones, the action environment must be `production`.** A staging action with the production World App will silently produce zero proofs and look like a frontend bug. If the user needs both simulator testing and real-device QA, create separate staging and production actions. +**CRITICAL: if real users will scan with their phones, the action environment must be `production`.** A staging action with the production World ID app will silently produce zero proofs and look like a frontend bug. If the user needs both simulator testing and real-device QA, create separate staging and production actions. ## Phase 6 — Test the integration end-to-end @@ -162,7 +162,7 @@ Do not declare the integration complete from compilation or Portal configuration - [ ] RP-signing endpoint succeeds without exposing or logging secrets. - [ ] Widget/request opens in the selected environment. -- [ ] The selected credential completes with the staging simulator or production World App as intended. +- [ ] The selected credential completes with the staging simulator or production World ID as intended. - [ ] Backend verification succeeds and the exact IDKit result reaches `/api/v4/verify/{rp_id}`. - [ ] The verified nullifier is persisted. - [ ] Replaying the same nullifier is rejected by the database uniqueness constraint. @@ -180,7 +180,7 @@ Surface these proactively when you see the corresponding symptom — don't make | Symptom | Cause | Recovery | |---|---|---| | 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. | -| World App 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. | +| 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. | | `/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. | | 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. | | `/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. | @@ -220,7 +220,7 @@ For launch readiness, also confirm: - Error codes: [https://docs.world.org/world-id/idkit/error-codes](https://docs.world.org/world-id/idkit/error-codes) - Developer Portal MCP: [https://github.com/worldcoin/developer-portal/tree/main/web/api/mcp](https://github.com/worldcoin/developer-portal/tree/main/web/api/mcp) - Developer Portal: [https://developer.world.org](https://developer.world.org) -- World App simulator (staging only): [https://simulator.worldcoin.org](https://simulator.worldcoin.org) +- World ID Simulator (staging only): [https://simulator.worldcoin.org](https://simulator.worldcoin.org) --- diff --git a/world-id/credentials/11.mdx b/world-id/credentials/11.mdx index cf0faab..44f0a86 100644 --- a/world-id/credentials/11.mdx +++ b/world-id/credentials/11.mdx @@ -41,13 +41,13 @@ Selfie Check (Beta) is useful for: You will need to use IDKit to integrate Selfie Check (Beta) into your application. -* **On Mobile (iOS/Android):** You will use IDKit to generate a Deep Link and attach it to a "Verify" CTA in your app. When the user clicks on this CTA, they are automatically redirected to the World App to complete the Selfie Check (Beta) flow. -* **On Desktop:** You will use IDKit to generate a **QR Code** and display it to the user to complete verification. When the user scans the QR Code with their mobile device camera, World App will launch and guide them through completing the Selfie Check (Beta) flow. +* **On Mobile (iOS/Android):** You will use IDKit to generate a Deep Link and attach it to a "Verify" CTA in your app. When the user clicks on this CTA, they are automatically redirected to World ID to complete the Selfie Check (Beta) flow. +* **On Desktop:** You will use IDKit to generate a **QR Code** and display it to the user to complete verification. When the user scans the QR Code with their mobile device camera, World ID will launch and guide them through completing the Selfie Check (Beta) flow. ## User Experience Flow 1. **Challenge:** The user initiates the flow on your app (Relying Party). -2. **Hand-off:** User is redirected to the World App. If the user doesn’t have the World App installed, they will be dropped into a seamless flow to download the World App and directly go into the Selfie Check (Beta) experience. +2. **Hand-off:** User is redirected to World ID. If the user doesn’t have World ID installed, they will be dropped into a seamless flow to download World ID and directly go into the Selfie Check (Beta) experience. 3. **Enrollment/Auth:** * **New User:** Prompts to "Take a selfie". The system performs a liveness check and a uniqueness check against other faces. * **Returning User:** Performs a quick Face Auth to verify continuity. diff --git a/world-id/from-idkit-standalone.mdx b/world-id/from-idkit-standalone.mdx index db01a46..b7faa4f 100644 --- a/world-id/from-idkit-standalone.mdx +++ b/world-id/from-idkit-standalone.mdx @@ -56,7 +56,7 @@ await IDKit.open(); ``` With `idkit-core`, fetch an RP signature from your backend, build the request, -render the `connectorURI`, and poll until World App returns a proof. +render the `connectorURI`, and poll until World ID returns a proof. ```ts title="After" import { IDKit, orbLegacy } from "@worldcoin/idkit-core"; diff --git a/world-id/idkit/credentials.mdx b/world-id/idkit/credentials.mdx index b18ea07..bca3249 100644 --- a/world-id/idkit/credentials.mdx +++ b/world-id/idkit/credentials.mdx @@ -207,9 +207,9 @@ Successful Identity Check responses include `identity_attested` so your backend ## User presence and liveness -To check for user presence and liveness, add the `require_user_presence` flag to your request. This is a request-level flag, not a credential; it asks World App for a fresh liveness check before returning the proof and fails with `user_presence_failed` if the check is not completed. +To check for user presence and liveness, add the `require_user_presence` flag to your request. This is a request-level flag, not a credential; it asks World ID for a fresh liveness check before returning the proof and fails with `user_presence_failed` if the check is not completed. -Depending on the credential requested, World App matches the user's live selfie to the credential image, such as the passport photo or the image captured during Orb verification. +Depending on the credential requested, World ID matches the user's live selfie to the credential image, such as the passport photo or the image captured during Orb verification. ```typescript title="JavaScript" diff --git a/world-id/idkit/design-guidelines.mdx b/world-id/idkit/design-guidelines.mdx index 84916c8..b6f34a8 100644 --- a/world-id/idkit/design-guidelines.mdx +++ b/world-id/idkit/design-guidelines.mdx @@ -176,11 +176,11 @@ title: "Design Guidelines" className="w-full h-auto max-w-[600px]" /> -**Request canceled** - User manually canceled request in World App +**Request canceled** - User manually canceled request in World ID Request canceled - User manually canceled request in World App user_rejected - User cancelled in World App. + User cancelled in World ID. Treat as user cancellation, allow retry. diff --git a/world-id/idkit/integrate.mdx b/world-id/idkit/integrate.mdx index dfddebf..c0684da 100644 --- a/world-id/idkit/integrate.mdx +++ b/world-id/idkit/integrate.mdx @@ -8,7 +8,7 @@ description: "Integrate World ID into your app" import IDKitResponse from "/snippets/idkit-response.mdx"; -IDKit is the SDK for integrating World ID into your app. It handles proof requests, verification flows, and communication with the World App — so your backend receives a cryptographic proof of human, not personal data. +IDKit is the SDK for integrating World ID into your app. It handles proof requests, verification flows, and communication with the World ID app — so your backend receives a cryptographic proof of human, not personal data. It's available as a React widget for drop-in integration, or as JS, Swift, and Kotlin SDKs for custom flows. To familiarize yourself with the core concepts of World ID, check out this [page](/world-id/concepts). @@ -16,11 +16,11 @@ It's available as a React widget for drop-in integration, or as JS, Swift, and K ## How it works -Your app sends a **proof request** through IDKit, challenging the user to prove something about themselves — such as uniqueness, document possession, or liveness — based on their [credentials](/world-id/overview#credentials). The user's World App generates a zero-knowledge proof without revealing any personal data. Your backend then verifies that proof and stores a **nullifier** (a per-app, per-action identifier) to prevent the same person from verifying twice. +Your app sends a **proof request** through IDKit, challenging the user to prove something about themselves — such as uniqueness, document possession, or liveness — based on their [credentials](/world-id/overview#credentials). The user's World ID app generates a zero-knowledge proof without revealing any personal data. Your backend then verifies that proof and stores a **nullifier** (a per-app, per-action identifier) to prevent the same person from verifying twice. IDKit integration flow -There are four components: your **client** (where IDKit runs), your **backend** (which signs requests and verifies proofs), the **World App** (on the user's device), and the **Developer Portal** (which validates proofs on-chain). The steps below walk through each piece. +There are four components: your **client** (where IDKit runs), your **backend** (which signs requests and verifies proofs), the **World ID app** (on the user's device), and the **Developer Portal** (which validates proofs on-chain). The steps below walk through each piece. # Step 1: Install IDKit @@ -128,7 +128,7 @@ func handleRPSignature(w http.ResponseWriter, r *http.Request) { The steps below cover the standard request flow. Depending on whether the user - already has World App and the credential you're requesting, they may be taken + already has World ID and the credential you're requesting, they may be taken through a different experience. See [Verification flows](/world-id/idkit/verification-flows) for details. @@ -373,7 +373,7 @@ sequenceDiagram Client->>Client: 2. Create IDKit request with RP signature Client->>User: 3. Show connect URL / QR code - User->>User: 4. Prove uniqueness in World App + User->>User: 4. Prove uniqueness in World ID User-->>Client: 5. Proof returned via IDKit diff --git a/world-id/idkit/signatures.mdx b/world-id/idkit/signatures.mdx index ed0a11c..d7b6131 100644 --- a/world-id/idkit/signatures.mdx +++ b/world-id/idkit/signatures.mdx @@ -7,7 +7,7 @@ description: "Spec for generating RP signatures, with pseudocode, SDK examples, Relying Party (RP) signatures prove that a proof request genuinely comes from your app, preventing impersonation attacks. Your backend signs every request with the `signing_key` from the [Developer Portal](https://developer.world.org), -and World App verifies the signature before generating a proof. RP signatures are enforced for [World ID 4.0 requests](/world-id/4-0-migration). +and World ID verifies the signature before generating a proof. RP signatures are enforced for [World ID 4.0 requests](/world-id/4-0-migration). Never expose your signing key to client-side code. If the key leaks, rotate it immediately in the Developer Portal. diff --git a/world-id/idkit/verification-flows.mdx b/world-id/idkit/verification-flows.mdx index 60d2938..0441083 100644 --- a/world-id/idkit/verification-flows.mdx +++ b/world-id/idkit/verification-flows.mdx @@ -5,17 +5,17 @@ description: "The flows your integration can land users in when you request a Wo "twitter:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png" --- -When your app requests a World ID proof, the user lands in one of three flows based on two factors: whether they have World App installed, and — if not — whether they already have a World App account. +When your app requests a World ID proof, the user lands in one of three flows based on two factors: whether they have World ID installed, and — if not — whether they already have a World ID. The integration flow is the same for all three paths, but the user experience differs. -| Flow | World App installed | Existing account | What happens | +| Flow | World ID installed | Existing account | What happens | | --- | --- | --- | --- | -| Hot | Yes | — | World App opens, displays a proof consent, and the user approves. Typically under 10 seconds. If the user does not yet hold the requested [credential](/world-id/idkit/credentials), World App walks them through enrollment first — your integration sees no difference. | -| Cold | No | No | The user installs World App and completes account onboarding first. The experience differs by platform — see below. | -| Semi-cold | No | Yes | The user installs World App and logs in to their existing account. **Android:** the flow resumes automatically. **iOS:** the user must return to your app and rescan, unless you use invite-code mode — see below. | +| Hot | Yes | — | World ID opens, displays a proof consent, and the user approves. Typically under 10 seconds. If the user does not yet hold the requested [credential](/world-id/idkit/credentials), World ID walks them through enrollment first — your integration sees no difference. | +| Cold | No | No | The user installs World ID and completes account onboarding first. The experience differs by platform — see below. | +| Semi-cold | No | Yes | The user installs World ID and logs in to their existing account. **Android:** the flow resumes automatically. **iOS:** the user must return to your app and rescan, unless you use invite-code mode — see below. | ## Cold and semi-cold flows @@ -23,17 +23,17 @@ Both flows require an install and work differently on each platform because of h ### Android -Android supports deferred deep linking through the Play Store. After the user downloads World App, they either create an account (cold) or log in to an existing one (semi-cold), then World App resumes the verification flow automatically. +Android supports deferred deep linking through the Play Store. After the user downloads World ID, they either create an account (cold) or log in to an existing one (semi-cold), then World ID resumes the verification flow automatically. ```mermaid sequenceDiagram participant App as Your App participant User participant Play as Play Store - participant WA as World App + participant WA as World ID App->>User: IDKit request (connect URL / QR) - User->>Play: Download World App + User->>Play: Download World ID Play-->>WA: Deferred deep link preserved WA->>User: Account onboarding OR Login @@ -51,9 +51,9 @@ iOS does not support deferred deep linking through the App Store. The original v #### Default behavior -1. The user downloads World App from the App Store and creates an account or logs in to an existing one. +1. The user downloads World ID from the App Store and creates an account or logs in to an existing one. 2. The user returns to your app, which re-triggers the IDKit verification request (e.g., the user rescans the QR code). -3. World App opens and takes the user through the standard in-app flow. +3. World ID opens and takes the user through the standard in-app flow. 4. The proof consent appears, the user approves, and the proof is returned to your app. ```mermaid @@ -61,10 +61,10 @@ sequenceDiagram participant App as Your App participant User participant Store as App Store - participant WA as World App + participant WA as World ID - App->>User: Prompt to install World App - User->>Store: Download World App + App->>User: Prompt to install World ID + User->>Store: Download World ID WA->>User: Account onboarding OR Login User->>App: Return to your app App->>User: IDKit request (rescan QR / connect URL) @@ -74,7 +74,7 @@ sequenceDiagram #### With invite-code mode -Invite-code mode displays a short 6-character code in your app that the user enters into World App. World App treats the code as an entry point to the in-app onboarding flows the user needs to complete in order to satisfy your IDKit request, then returns the proof. +Invite-code mode displays a short 6-character code in your app that the user enters into World ID. World ID treats the code as an entry point to the in-app onboarding flows the user needs to complete in order to satisfy your IDKit request, then returns the proof. Invite-code mode exists because iOS lacks deferred deep linking — Android preserves the context via the Play Store. @@ -82,13 +82,13 @@ Invite-code mode displays a short 6-character code in your app that the user ent 1. Your app triggers an IDKit invite-code request. 2. Your app opens the URL that IDKit provides. One of three paths follows: - - **User has World App (mobile):** World App launches directly via deep link. - - **User has World App (desktop):** The user scans the QR code with World App. - - **User needs to install World App:** The user installs World App, completes account onboarding or logs in, then enters the invite code to resume the request. -3. World App restores the verification context, walks the user through credential enrollment if needed, and presents a proof consent. + - **User has World ID (mobile):** World ID launches directly via deep link. + - **User has World ID (desktop):** The user scans the QR code with World ID. + - **User needs to install World ID:** The user installs World ID, completes account onboarding or logs in, then enters the invite code to resume the request. +3. World ID restores the verification context, walks the user through credential enrollment if needed, and presents a proof consent. 4. The user approves and the proof is returned to your app. -The 6-character code persists across the App Store install, so once World App is installed and onboarded the user can resume the verification flow without returning to your app first. This also covers cross-device scenarios (e.g., a desktop browser displaying the QR for the user's phone) where deep linking cannot carry context. +The 6-character code persists across the App Store install, so once World ID is installed and onboarded the user can resume the verification flow without returning to your app first. This also covers cross-device scenarios (e.g., a desktop browser displaying the QR for the user's phone) where deep linking cannot carry context. **Demo** @@ -106,11 +106,11 @@ sequenceDiagram participant User participant LP as Landing Page participant Store as App Store - participant WA as World App + participant WA as World ID App->>LP: Open IDKit-provided URL LP->>User: Display invite code + QR - User->>Store: Download World App + User->>Store: Download World ID WA->>User: Account onboarding OR Login User->>WA: Enter invite code WA->>WA: Resolve code & restore context