Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
272 changes: 111 additions & 161 deletions world-id/idkit/credentials.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,249 +4,199 @@ title: "Configure Credentials"
"twitter:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png"
---

A [Credential](https://docs.rs/world-id-primitives/latest/world_id_primitives/credential/struct.Credential.html) is a statement an issuer makes about a World ID holder. Fundamentally, when you as an RP request a proof, the choice of Credential matters significantly to fulfill your use case. For example, if you want to protect an action that should only be done once per human, you probably want to use the Proof of Human credential.
{/* cspell:ignore NFC liveness */}

# World ID 4.0 Presets
A [Credential](https://docs.rs/world-id-primitives/latest/world_id_primitives/credential/struct.Credential.html) is a statement an issuer makes about a World ID holder. In IDKit, the credential you request determines what the user proves to your application.

These presets create World ID 4.0 proof requests and automatically fall back to the matching legacy proof when a World ID 4.0 proof is not available. If you have an existing integration using legacy presets, please take a look at the [migration guide](/world-id/4-0-migration).
# What you can request with IDKit

## `proofOfHuman`
| Offering | What it proves | Common SDK path |
| --- | --- | --- |
| Proof of Human | The user is a unique human, backed by anonymous biometric verification by the Orb. | `proofOfHuman` |
| Passport | The user holds a verified NFC passport credential. | `passport` |
| Selfie Check | A low-assurance biometric credential using the device camera for liveness and facial similarity. | `selfieCheckLegacy` today. World ID 4.0 support is rolling out soon. |

Requires Proof of Human. Falls back to an Orb legacy proof.
You can also add a liveness check to any preset with `require_user_presence`.

<CodeGroup title="proofOfHuman">
<Note>
If you have an existing legacy integration, see the [World ID 4.0 migration guide](/world-id/4-0-migration).
</Note>

# SDK presets

This page focuses on preset helpers for common credential requests: `proofOfHuman`, `passport`, `selfieCheckLegacy`, and the legacy presets.

The snippets below use `rp_context` as if it was already generated and signed by your backend. See [Integrate IDKit](/world-id/idkit/integrate) for the full RP-signing flow.

## Proof of Human

Use `proofOfHuman` for the current World ID 4.0 Proof of Human credential. The preset also includes legacy Orb fallback for users who do not yet have a World ID 4.0 proof available.

<CodeGroup title="Proof of Human">
```typescript title="JavaScript"
import { IDKit, proofOfHuman } from "@worldcoin/idkit-core";

const preset = proofOfHuman({ signal: "user-123" });

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(proofOfHuman({ signal: "user-123" }));
rp_context,
allow_legacy_proofs: true,
}).preset(preset);
```

```tsx title="React"
import { IDKitRequestWidget, proofOfHuman } from "@worldcoin/idkit";

const preset = proofOfHuman({ signal: "user-123" });

<IDKitRequestWidget
open={open}
onOpenChange={setOpen}
app_id="app_xxxxx"
action="my-action"
rp_context={rp_context}
preset={proofOfHuman({ signal: "user-123" })}
rp_context={rpContext}
allow_legacy_proofs={true}
preset={preset}
handleVerify={handleVerify}
onSuccess={(result) => { /* ... */ }}
/>;
```
</CodeGroup>

## `passport`
## Passport

Requires a Passport credential. Falls back to a Document legacy proof.
Use `passport` for the current World ID 4.0 Passport credential. The preset also includes legacy Document fallback for users who do not yet have a World ID 4.0 proof available.

<CodeGroup title="passport">
<CodeGroup title="Passport">
```typescript title="JavaScript"
import { IDKit, passport } from "@worldcoin/idkit-core";

const preset = passport({ signal: "user-123" });

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(passport({ signal: "user-123" }));
rp_context,
allow_legacy_proofs: true,
}).preset(preset);
```

```tsx title="React"
import { IDKitRequestWidget, passport } from "@worldcoin/idkit";

const preset = passport({ signal: "user-123" });

<IDKitRequestWidget
open={open}
onOpenChange={setOpen}
app_id="app_xxxxx"
action="my-action"
rp_context={rp_context}
preset={passport({ signal: "user-123" })}
rp_context={rpContext}
allow_legacy_proofs={true}
preset={preset}
handleVerify={handleVerify}
onSuccess={(result) => { /* ... */ }}
/>;
```
</CodeGroup>

## Parameters

Both World ID 4.0 presets accept an optional `signal` parameter:
## Selfie Check

| Parameter | Type | Description |
|-----------|------|-------------|
| `signal` | `string?` | Binds specific context into the proof (e.g. user ID, wallet address). Your backend should enforce the same value. |
Selfie Check is available through the legacy preset today and returns a World ID 3.0 Face proof. World ID 4.0 support is rolling out soon.

# Legacy Presets
Learn more in [Selfie Check](/world-id/credentials/11).

Legacy presets only return World ID 3.0 proofs. These function the same as `VerificationLevel` from previous IDKit versions.

## `orbLegacy`

Requires Orb verification.

<CodeGroup title="orbLegacy">
<CodeGroup title="Selfie Check">
```typescript title="JavaScript"
import { IDKit, orbLegacy } from "@worldcoin/idkit-core";

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(orbLegacy({ signal: "user-123" }));
```

```swift title="Swift"
import IDKit

let request = try IDKit.request(config: config)
.preset(orbLegacy(signal: "user-123"))
```

```kotlin title="Kotlin"
import com.worldcoin.idkit.orbLegacy

val request = IDKit.request(config)
.preset(orbLegacy(signal = "user-123"))
```
</CodeGroup>

## `secureDocumentLegacy`

Requires at least a Secure Document verification. Returns the user's highest credential (Secure Document or Orb).

<CodeGroup title="secureDocumentLegacy">
```typescript title="JavaScript"
import { IDKit, secureDocumentLegacy } from "@worldcoin/idkit-core";

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(secureDocumentLegacy({ signal: "user-123" }));
```

```swift title="Swift"
import IDKit

let request = try IDKit.request(config: config)
.preset(secureDocumentLegacy(signal: "user-123"))
```

```kotlin title="Kotlin"
import com.worldcoin.idkit.secureDocumentLegacy

val request = IDKit.request(config)
.preset(secureDocumentLegacy(signal = "user-123"))
```
</CodeGroup>

## `documentLegacy`

Requires at least a Document verification. Returns the user's highest credential (Document, Secure Document, or Orb).
import { IDKit, selfieCheckLegacy } from "@worldcoin/idkit-core";

<CodeGroup title="documentLegacy">
```typescript title="JavaScript"
import { IDKit, documentLegacy } from "@worldcoin/idkit-core";
const preset = selfieCheckLegacy({ signal: "user-123" });

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(documentLegacy({ signal: "user-123" }));
rp_context,
allow_legacy_proofs: true,
}).preset(preset);
```

```swift title="Swift"
import IDKit

let request = try IDKit.request(config: config)
.preset(documentLegacy(signal: "user-123"))
```
```tsx title="React"
import { IDKitRequestWidget, selfieCheckLegacy } from "@worldcoin/idkit";

```kotlin title="Kotlin"
import com.worldcoin.idkit.documentLegacy
const preset = selfieCheckLegacy({ signal: "user-123" });

val request = IDKit.request(config)
.preset(documentLegacy(signal = "user-123"))
<IDKitRequestWidget
open={open}
onOpenChange={setOpen}
app_id="app_xxxxx"
action="my-action"
rp_context={rpContext}
allow_legacy_proofs={true}
preset={preset}
handleVerify={handleVerify}
onSuccess={(result) => { /* ... */ }}
/>;
```
</CodeGroup>

## User presence and liveness

## `deviceLegacy`
`require_user_presence` asks World App to perform an additional liveness step before completing the proof. This flag works with presets.

Requires at least a Device verification. Returns the user's highest credential (Device,Document, Secure Document, or Orb).

<CodeGroup title="deviceLegacy">
<CodeGroup title="User presence">
```typescript title="JavaScript"
import { IDKit, deviceLegacy } from "@worldcoin/idkit-core";

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(deviceLegacy({ signal: "user-123" }));
```

```swift title="Swift"
import IDKit

let request = try IDKit.request(config: config)
.preset(deviceLegacy(signal: "user-123"))
```

```kotlin title="Kotlin"
import com.worldcoin.idkit.documentLegacy

val request = IDKit.request(config)
.preset(deviceLegacy(signal = "user-123"))
```
</CodeGroup>

## `selfieCheckLegacy` (Selfie Check Beta)

Requires Selfie Check verification. Returns a World ID 3.0 Face proof.

Learn more about Selfie Check here: [Selfie Check Overview](/world-id/selfie-check/overview).
import { IDKit, proofOfHuman } from "@worldcoin/idkit-core";

<CodeGroup title="selfieCheckLegacy">
```typescript title="JavaScript"
import { IDKit, selfieCheckLegacy } from "@worldcoin/idkit-core";
const preset = proofOfHuman({ signal: "user-123" });

const request = await IDKit.request({
app_id: "app_xxxxx",
action: "my-action",
rp_context: { /* ... */ },
}).preset(selfieCheckLegacy({ signal: "user-123" }));
rp_context,
allow_legacy_proofs: true,
require_user_presence: true,
}).preset(preset);
```

```tsx title="React"
import { IDKitRequestWidget, selfieCheckLegacy } from "@worldcoin/idkit";
import { IDKitRequestWidget, proofOfHuman } from "@worldcoin/idkit";

