> ## Documentation Index
> Fetch the complete documentation index at: https://bkey.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Sandbox test data

> The identity values that resolve in the sandbox, the persona-matching rule that catches almost everyone, and how to test the failure paths on purpose.

<div className="bmoni-spine">
  <span>Lifecycle</span>
  <a data-stage="1" href="/lifecycle#1-create-the-user">User</a>
  <a data-stage="2" href="/lifecycle#2-provision-the-smart-wallet">Wallet</a>
  <a data-stage="3" href="/lifecycle#3-verify-identity-kyc">KYC</a>
  <a data-stage="4" href="/lifecycle#4-activate-the-rail">Rail</a>
  <a data-stage="5" href="/lifecycle#5-fund-the-wallet">Fund</a>
  <a data-stage="6" href="/lifecycle#6-move-money">Move money</a>
</div>

This page gives you the identity values that resolve in the sandbox, and the one rule you must follow for them to work.

Identity look-up is the first real call in onboarding, and it is where most integrations fail first. The cause is almost never a malformed request. Read [Match the persona exactly](#match-the-persona-exactly) before you debug anything else.

<Note>
  Looking for a funded balance rather than an identity? [Request test tokens](/request-test-tokens) credits NGN and USD to a sandbox wallet. This page covers identity data; that page covers money.
</Note>

## The test personas

Nigerian identity look-ups are resolved by our identity provider against its own sandbox, which recognises a fixed set of test personas. Only the values below resolve — no other number will, however well-formed.

There are two personas. Almost everything belongs to the first.

### Bunch Dillon

| Credential                           | Value              |
| ------------------------------------ | ------------------ |
| BVN                                  | `95888168924`      |
| National Identification Number (NIN) | `63184876213`      |
| Virtual NIN (vNIN)                   | `JZ426633988976CH` |
| Driver's licence                     | `63184876213`      |
| Phone                                | `08000000000`      |

Set `firstName` to `Bunch` and `lastName` to `Dillon`.

<Warning>
  The driver's licence uses the **same number** as the NIN, but the names come back in the opposite order for it — `Dillon` as the first name and `Bunch` as the last. If you are testing driver's licence verification, swap them.
</Warning>

### Samson Jabo

| Credential | Value                                                   |
| ---------- | ------------------------------------------------------- |
| BVN        | `22222222222`                                           |
| NIN        | `18482561982` (returns `Guion Audi`, not `Samson Jabo`) |
| Phone      | `08000000001`                                           |

Set `firstName` to `Samson` and `lastName` to `Jabo`.

<Note>
  `22222222222` is a real sandbox test BVN. Because it looks like a placeholder, it is often reached for by guesswork — and a correct number still fails if the submitted details do not match the persona. See the next section.
</Note>

### International passport

| Credential      | Value       | Name       |
| --------------- | ----------- | ---------- |
| Passport number | `A10000001` | `John Doe` |

## Match the persona exactly

**A correct identity number is not enough.** Verification checks the number *and* the details you submitted alongside it. Any verification performed with details other than the persona's simulates a failed identity match — which is the sandbox behaving correctly, not a bug.

So if you create a user called `Test User` and then verify BVN `22222222222`, verification fails. The BVN is valid; the name is not Samson Jabo.

<Warning>
  Create the user with the persona's own `firstName`, `lastName`, and phone number. Do not use your own name, a placeholder, or a randomly generated fixture for the fields that get matched.
</Warning>

The persona phone numbers above are in local Nigerian format. BMONI requires E.164, so convert them: `08000000000` becomes `+2348000000000`.

```http theme={null}
POST /v1/users
{
  "firstName": "Bunch",
  "lastName": "Dillon",
  "email": "bunch.dillon@example.com",
  "phoneNumber": "+2348000000000",
  "bvn": "95888168924"
}
```

<Tip>
  Keep one persona per sandbox user. Mixing Bunch Dillon's BVN with Samson Jabo's phone number fails the match for the same reason a real mismatch would.
</Tip>

### Which calls match, and which only fetch

Not every call performs matching, which is why a look-up can succeed while verification later fails.

| Call                                          | Behaviour                                                                                              |
| --------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `GET /v1/users/{userId}/kyc/bvn-lookup/{bvn}` | **Fetch only.** Returns the persona's record. Does not match against your profile, and writes nothing. |
| `GET /v1/users/{userId}/kyc/nin-lookup/{nin}` | **Matches.** Sends the profile's `firstName` and `lastName` for name-match verification.               |
| `POST /v1/users/{userId}/kyc/activate`        | **Matches.** Full verification against the submitted profile.                                          |

<Note>
  Because `bvn-lookup` only fetches, it is the cheapest way to confirm your key reaches the verification service at all. If that call returns a record but activation fails, your plumbing is fine and your profile details do not match the persona.
</Note>

## Prerequisites the errors do not mention

### A NIN look-up needs the name saved first

`nin-lookup` sends the user's `firstName` and `lastName` for name-match verification, so **both must already be saved on the KYC profile.** If they are missing, the look-up fails, and the error does not tell you the name is the reason.

```http theme={null}
PATCH /v1/users/{userId}/kyc
{
  "personalInfo": {
    "firstName": "Bunch",
    "lastName": "Dillon"
  }
}
```

Then look up the NIN:

```http theme={null}
GET /v1/users/{userId}/kyc/nin-lookup/63184876213
```

<Note>
  A BVN look-up has no such prerequisite — it returns the name rather than checking it. If you are populating a profile from scratch, run the BVN look-up first and use its response to fill `firstName` and `lastName`. Doing it in that order also guarantees the name matches.
</Note>

### A look-up writes nothing

Both look-ups are previews. They return the provider's record and do not touch the KYC profile. Fetching a BVN does not save it — you still have to `PATCH /v1/users/{userId}/kyc` with the values you want to keep.

## Validation before any look-up

Both look-ups validate locally and reject bad input without calling the provider.

| Endpoint                                      | Rule                              | Failure                                 |
| --------------------------------------------- | --------------------------------- | --------------------------------------- |
| `GET /v1/users/{userId}/kyc/bvn-lookup/{bvn}` | Exactly 11 digits after trimming. | `400` — `BVN must be exactly 11 digits` |
| `GET /v1/users/{userId}/kyc/nin-lookup/{nin}` | Exactly 11 digits after trimming. | `400` — `NIN must be exactly 11 digits` |

Surrounding whitespace is trimmed for you, so `" 95888168924 "` passes. Whitespace *inside* the number does not — `"958 881 689 24"` is 14 characters and fails.

<Tip>
  Validate the length in your own client before you call. A `400` here costs a round trip that a regular expression would have caught.
</Tip>

## What a successful BVN look-up returns

```http theme={null}
GET /v1/users/{userId}/kyc/bvn-lookup/95888168924
```

The response shape is fixed. Below, the persona's documented values are filled in; `…` marks a field whose value comes from the underlying record and is not documented, so read it from your own response rather than assuming it.

```json theme={null}
{
  "bvn": "95888168924",
  "firstName": "Bunch",
  "lastName": "Dillon",
  "middleName": null,
  "dateOfBirth": "…",
  "gender": "…",
  "email": null,
  "phoneNumber": "+2348000000000",
  "residentialAddress": null,
  "stateOfResidence": null,
  "lgaOfOrigin": null,
  "nin": "63184876213",
  "photo": null
}
```

`dateOfBirth` is always normalised to `YYYY-MM-DD`, whatever format the provider returns. Every field except `bvn`, `firstName`, `lastName`, `dateOfBirth`, and `gender` is nullable, and a sandbox persona leaves several of them empty — so do not require them in your client. Run the call once and record what the persona actually returns before you write assertions against it.

## Biometric face match

Face-match checks use the persona's identity number:

| Check                       | Identity number | Name                                               |
| --------------------------- | --------------- | -------------------------------------------------- |
| NIN face match              | `63184876213`   | `Bunch Dillon`                                     |
| BVN face match              | `95888168924`   | `Bunch Dillon`                                     |
| Driver's licence face match | `63184876213`   | `Bunch Dillon` (note the licence name order above) |

## Testing the failure paths on purpose

Every case below is deterministic, which makes them suitable for automated tests.

| To test                                    | Send                                                     | Expect                                         |
| ------------------------------------------ | -------------------------------------------------------- | ---------------------------------------------- |
| Malformed input, too short                 | `1234567890` (10 digits)                                 | `400` — `BVN must be exactly 11 digits`        |
| Malformed input, non-numeric               | `9588816892A`                                            | `400` — `BVN must be exactly 11 digits`        |
| Malformed input, internal spaces           | `958 881 689 24`                                         | `400` — `BVN must be exactly 11 digits`        |
| A well-formed number that does not resolve | `11111111111`                                            | A look-up miss — see below                     |
| **A failed identity match**                | A valid persona number against a deliberately wrong name | Verification failure, not a look-up miss       |
| Wrong partner's user                       | A valid BVN with another partner's `bmoniUserId`         | `403` — `User does not belong to this partner` |
| Missing name on a NIN look-up              | A valid NIN, before saving `firstName`/`lastName`        | A provider-side name-match failure             |

The mismatch row is the one worth automating. It is the failure your real users will hit most often, and the easiest to ship without noticing.

### What a look-up miss looks like today

A well-formed number with no matching record currently surfaces the upstream message `requested item could not be found`. That wording does not distinguish a wrong number from an identity absent from the sandbox.

<Note>
  Making a sandbox look-up miss self-explanatory — naming the sandbox and pointing here — is tracked as platform work. Until it lands, read `requested item could not be found` from a look-up as "this number is not one of the personas above".
</Note>

<Note>
  If a look-up for a persona number such as `95888168924` returns a miss, the number is not the problem. Check that you are calling the sandbox base URL with your sandbox key, then raise it with [developers@bkey.me](mailto:developers@bkey.me) — do not work through other numbers, because none of them resolve.
</Note>

## Related

* [Request test tokens](/request-test-tokens) — funding a sandbox wallet.
* [Errors and status codes](/api-reference/errors) — every error these endpoints return.
* [Nigeria KYC requirements](/api-reference/kyc-nga-requirements) — the fields Nigerian verification needs.
* [Integration flow](/api-reference/integration-flow) — where identity look-up sits in onboarding.

***

*Last reviewed: 7 August 2026. Persona values current as of 12 November 2025.*
