UnifyIDDeveloper

Quickstart

Add Continue with UnifyID

Create a Sandbox application, send a secure authorization request, exchange its one-time code, and retrieve only approved information.

Prerequisites

  • A verified UnifyID identity and developer portal access.
  • A backend capable of storing a short-lived OAuth transaction.
  • An exact callback URI. Localhost may use HTTP; other hosts require HTTPS.
  • The API at https://api.dev.unifyid.io and identity experience at https://dev.unifyid.io.

1. Create an application

Open Applications → Create application. Enter the app name and description, register the callback, and choose the smallest useful scope set. Copy its public client_id. Confidential backends should also create a client secret under Credentials.

2. Create a transaction

const state = crypto.randomBytes(32).toString("base64url");
const nonce = crypto.randomBytes(32).toString("base64url");
const codeVerifier = crypto.randomBytes(48).toString("base64url");
const codeChallenge = crypto
  .createHash("sha256")
  .update(codeVerifier)
  .digest("base64url");

// Store all values in the initiating login transaction.
// Expire the transaction quickly and never reuse it.

3. Redirect the browser

GET https://api.dev.unifyid.io/v1/oauth/authorize
  ?response_type=code
  &client_id=vid_sandbox_xxx
  &redirect_uri=http%3A%2F%2Flocalhost%3A4000%2Fcallback
  &scope=openid%20profile%20email%20identity_verified
  &state={state}
  &nonce={nonce}
  &code_challenge={codeChallenge}
  &code_challenge_method=S256
  &purpose=Create%20and%20secure%20your%20account

The person signs in, completes face assurance when required, and approves or denies the listed information. UnifyID returns a one-time code and the original state.

4. Validate the callback

Required security checks

Complete every check before accepting the authorization response.

  1. Load the initiating transaction from the same browser session.
  2. Compare state with a timing-safe check.
  3. Reject missing, expired, reused, or mismatched transactions.
  4. Mark the transaction consumed before code exchange.

5. Exchange the code

curl -X POST https://api.dev.unifyid.io/v1/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "CODE_FROM_CALLBACK",
    "redirect_uri": "http://localhost:4000/callback",
    "client_id": "vid_sandbox_xxx",
    "code_verifier": "ORIGINAL_CODE_VERIFIER",
    "client_secret": "SERVER_SIDE_SECRET"
  }'

Public browser and mobile clients omit client_secret; PKCE remains required. The code is short-lived, single-use, and bound to the client, redirect URI, and PKCE transaction.

6. Validate and retrieve data

Validate the ID token signature, issuer, audience, expiry, nonce, and type. Store sub as the application’s external account key.

curl https://api.dev.unifyid.io/v1/userinfo \
  -H "Authorization: Bearer {oauth_access_token}"
{
  "sub": "application_specific_subject",
  "email": "person@example.com",
  "identity_verified": true
}
Unapproved, unavailable, or out-of-policy properties are omitted. UnifyID does not fabricate empty identity data.

Security requirements

Never expose a client secret to browser code. Never log codes, tokens, PKCE verifiers, returned claims, or biometric workflow information.

Next steps

Review Scopes, add signed webhooks, and complete the Sandbox verification plan.

Was this page helpful?
UnifyID Developer Documentation · Version V.1 · Updated July 2026