Skip to content
Merged
14 changes: 9 additions & 5 deletions docs.json
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,8 @@
{
"group": "Credentials",
"pages": [
"world-id/credentials/legacy-presets",
"world-id/credentials/index",
"world-id/credentials/9303",
"world-id/selfie-check/overview"
]
},
Expand Down Expand Up @@ -124,7 +125,10 @@
},
{
"group": "Issuers",
"pages": ["world-id/reference/poh-issuer"]
"pages": [
"world-id/reference/poh-issuer",
"world-id/reference/nfc-issuer"
]
}
]
},
Expand Down Expand Up @@ -771,19 +775,19 @@
},
{
"source": "/world-id/credentials/presets",
"destination": "/world-id/credentials/legacy-presets"
"destination": "/world-id/credentials#legacy-presets"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would rename the page back

},
{
"source": "/world-id/face-check/overview",
"destination": "/world-id/selfie-check/overview"
},
{
"source": "/world-id/face-check/web-integration",
"destination": "/world-id/credentials/legacy-presets"
"destination": "/world-id/credentials#legacy-presets"
},
{
"source": "/world-id/face-check/testing",
"destination": "/world-id/credentials/legacy-presets"
"destination": "/world-id/credentials#legacy-presets"
},
{
"source": "/mini-apps/reference/errors",
Expand Down
Binary file added images/docs/id/issuers/9303/thumbnail.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
221 changes: 221 additions & 0 deletions snippets/credential-hero.jsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,221 @@
/**
* Hero card for credential issuer documentation pages.
* Mintlify-safe: no hooks, no client-side state.
*
* IMPORTANT: Tailwind classes MUST be string literals in className
* props — Mintlify only prefixes classes it can statically analyze.
* Never use variables for className values.
*
* Props:
* - title: string — credential display name
* - description: string — one-sentence summary
* - image: string — path to thumbnail image
* - bgColor: string — hex color for the banner background
* - issuerName: string — who issues this credential
* - issuerHref: string — link to issuer (optional)
* - issuerVerified: boolean — show verified badge (optional)
* - status: "active" | "beta" | "deprecated"
* - id: number — credential schema ID
* - sybilResistance: boolean — whether uniqueness is enforced
* - sybilResistanceDescription: string — tooltip on the Yes tag
* - validityPeriod: string — e.g. "10 years or document expiry"
* - sourceCodeHref: string — GitHub URL, or "coming-soon"
*/
export const CredentialHero = ({
title,
description,
image,
bgColor = "#1a1a2e",
issuerName,
issuerHref,
issuerVerified,
status,
id,
sybilResistance,
sybilResistanceDescription,
validityPeriod,
sourceCodeHref,
}) => {
return (
<div className="not-prose rounded-3xl bg-zinc-100 dark:bg-zinc-900">
{/* Banner */}
<div
className="relative overflow-hidden rounded-t-3xl px-6 py-8 md:px-8 md:py-10"
style={{ backgroundColor: bgColor }}
>
<div className="flex items-center justify-between gap-6">
<div className="min-w-0">
<h2 className="m-0 text-2xl font-semibold text-white sm:text-3xl">
{title}
</h2>
{description && (
<p className="m-0 mt-2 max-w-[420px] text-[15px] leading-relaxed text-white/75">
{description}
</p>
)}
</div>
{image && (
<img
src={image}
alt={title}
className="hidden h-28 w-auto rounded-xl object-contain shadow-lg shadow-black/30 sm:block"
/>
)}
</div>
</div>

{/* Metadata table */}
<div>
{issuerName && (
<div className="flex items-center gap-3 border-b border-zinc-200 px-6 py-3.5 text-[14px] md:px-8 dark:border-zinc-800">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="building" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
Issued by
</span>
<span className="inline-flex items-center gap-1">
{issuerVerified && (
<Tooltip tip="Verified issuer">
<span className="inline-flex items-center cursor-help" style={{ height: "20px" }}>
<Icon icon="circle-check" iconType="solid" size={14} color="#3b82f6" />
</span>
</Tooltip>
)}
{issuerHref ? (
<a
href={issuerHref}
target="_blank"
rel="noopener noreferrer"
className="font-medium text-zinc-900 underline decoration-zinc-300 underline-offset-2 hover:decoration-zinc-500 dark:text-zinc-100 dark:decoration-zinc-600 dark:hover:decoration-zinc-400"
>
{issuerName}
</a>
) : (
<span className="font-medium text-zinc-900 dark:text-zinc-100">
{issuerName}
</span>
)}
</span>
</div>
)}
{status && (
<div className="flex items-center gap-3 border-b border-zinc-200 px-6 py-3.5 text-[14px] md:px-8 dark:border-zinc-800">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="signal" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
Status
</span>
{status === "active" && (
<span className="inline-flex items-center rounded-md bg-green-50 px-2 py-0.5 text-xs font-semibold text-green-700 ring-1 ring-green-600/20 ring-inset dark:bg-green-500/10 dark:text-green-400 dark:ring-green-500/20">
Active
</span>
)}
{status === "beta" && (
<span className="inline-flex items-center rounded-md bg-blue-50 px-2 py-0.5 text-xs font-semibold text-blue-700 ring-1 ring-blue-600/20 ring-inset dark:bg-blue-500/10 dark:text-blue-400 dark:ring-blue-500/20">
Beta
</span>
)}
{status === "deprecated" && (
<span className="inline-flex items-center rounded-md bg-amber-50 px-2 py-0.5 text-xs font-semibold text-amber-700 ring-1 ring-amber-600/20 ring-inset dark:bg-amber-500/10 dark:text-amber-400 dark:ring-amber-500/20">
Deprecated
</span>
)}
</div>
)}
{id != null && (
<div className="flex items-center gap-3 border-b border-zinc-200 px-6 py-3.5 text-[14px] md:px-8 dark:border-zinc-800">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="hashtag" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
ID
</span>
<span className="font-mono font-medium text-zinc-900 dark:text-zinc-100">
{id}
</span>
</div>
)}
{sybilResistance != null && (
<div className="flex items-center gap-3 border-b border-zinc-200 px-6 py-3.5 text-[14px] md:px-8 dark:border-zinc-800">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="shield-check" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
Sybil resistance
</span>
{sybilResistance ? (
<span className="inline-flex items-center gap-1.5">
<span className="inline-flex items-center rounded-md bg-green-50 px-2 py-0.5 text-xs font-semibold text-green-700 ring-1 ring-green-600/20 ring-inset dark:bg-green-500/10 dark:text-green-400 dark:ring-green-500/20">
Yes
</span>
{sybilResistanceDescription && (
<Tooltip tip={sybilResistanceDescription}>
<span className="cursor-help text-zinc-400 dark:text-zinc-500">
<Icon icon="circle-info" size={14} />
</span>
</Tooltip>
)}
</span>
) : (
<span className="inline-flex items-center rounded-md bg-zinc-100 px-2 py-0.5 text-xs font-semibold text-zinc-500 ring-1 ring-zinc-500/20 ring-inset dark:bg-zinc-800 dark:text-zinc-400 dark:ring-zinc-500/20">
No
</span>
)}
</div>
)}
{validityPeriod && (
<div className="flex items-center gap-3 border-b border-zinc-200 px-6 py-3.5 text-[14px] md:px-8 dark:border-zinc-800">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="clock" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
<span className="inline-flex items-center gap-1">
Validity period
<Tooltip tip="The default duration period of the credential. Generally the maximum recommended sybil resistance window.">
<span className="cursor-help text-zinc-400 dark:text-zinc-500">
<Icon icon="circle-info" size={12} />
</span>
</Tooltip>
</span>
</span>
<span className="font-medium text-zinc-900 dark:text-zinc-100">
{validityPeriod}
</span>
</div>
)}
{sourceCodeHref && (
<div className="flex items-center gap-3 px-6 py-3.5 text-[14px] md:px-8">
<span className="flex h-7 w-7 shrink-0 items-center justify-center rounded-lg bg-zinc-200/70 text-zinc-500 dark:bg-zinc-800 dark:text-zinc-400">
<Icon icon="code" size={16} />
</span>
<span className="w-36 shrink-0 font-medium text-zinc-500 dark:text-zinc-400">
SDK Reference
</span>
{sourceCodeHref === "coming-soon" ? (
<span className="inline-flex items-center gap-1.5 rounded-md bg-blue-50 px-2 py-0.5 text-xs font-semibold text-blue-700 ring-1 ring-blue-600/20 ring-inset dark:bg-blue-500/10 dark:text-blue-400 dark:ring-blue-500/20">
<Icon icon="lock" size={11} />
Coming soon
</span>
) : (
<a
href={sourceCodeHref}
target="_blank"
rel="noopener noreferrer"
className="font-medium text-zinc-900 underline decoration-zinc-300 underline-offset-2 hover:decoration-zinc-500 dark:text-zinc-100 dark:decoration-zinc-600 dark:hover:decoration-zinc-400"
>
{sourceCodeHref.split("/").pop()}
</a>
)}
</div>
)}
</div>

{/* Bottom spacer */}
<div className="h-2" />
</div>
);
};

export default CredentialHero;
100 changes: 100 additions & 0 deletions world-id/credentials/9303.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
---
title: "NFC Credential"
icon: "passport"
iconType: "duotone"
description: "A unique government-issued document, such as a passport or eID."
"og:image": "https://docs.world.org/images/docs/docs-meta.png"
"twitter:image": "https://docs.world.org/images/docs/docs-meta.png"
---

{/* cspell:ignore uniqueness NFC PCP eIDs */}

import { CredentialHero } from "/snippets/credential-hero.jsx";

<CredentialHero
title="NFC Credential"
description="A unique government-issued document, such as a passport or eID."
image="/images/docs/id/issuers/9303/thumbnail.png"
bgColor="#4a1520"
issuerName="Tools for Humanity"
issuerHref="https://www.toolsforhumanity.com"
issuerVerified={true}
status="active"
id={9303}
sybilResistance={true}
sybilResistanceDescription="Each document can only be used with one World ID. Duplicate enrollments for the same document are rejected."
validityPeriod="Document expiry (max 10 years)"
sourceCodeHref="coming-soon"
/>

## Introduction

The NFC Credential represents a unique government-issued document. It supports passports and eIDs. Availability varies by country and continues to expand over time. An NFC Credential is **guaranteed to be issued to a single World ID per unique document**. In addition to ICAO-9303 compliant documents (such as passports or eIDs), the Japanese [My Number Card](https://en.wikipedia.org/wiki/My_Number_Card) (MNC) is also supported. The MNC flow uses different enrollment handling internally, but it issues the same credential.

## Use Cases

Use the NFC Credential when you need proof of a unique government document. This is useful for applications that need document-level Sybil resistance without requiring a proof of a unique human.

## Credential Structure

This credential implements the following attributes beyond the defaults in the [Credential](https://docs.rs/world-id-primitives/latest/world_id_primitives/credential/struct.Credential.html).

<table>
<thead>
<tr>
<th className="whitespace-nowrap">Attribute</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td className="whitespace-nowrap">
<code>genesis_issued_at</code>
</td>
<td>The timestamp of when the unique document was first verified.</td>
</tr>
<tr>
<td className="whitespace-nowrap">
<code>expires_at</code>
</td>
<td>The expiration of the document with a maximum of 10 years.</td>
</tr>
<tr>
<td className="whitespace-nowrap">
<code>associated_data_commitment</code>
</td>
<td>
A commitment to the user's Associated Data (see{" "}
<a href="/world-id/reference/nfc-issuer#associated-data">
NFC Issuer implementation notes
</a>
).
</td>
</tr>
</tbody>
</table>

In addition, the credential implements the following claims:

### Claim 0 - Authentication Claim

Identifies the type of authentication performed when enrolling a document. This helps determine the state of the document at enrollment time. For example, documents that only undergo Passive Authentication have no guarantee that the data isn't cloned from an original document. Please note that not all authentications are supported for all documents, and it usually varies per country. The strongest authentication available is always selected.

| Value | Claim | Description |
| ----- | --------------------- | -------------------------------------------------------------------------------------------------- |
| `1` | None | Passive authentication only (document signature verification). |
| `2` | Chip Authentication | Document passed Chip Authentication (CA) per ICAO 9303. Proves the chip is genuine and not cloned. |
| `3` | Active Authentication | Document passed Active Authentication (AA) per ICAO 9303. Proves the chip holds a private key. |
| `4` | MNC Authentication | Document was verified via the MNC (My Number Card) SD-JWT flow. |

### Claim 1 - SOD Signature

Contains a hash of the document's signature from the issuing authority. For passports and other ICAO-9303 compliant documents, the signature is retrieved from `SignedData.SignerInfos[0].Signature` in the `EF.SOD` (Security Object Document) (see [Section 4.6.2.1 from ICAO-9303 Part 10](https://www.icao.int/sites/default/files/publications/DocSeries/9303_p10_cons_en.pdf)). The raw signature bytes are then hashed with blake3 and converted to a field element with modulo reduction. Please note that this claim is not set for credentials from My Number Cards.

## Credential Renewal

Renewal is not supported for this credential. A document can only be enrolled once. From a user standpoint, they will generally obtain a new document from their issuing authority (e.g. a new passport) and register it as a new credential.

## Technical Reference

For issuer endpoints, migration payloads, and implementation-specific details, see the [NFC Issuer reference](/world-id/reference/nfc-issuer).
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
---
title: "Legacy Presets"
title: "About Credentials"
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wouldn't rename this. This is developer facing we want to keep it explicit we're talking about Presets here an IDKit concept

sidebarTitle: "About"
"og:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png"
"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.


# Legacy Presets

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

## `orbLegacy`
Expand Down
3 changes: 2 additions & 1 deletion world-id/reference/contracts.mdx
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
---
title: "Smart Contracts (Legacy)"
title: "Contracts 3.0"
description: "World ID 3.0 smart contracts overview: supported chains, architecture, World ID Router verifyProof, and sybil resistance."
"og:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png"
"twitter:image": "https://raw.githubusercontent.com/worldcoin/developer-docs/main/images/docs/docs-meta.png"
deprecated: true
---

<Warning>
Expand Down
Loading
Loading