---
title: "DigiLocker"
description: "Use DigiLocker for MainSDK identity checks in India - partner access, main.yaml for the India market, claims-only results, testing and swapping."
section: "integrations"
canonical: "https://mainsdk.dev/docs/integrations/digilocker"
updated: "2026-10-28"
---

# DigiLocker

> Use DigiLocker for MainSDK identity checks in India - partner access, main.yaml for the India market, claims-only results, testing and swapping.

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

DigiLocker is India's government digital document wallet, where people keep issued documents such as identity and education records. Behind [`verify`](https://mainsdk.dev/docs/interfaces/verify), it runs `verify.identity()` for users in India, with the person's consent and only the claims you ask for. Pick it when a flow for Indian users needs a government-backed identity check.

> **Note:** Built (spec `verify`), through the DigiLocker driver of `digital-ids`. That driver follows DigiLocker's public OAuth 2.0 API and is not proven against the live service from here: run one consent flow against the partner sandbox first.

## Interfaces it serves

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

- Status: Building for 0.7 · ships as a beta API
- Driver: `digilocker` (DigiLocker). identity, through the digital-ids driver
- Docs: https://mainsdk.dev/docs/interfaces/verify.md

```yaml
verify:
  driver: digilocker
```

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

## Before you start

1. **Apply for partner access** to DigiLocker as a requesting organisation. Access needs approval before you receive credentials.
2. **Register your redirect URL** and keep the client credentials you are issued in your secrets manager.

## Configure

```yaml title="main.yaml"
verify:
  driver: twilio-verify          # phone and email checks
  identity: { in: digilocker }   # identity checks in India go through DigiLocker
  require: { in: substantial }   # digilocker reaches substantial, not high
  drivers:
    digilocker:
      client-id: secret:DIGILOCKER_CLIENT_ID
      client-secret: secret:DIGILOCKER_CLIENT_SECRET
      redirect: https://app.example.com/digilocker/callback   # the redirect URL you registered
```

You can put the `identity` line in the India overlay, `main.in.yaml`, instead.

## Use it

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

export async function startAgeCheck(user: string) {
  const started = await verify.identity({
    level: "substantial",
    market: "in",
    claims: ["age_over_18"],
    purpose: "Sell age-restricted items",
    user,
    consent: { policy: "privacy-2026-10" },
  });
  return started.url;   // DigiLocker's consent screen; its redirect brings a code back
}

export async function finishAgeCheck(id: string, code: string) {
  const done = await verify.identity.complete({ id, code });
  return done.status === "approved" ? done.claims : null;   // { age_over_18: true }
}
```

The levels are `basic`, `substantial` and `high`. DigiLocker reaches `substantial`; asking for `high` in `in` fails with `MAIN-VERIFY-0004`, and `mainsdk check` reports it when `verify.require` says so.

## Local development and testing

In tests, set `verify.identity.in: local`: the local fake approves with `code: "approve"` and keeps nothing but the asked claims.

## What MainSDK adds on top

The `verify` and digital-ids specs set what the driver must do:

- Only the requested claims are stored, labelled, with a consent record.
- `mainsdk check` flags a request for more claims than the flow needs.

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

## Limits and notes

- India only: route it with `identity: { in: digilocker }`.
- Built as a `verify` driver (spec `verify`); `verify` owns `verify.identity()` and the DigiLocker driver stays in `digital-ids`.
- DigiLocker returns a date of birth, not a claim: the driver derives `age_over_NN` and drops the date, so your app never holds it.
- Identity results are personal data; label the fields that store them in [`db`](https://mainsdk.dev/docs/interfaces/db), in the `in` region.

## Swap to or from it

```yaml title="main.yaml"
verify:
  identity: { in: onfido }   # was { in: digilocker }
```

Results you keep live in your own `db`, so a swap carries little provider state.

## FAQ

**Do I get the person's documents?** You get the claims you asked for, such as a verified name or age, not the documents themselves.

**Can I use DigiLocker outside India?** No. It serves people with Indian government records.

## Next

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