Browser client
createFaceCard, enroll and signIn.
createFaceCard
import { createFaceCard } from '@facecard/sdk';
const fc = createFaceCard({ publishableKey: 'fc_pk_live_xxx' });| Option | Type | Description |
|---|---|---|
publishableKey | string | Your fc_pk_live_... key. The page origin must be on the app's allow list. |
The client asks for the camera when you call enroll or signIn. It requests a fresh challenge for each call and computes the face descriptors in the browser. No image leaves the device.
enroll
const { user, token } = await fc.enroll({
email: 'ada@example.com',
name: 'Ada',
consent: { policy_version: '2026-10-14', accepted: true },
});| Field | Type | Description |
|---|---|---|
email | string | Unique in the app. |
name | string | Display name. |
consent | { policy_version: string, accepted: true } | Pass it only after the user accepted your privacy notice; policy_version names that notice. Otherwise the call fails with consent_required before any network request. |
Resolves with the created user (id, email, name, created_at) and a token, the same data as POST /v1/enroll. Rejects with email_taken or face_already_enrolled on a conflict.
signIn
const { user, token } = await fc.signIn();Resolves with the matched user and a token, like POST /v1/match. Rejects with no_match when no enrolled face matched clearly enough.
signOut
await fc.signOut();Calls POST /v1/me/logout so the server revokes the token, then always clears the token the client holds. It is best effort: a network error, a timeout (3 seconds by default, change it with { timeoutMs }) or a 401 is swallowed and it never throws. It resolves true when the server confirmed the sign out and false otherwise, so you can drop your own session state right after it without waiting on the result. Pass { token } to sign out a token you hold yourself; the client's stored token is then left alone.
Offline JWKS verification on your server cannot see a sign out. Use tokens.verify (the revocation aware check) when that matters.
Verify on your server
The returned token is only a claim until your server checks it. See Quickstart: server.
Handling errors
import { FaceCardError } from '@facecard/sdk';
try {
await fc.signIn();
} catch (err) {
if (err instanceof FaceCardError) {
switch (err.code) {
case 'no_match': /* ask the user to retry */ break;
case 'rate_limited': /* wait before retrying */ break;
default: console.error(err.code, err.status);
}
}
}