# Bank Account Verification

> Resolve and verify the holder name on a Nigerian bank account via NIBSS ICAD Name Enquiry. Batch-capable.

Resolves the holder name of a bank account (10-digit NUBAN) through NIBSS ICAD Name Enquiry, and checks it against the name you expect. Ideal for payouts and onboarding; use [bulk jobs](https://speedmap-delta.vercel.app/docs/bulk) for batches.

`POST /v1/verify/account`

- **Availability:** Sandbox and live
- **Indicative price:** ₦25.00 per completed check
- **Consent:** Not required (`not_required`); no `reason` either.
- **MCP tool:** `verify_account`

## Request

**Body parameters**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `account_number` | string | Yes | Format: 10 digits. |
| `bank_code` | string | Yes | Format: 3 to 6 digits. |
| `match` | object | No |  |
| `match.name` | string | Yes | Expected account holder name; compared token by token, order-insensitive. At least 2 characters. |

- Bank codes are CBN codes such as `058` (GTBank). `GET /v1/banks` lists them.
- `match.name` is compared token by token and in any order: every word you send must appear in the account name.

Send an `Idempotency-Key` header so a retried request is never billed twice. See [Idempotency](https://speedmap-delta.vercel.app/docs/idempotency).

_cURL_

```bash
curl -X POST http://localhost:4000/v1/verify/account \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "account_number": "0123456789",
  "bank_code": "058",
  "match": {
    "name": "Clarke Griffin"
  }
}'
```

_Node.js_

```javascript
const res = await fetch("http://localhost:4000/v1/verify/account", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SPEEDMAP_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "account_number": "0123456789",
    "bank_code": "058",
    "match": {
      "name": "Clarke Griffin"
    }
  }),
});

const verification = await res.json();
if (!res.ok) throw new Error(verification.error.message);
console.log(verification.status, verification.match);
```

_Python_

```python
import os, uuid, requests

res = requests.post(
    "http://localhost:4000/v1/verify/account",
    headers={
        "Authorization": f"Bearer {os.environ['SPEEDMAP_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "account_number": "0123456789",
        "bank_code": "058",
        "match": {
            "name": "Clarke Griffin"
        }
    },
    timeout=30,
)
res.raise_for_status()
verification = res.json()
print(verification["status"], verification["match"])
```

## Response

A completed check returns `200` with a [verification object](https://speedmap-delta.vercel.app/docs/verifications). `status` is `verified` or `not_found`. If the provider has not answered in time you get `202` with `status: "pending"`; [retrieve it later](https://speedmap-delta.vercel.app/docs/verifications#pending-verifications) or wait for the `verification.completed` [webhook](https://speedmap-delta.vercel.app/docs/webhooks).

**200 OK · assertion**

```json
{
  "reference_id": "spm_8171f3a87cbe221341f7185f",
  "object": "verification",
  "product": "account",
  "method": "account_name_enquiry",
  "status": "verified",
  "match": true,
  "field_matches": null,
  "field_confidence": null,
  "mode": "sandbox",
  "reason": null,
  "subject": "******6789",
  "summary": {
    "account_name_masked": "A***** C***** O*****",
    "bank_name": "Guaranty Trust Bank",
    "name_match": true
  },
  "consent": {
    "mechanism": "not_required",
    "consent_id": null,
    "timestamp": "2026-10-19T09:41:07.512Z"
  },
  "source": "api",
  "error": null,
  "billing": {
    "amount_kobo": 0,
    "currency": "NGN"
  },
  "latency_ms": 190,
  "created_at": "2026-10-19T09:41:07.512Z",
  "updated_at": "2026-10-19T09:41:07.874Z"
}
```

**summary**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `account_name_masked` | string | No | Account name with each word masked: `A***** C***** O*****`. |
| `bank_name` | string | No | Bank name for the code you sent. |
| `name_match` | boolean \| null | No | Result of `match.name`; `null` when not requested. |

Full-tier accounts calling the REST API also receive `provider`, `provider_reference` and `data`, the normalized record. MCP, webhooks, lists and bulk results never include it. See [Response shaping](https://speedmap-delta.vercel.app/docs/response-shaping).

**Full tier only**

```json
{
  "provider": "sandbox",
  "provider_reference": "SBX6CB753DB2C",
  "data": {
    "account_number": "0123456789",
    "bank_code": "058",
    "bank_name": "Guaranty Trust Bank",
    "account_name": "CLARKE ELIZA GRIFFIN",
    "bvn_linked": true,
    "name_match": true
  }
}
```

## Test values

Send these bodies with a sandbox key. More outcome triggers are on the [Sandbox](https://speedmap-delta.vercel.app/docs/sandbox) page.

**Name matches**

```json
{
  "account_number": "0123456789",
  "bank_code": "058",
  "match": {
    "name": "Clarke Griffin"
  }
}
```

**Name mismatch**

```json
{
  "account_number": "1234567890",
  "bank_code": "044",
  "match": {
    "name": "John Doe"
  }
}
```

**Corporate account**

```json
{
  "account_number": "4567890123",
  "bank_code": "011"
}
```

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 400 | `invalid_request` | The body failed validation. `details` lists each field. |
| 401 | `unauthorized` | Missing or invalid API key. |
| 402 | `insufficient_balance` | Live only: wallet balance is below the check price. |
| 403 | `not_entitled` | Your workspace is not enabled for this product or method. |
| 409 | `idempotency_key_reused` | The `Idempotency-Key` was used with a different body. |
| 422 | `provider_rejected_request` | The upstream registry rejected the request. |
| 503 | `verification_unavailable` | Temporary failure. Retry, with the same or a new `Idempotency-Key`. |

All errors share one shape. See [Errors](https://speedmap-delta.vercel.app/docs/errors) for the full list.

---

Source: https://speedmap-delta.vercel.app/docs/products/account
