# Phone Identity Lookup

> Resolve a mobile number to the name and date of birth on its ICAD/BVN record. For corroboration and fraud signal, not as standalone identity.

Resolves a mobile number to the name and date of birth on its linked ICAD/BVN record. Use it to corroborate other evidence or as a fraud signal, not as a standalone identity check.

`POST /v1/verify/phone`

- **Availability:** Sandbox and live
- **Indicative price:** ₦50.00 per completed check
- **Consent:** Your attestation (`client_attested`).

## Request

**Body parameters**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `phone` | string | Yes | Format: Nigerian mobile number, `0803…` or `+234803…`. |
| `reason` | string | Yes | Purpose of the check. One of the 38 NIMC purpose codes. See the [purpose code list](https://speedmap-delta.vercel.app/docs/compliance#purpose-codes). |
| `consent` | object | Yes | Your attestation that you obtained the data subject's consent for this purpose. |
| `consent.obtained` | boolean | Yes | Always `true`. |
| `match` | object | No | Optional values to compare against the record. Each comparison is returned in field_matches; match is true only if all of them agree. |
| `match.first_name` | string | No | Must not be empty. |
| `match.middle_name` | string | No | Must not be empty. |
| `match.last_name` | string | No | Must not be empty. |
| `match.date_of_birth` | string | No | Format: date, `YYYY-MM-DD`. |

- Accepts local (`0803…`) and international (`+234803…`) formats.

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/phone \
  -H "Authorization: Bearer sk_test_..." \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{
  "phone": "08031234567",
  "reason": "financialProducts",
  "consent": {
    "obtained": true
  },
  "match": {
    "last_name": "Griffin"
  }
}'
```

_Node.js_

```javascript
const res = await fetch("http://localhost:4000/v1/verify/phone", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.SPEEDMAP_API_KEY}`,
    "Content-Type": "application/json",
    "Idempotency-Key": crypto.randomUUID(),
  },
  body: JSON.stringify({
    "phone": "08031234567",
    "reason": "financialProducts",
    "consent": {
      "obtained": true
    },
    "match": {
      "last_name": "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/phone",
    headers={
        "Authorization": f"Bearer {os.environ['SPEEDMAP_API_KEY']}",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "phone": "08031234567",
        "reason": "financialProducts",
        "consent": {
            "obtained": True
        },
        "match": {
            "last_name": "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": "phone",
  "method": "phone_lookup",
  "status": "verified",
  "match": true,
  "field_matches": {
    "last_name": true
  },
  "field_confidence": {
    "last_name": 100
  },
  "mode": "sandbox",
  "reason": "financialProducts",
  "subject": "*******4567",
  "summary": {
    "first_name": "A*****",
    "last_name": "O*****"
  },
  "consent": {
    "mechanism": "client_attested",
    "consent_id": null,
    "timestamp": "2026-10-19T09:41:07.512Z"
  },
  "source": "api",
  "error": null,
  "billing": {
    "amount_kobo": 0,
    "currency": "NGN"
  },
  "latency_ms": 233,
  "created_at": "2026-10-19T09:41:07.512Z",
  "updated_at": "2026-10-19T09:41:07.874Z"
}
```

**summary**

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `first_name` | string | No | First name on the record, masked to its first letter: `A*****`. |
| `last_name` | string | No | Last name on the record, masked to its first letter. |

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": {
    "first_name": "CLARKE",
    "middle_name": "ELIZA",
    "last_name": "GRIFFIN",
    "date_of_birth": "1992-04-18"
  }
}
```

## Test values

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

**Linked number**

```json
{
  "phone": "08031234567",
  "reason": "financialProducts",
  "consent": {
    "obtained": true
  }
}
```

**Unlinked number**

```json
{
  "phone": "08000000000",
  "reason": "financialProducts",
  "consent": {
    "obtained": true
  }
}
```

## 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/phone
