---
title: "Onfido"
description: "Use Onfido for MainSDK document and biometric identity checks - API token, main.yaml per market, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/onfido"
updated: "2026-10-28"
---

# Onfido

> Use Onfido for MainSDK document and biometric identity checks - API token, main.yaml per market, testing and swapping.

Canonical: https://mainsdk.dev/docs/integrations/onfido · Updated: 2026-10-28

Onfido verifies a person's identity from a photo of their identity document and a selfie or video. Behind [`verify`](https://mainsdk.dev/docs/interfaces/verify), it runs `verify.identity()` in the markets you route to it. Pick it for regulated flows, such as onboarding to financial services, where you need a document-based identity check across many countries.

> **Note:** Built (spec `verify`). The Onfido requests (a Studio workflow run, read back by its id) follow Onfido's public docs and are tested against recorded replies, not a live account. Run one check in the sandbox before a market depends on it.

## Interfaces it serves

### Phone, email and identity checks (`verify`)

- Status: Building for 0.7 · ships as a beta API
- Driver: `onfido` (Onfido). identity
- Docs: https://mainsdk.dev/docs/interfaces/verify.md

```yaml
verify:
  driver: onfido
```

Swap to another provider: `twilio-verify`, `bird`, `local`, `digilocker`, `persona`.

## Before you start

1. **Get an Onfido account** and a sandbox to build against.
2. **Pick the regional environment** that matches where your users' data must live, since Onfido runs separate regions.
3. **Create an API token** for each environment and keep it in your secrets manager.

## Configure

```yaml title="main.yaml"
verify:
  driver: twilio-verify     # phone and email checks
  identity: { us: onfido, default: onfido }   # market to identity driver; default serves the rest
  require: { us: high }                       # the level the market requires; onfido reaches high
  drivers:
    onfido:
      token: secret:ONFIDO_TOKEN              # the API token of the environment
      workflow: wf_123                        # the Studio workflow that runs document and selfie
      region: eu                              # eu, us or in; picks api.<region>.onfido.com
```

## Use it

```ts title="lib/kyc.ts"
import { verify } from "mainsdk/verify";

export async function startCheck(user: string) {
  const started = await verify.identity({
    level: "high",
    market: "us",
    claims: ["age_over_18"],
    purpose: "Open an account",
    user,
    consent: { policy: "privacy-2026-10" },
  });
  return started.url;   // send the person to Onfido; later verify.identity.complete({ id: started.id })
}
```

## Local development and testing

Use Onfido's sandbox with a sandbox token. In tests, set `verify.identity.default: local`: the local fake approves with `code: "approve"` and keeps nothing but the asked claims.

## What MainSDK adds on top

One call for identity checks in every market, routed by `identity`, and swappable with no code change. Only the claims you ask for are kept, each labelled, with a consent record; a level the driver cannot reach fails with `MAIN-VERIFY-0004` before the person is sent anywhere.

See [Phone, email and identity checks](https://mainsdk.dev/docs/interfaces/verify).

## Limits and notes

- Built `verify` driver (spec `verify`). It declares its own host, `api.<region>.onfido.com`, so `network.allow` does not change.
- Onfido reaches the `high` level.
- Identity results are personal data; label the fields that store them in [`db`](https://mainsdk.dev/docs/interfaces/db).
- `verify` is free and runs in your app.

## Swap to or from it

```yaml title="main.yaml"
verify:
  identity: { us: persona }   # was { us: onfido }
```

Results you keep live in your own `db`. Checks in progress at Onfido stay there.

## FAQ

**Does Onfido store the document images?** Onfido processes them under its own terms; check its data retention settings for your account.

## Next

- [Phone, email and identity checks](https://mainsdk.dev/docs/interfaces/verify)
- [Persona](https://mainsdk.dev/docs/integrations/persona) and [DigiLocker](https://mainsdk.dev/docs/integrations/digilocker)
- [Swap a driver](https://mainsdk.dev/docs/guides/swap-a-driver)
