Quickstart: server
Verify user tokens and list users from Node with your secret key.
Your server uses a secret key (fc_sk_live_xxx). Create one in the developer portal. The key is shown once, so store it in your secret manager or environment, never in browser code or in git.
npm install @facecard/sdk
export FACECARD_SECRET_KEY=fc_sk_live_xxxVerify a token from the browser
import { createFaceCardServer, FaceCardError } from '@facecard/sdk';
const facecard = createFaceCardServer({ secretKey: process.env.FACECARD_SECRET_KEY! });
export async function startSession(token: string) {
const result = await facecard.tokens.verify(token);
if (!result.valid) {
throw new Error(`Token rejected: ${result.reason}`);
}
// claims: sub (user id), app_id, email, iat, exp, jti
return result.claims;
}Verifying with tokens.verify calls the API. If you want to avoid a network call, verify the signature locally against the public keys:
const claims = await facecard.verifyTokenOffline(token);
console.log(claims.sub, claims.email);verifyTokenOffline checks the ES256 signature, the issuer, the audience and the expiry using the JWKS at https://api.facecard.dev/.well-known/jwks.json. See User tokens and JWKS.
List users
const page = await facecard.users.list({ limit: 50 });
for (const user of page.users) {
console.log(user.id, user.email);
}
if (page.next_cursor) {
const next = await facecard.users.list({ limit: 50, cursor: page.next_cursor });
}users.list returns only users of the app that owns the key, and never returns face data.
Read usage and delete a user
const usage = await facecard.usage('2026-10');
console.log(usage.auths, 'of', usage.limit);
await facecard.users.delete('usr_123'); // removes the user and all their face templatesThe same thing with curl
curl https://api.facecard.dev/v1/users?limit=50 \
-H "Authorization: Bearer fc_sk_live_xxx"
curl -X POST https://api.facecard.dev/v1/tokens/verify \
-H "Authorization: Bearer fc_sk_live_xxx" \
-H "Content-Type: application/json" \
-d '{"token":"<jwt>"}'Handling errors
Every failed call throws a FaceCardError with a code and an HTTP status:
try {
await facecard.users.get('usr_missing');
} catch (err) {
if (err instanceof FaceCardError && err.code === 'not_found') {
// handle it
} else {
throw err;
}
}See Errors and the server SDK reference.