Integration
ID tokens
Integration

ID tokens

Every verified session also carries a signed JWT. Use it to pass a verified identity between your own services without calling LKP again.

Format#

Tokens are RS256 JWTs, valid for one hour. They appear as result.idToken on the session object and in the webhook payload.

issstringrequired
The LKP API origin, https://lkp-verifier.onrender.com.
audstringrequired
Your app ID (app_…). Always check it.
substringrequired
The nullifier: your anonymous, stable user ID.
verified_claimsstring[]required
Requirements that were proven, e.g. ["Age >= 18"].
request_idstringrequired
Unique per verification; use it to reject token reuse if you need to.
iat / expnumberrequired
Issued-at and expiry (Unix seconds).

Verify a token#

Fetch the public keys from the JWKS endpoint (cache them) and check signature, issuer, audience and expiry. Any standard JWT library works.

import { createRemoteJWKSet, jwtVerify } from "jose";

const JWKS = createRemoteJWKSet(new URL("https://lkp-verifier.onrender.com/.well-known/jwks.json"));

export async function verifyLkpToken(token: string) {
  const { payload } = await jwtVerify(token, JWKS, {
    issuer: "https://lkp-verifier.onrender.com",
    audience: process.env.LKP_APP_ID, // "app_…"
  });
  return { userId: payload.sub, claims: payload.verified_claims as string[] };
}

Discovery metadata is available at https://lkp-verifier.onrender.com/.well-known/openid-configuration.

Where tokens come from matters
Accept ID tokens only from your own backend (which got them from the LKP API with your secret key), not straight from a browser. A token proves that someone verified for your app; binding it to the right user session is up to you.