const preset = proofOfHuman({ signal: "user-123" });

<IDKitRequestWidget
open={open}
onOpenChange={setOpen}
app_id="app_xxxxx"
action="my-action"
rp_context={rp_context}
preset={selfieCheckLegacy({ signal: "user-123" })}
rp_context={rpContext}
allow_legacy_proofs={true}
require_user_presence={true}
preset={preset}
handleVerify={handleVerify}
onSuccess={(result) => { /* ... */ }}
/>;
```
</CodeGroup>

```swift title="Swift"
import IDKit

let request = try IDKit.request(config: config)
.preset(selfieCheckLegacy(signal: "user-123"))
```
If the user does not complete the liveness step, the request fails with `user_presence_failed`.

```kotlin title="Kotlin"
import com.worldcoin.idkit.selfieCheckLegacy
## Other legacy presets

val request = IDKit.request(config)
.preset(selfieCheckLegacy(signal = "user-123"))
```
</CodeGroup>
These presets only return World ID 3.0 proofs. Keep them for existing integrations or when you specifically need the older verification level.

## Parameters
| Preset | What it requests |
| --- | --- |
| `orbLegacy` | Orb verification. |
| `secureDocumentLegacy` | At least a Secure Document verification. Returns the user's highest legacy credential: Secure Document or Orb. |
| `documentLegacy` | At least a Document verification. Returns the user's highest legacy credential: Document, Secure Document, or Orb. |
| `deviceLegacy` | At least a Device verification. Returns the user's highest legacy credential: Device, Document, Secure Document, or Orb. |

All legacy presets accept an optional `signal` parameter:
## Common parameters

| Parameter | Type | Description |
|-----------|------|-------------|
| `signal` | `string?` | Binds specific context into the proof (e.g. user ID, wallet address). Your backend should enforce the same value. |
| Parameter | Where it is used | Description |
| --- | --- | --- |
| `signal` | Presets | Binds application context into the proof, such as a user ID or wallet address. Your backend should enforce the same value. |
| `allow_legacy_proofs` | Request config and widgets | Required for request flows. Set to `true` while accepting World ID 3.0 fallback proofs; set to `false` for World ID 4.0-only requests. |
| `require_user_presence` | Request config and widgets | Optional liveness step. Defaults to `false`. |
5 changes: 5 additions & 0 deletions world-id/idkit/error-codes.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,11 @@ This page focuses on IDKit SDK and bridge error codes returned during request fl
<td className="p-2 align-middle">RP signature has expired.</td>
<td className="p-2 align-middle">Request a fresh RP signature before starting verification.</td>
</tr>
<tr>
<td className="p-2 align-middle"><code>user_presence_failed</code></td>
<td className="p-2 align-middle">Required user-presence check was not completed.</td>
<td className="p-2 align-middle">Let the user retry the request.</td>
</tr>
<tr>
<td className="p-2 align-middle"><code>identity_attributes_not_matched</code></td>
<td className="p-2 align-middle">User identity attributes did not match the requested constraints.</td>
Expand Down
Loading