isHuman Network
Proof-of-humanity credentials with local verification and site-private identity boundaries.
What is isHuman?
isHuman is Lemma's proof-of-humanity network for websites and applications. A user verifies once through Stripe Identity, then receives an Ed25519-signed credential that can be reused across sites while preserving privacy via per-site PPIDs.
Master credential is issued for lemma.id. On third-party sites, the wallet bridge derives a site-specific credential on first request and stores it for later use.
Verification Flow
| Step | Component | What happens |
|---|---|---|
| 1 | User + Stripe Identity | User completes identity verification flow initiated from /api/ishuman/start-verification. |
| 2 | Stripe webhook | /api/webhooks/stripe-identity receives identity.verification_session.verified and records verification state. |
| 3 | Credential issuance | Lemma issues a signed isHuman credential (isHuman: true) with issuer metadata and TTL. |
| 4 | Wallet bridge | Client requests credential through /wallet/bridge. If needed, bridge calls /api/ishuman/derive-site-proof. |
| 5 | Site verifier SDK | IsHumanVerifier validates claim, expiry, revocation membership, and Ed25519 signature locally in browser. |
SDK Integration
Basic integration uses the hosted SDK and calls verify() when you need a verdict.
<script src="https://lemma.id/sdk/ishuman-verifier.js"></script>
<script>
const verifier = new IsHumanVerifier({ siteId: 'your-site-id' });
const result = await verifier.verify();
// result: { human, ppid, reason, timeMs, error }
</script>
Constructor options
| Option | Type | Default | Notes |
|---|---|---|---|
siteId | string | window.location.hostname | Registered site identifier used for bridge requests. |
lemmaOrigin | string | https://lemma.id | Override for non-production testing environments. |
debug | boolean | false | Enables SDK console logging. |
isBlockedLocally | function | null | Optional local callback for site-level PPID block checks. |
verify() result
verify() returns { human: boolean, ppid: string | null, reason: string, timeMs: number, error: string | null }.
Common reasons include valid, no_credential, expired, revoked, invalid_signature, and site_blocked.
isHuman API Reference
| Method | Path | Purpose | Auth |
|---|---|---|---|
POST | /api/ishuman/start-verification | Create Stripe Identity verification session. | None |
GET | /api/ishuman/verification-status/<session_id> | Poll verification status and fetch credential payload when ready. | None |
POST | /api/ishuman/site-block | Apply immediate site-level PPID block. | X-API-Key |
POST | /api/ishuman/site-unblock | Remove site-scoped block. | X-API-Key |
POST | /api/ishuman/network-revoke | Submit network-wide revocation request (pending review). | X-API-Key |
POST | /api/ishuman/approve-revocation | Admin approval path for network revocation. | Admin credential |
GET | /api/ishuman/check | Check site block and network revocation status for a PPID. | None |
GET | /api/ishuman/site-blocks | List all active blocks for the authenticated site. | X-API-Key |
GET | /api/ishuman/stats | Public network statistics. | None |
POST | /api/ishuman/derive-site-proof | Derive or fetch cached site-specific credential from master proof. | None |
Revocation and Abuse Controls
Revocation is tiered. Do not rely on the abuser's browser or wallet to enforce a ban.
Tier 0: Immediate site deny (customer app)
Your app should stop the current session immediately (for example end the session, deny the action, or return 403) while Lemma propagates canonical revocation.
Tier 1: Site-bound PPID revocation (immediate, canonical)
Call POST /api/ishuman/site-block with your site API key. Lemma writes both a SiteBlock row and a canonical RevocationList entry for the site-bound PPID, then publishes Bloom sync so verifiers reject that PPID across devices on your site.
You can also revoke IAM users via POST /api/developer/sites/<site_id>/users/<ppid>/revoke, which now triggers the same canonical PPID revocation path.
For local-first verification with ishuman-verifier.js, either call GET /api/ishuman/check server-side or provide isBlockedLocally(ppid) backed by your own synced block list.
Tier 2: Network revocation (reviewed)
Sites can request network action via POST /api/ishuman/network-revoke (tier 1 block is applied immediately). Admin approval through POST /api/ishuman/approve-revocation revokes wallet, master credential, and all derived credentials network-wide.
Privacy Model (PPID by Site)
- PPID derivation binds identity to wallet secret + normalized site hostname.
- Derived credentials are site-specific; one site's PPID cannot be correlated directly by another site.
- Wallet bridge and derivation paths preserve separation between internal site IDs and runtime hostname binding.