> For the complete documentation index, see [llms.txt](https://docs.fraudcheck.co.za/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.fraudcheck.co.za/consumer-service/identity/address-lookup.md).

# Address Lookup

Address Lookup returns the known address history for a consumer based on their South African ID number. Use it to confirm a stated address against verified records, surface previous addresses, or flag inconsistencies during onboarding and KYC checks.

## When to use this

Use this service to:

* Verify a consumer's stated address against verified records
* Retrieve up to four historical addresses for a consumer
* Detect address inconsistencies that may indicate fraud
* Support KYC and onboarding workflows

{% hint style="info" %}
Address data reflects records previously reported to verified consumer databases - namely consumer credit databases. It is not a live query against a government or postal database.
{% endhint %}

## How it works

Submit an ID number, first name, surname, and consent flag in a single POST request. The service looks up the consumer in the verified address database and returns their demographic details and address history synchronously. If no records are found, the response is still successful with an empty address history.

| Property              | Value                       |
| --------------------- | --------------------------- |
| Response type         | `Synchronous`               |
| Typical response time | < 5s (up to 60s under load) |
| Result retrieval      | Returned inline             |
| Consent required      | `Yes` (mandatory)           |
| Region                | South Africa                |

## Authentication

```http
Authorization: Bearer {your_access_token}
```

## Endpoint

```http
POST /address-lookup/verify
```

## Request

### Headers

| Header          | Required | Value              |
| --------------- | -------- | ------------------ |
| `Authorization` | Yes      | `Bearer {token}`   |
| `Content-Type`  | Yes      | `application/json` |

### Body parameters

| Field                          | Type    | Required | Description                             |
| ------------------------------ | ------- | -------- | --------------------------------------- |
| `IdentityNo`                   | string  | Yes      | 13-digit South African ID number        |
| `FirstName`                    | string  | Yes      | Consumer's first name                   |
| `LastName`                     | string  | Yes      | Consumer's surname                      |
| `ConsentObtainedByDataSubject` | boolean | Yes      | Must be `true`. Confirms POPIA consent. |

### Example request

```json
{
  "IdentityNo": "8601015800086",
  "FirstName": "John",
  "LastName": "Smith",
  "ConsentObtainedByDataSubject": true
}
```

## Response

### Response fields

| Field              | Type    | Description                                        |
| ------------------ | ------- | -------------------------------------------------- |
| `success`          | boolean | Whether the request was processed                  |
| `transaction_id`   | string  | Unique identifier for this request                 |
| `screening_result` | string  | `ACCEPT`, `REVIEW`, or `REJECT`                    |
| `lookup_result`    | object  | Container for consumer details and address history |

### `lookup_result.consumer_info` fields

Consumer demographic details. Empty `{}` if no record was found.

| Field                 | Type   | Description                           |
| --------------------- | ------ | ------------------------------------- |
| `surname`             | string | Surname on file                       |
| `forename1`           | string | First name on file                    |
| `gender`              | string | `M` or `F`                            |
| `date_of_birth`       | string | Date of birth (`YYYYMMDD`)            |
| `identity_no`         | string | ID number on file                     |
| `marital_status_desc` | string | Marital status (e.g. `SINGLE`)        |
| `deceased_date`       | string | Deceased date, or `0` if not deceased |

### `lookup_result.address_history[]` fields

Up to 4 addresses, ordered most recent first. Empty `[]` if none on file.

| Field              | Type   | Description                                |
| ------------------ | ------ | ------------------------------------------ |
| `line1`            | string | Address line 1                             |
| `suburb`           | string | Suburb                                     |
| `city`             | string | City                                       |
| `postal_code`      | string | Postal code                                |
| `province`         | string | Province name                              |
| `information_date` | string | Date the address was reported (`YYYYMMDD`) |
| `address_period`   | string | Months at this address                     |
| `owner_tenant`     | string | `O` = Owner, `T` = Tenant                  |

### Screening result logic

| Result   | Meaning                                            |
| -------- | -------------------------------------------------- |
| `ACCEPT` | Identity matched and at least one address returned |
| `REVIEW` | Identity matched but no addresses on file          |
| `REJECT` | Identity not found in the consumer database        |

### Example response - addresses found

```json
{
  "success": true,
  "transaction_id": "d41d8cd98f00b204e9800998ecf8427e",
  "screening_result": "ACCEPT",
  "lookup_result": {
    "success": true,
    "consumer_info": {
      "surname": "SMITH",
      "forename1": "JOHN",
      "gender": "M",
      "date_of_birth": "19860101",
      "identity_no": "8601015800086",
      "marital_status_desc": "SINGLE",
      "deceased_date": "0"
    },
    "address_history": [
      {
        "line1": "12 MAIN ROAD",
        "suburb": "SANDTON",
        "city": "JOHANNESBURG",
        "postal_code": "2196",
        "province": "GAUTENG",
        "information_date": "20210527",
        "address_period": "24",
        "owner_tenant": "O"
      }
    ]
  }
}
```

### Example response - no addresses on file

```json
{
  "success": true,
  "transaction_id": "d41d8cd98f00b204e9800998ecf8427e",
  "screening_result": "REVIEW",
  "lookup_result": {
    "success": true,
    "consumer_info": {},
    "address_history": []
  }
}
```

## Errors

| HTTP | Code                  | Meaning                                                             | Action                                                |
| ---- | --------------------- | ------------------------------------------------------------------- | ----------------------------------------------------- |
| 400  | `bad_request`         | Missing required field or `ConsentObtainedByDataSubject` not `true` | Set consent to `true` and provide all required fields |
| 401  | `unauthorized`        | Token missing or expired                                            | Refresh your access token                             |
| 403  | `forbidden`           | Account lacks access to this service                                | Contact your account manager                          |
| 502  | `service_unavailable` | Upstream lookup service unavailable                                 | Retry with exponential backoff                        |
| 500  | `server_error`        | Unexpected error                                                    | Contact support                                       |

{% hint style="info" %}
An identity that cannot be found returns HTTP `200` with `screening_result: "REJECT"` - it is a successful API call with a negative result, not an error.
{% endhint %}

## Code examples

{% tabs %}
{% tab title="cURL" %}

```bash
BASE_URL="https://consumer-service-api.fraudcheckonline.co.za/consumer-service"

curl -X POST "$BASE_URL/address-lookup/verify" \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "IdentityNo": "8601015800086",
    "FirstName": "John",
    "LastName": "Smith",
    "ConsentObtainedByDataSubject": true
  }'
```

{% endtab %}

{% tab title="Python" %}

```python
import requests

BASE_URL = "https://consumer-service-api.fraudcheckonline.co.za/consumer-service"

response = requests.post(
    f"{BASE_URL}/address-lookup/verify",
    headers={
        "Authorization": f"Bearer {access_token}",
        "Content-Type": "application/json",
    },
    json={
        "IdentityNo": "8601015800086",
        "FirstName": "John",
        "LastName": "Smith",
        "ConsentObtainedByDataSubject": True,
    },
)
result = response.json()

print(f"Screening: {result['screening_result']}")
for addr in result["lookup_result"].get("address_history", []):
    print(f"{addr['line1']}, {addr['suburb']}, {addr['city']}, {addr['province']} {addr['postal_code']}")
```

{% endtab %}

{% tab title="JavaScript (Node.js)" %}

```javascript
const BASE_URL = "https://consumer-service-api.fraudcheckonline.co.za/consumer-service";

const response = await fetch(`${BASE_URL}/address-lookup/verify`, {
  method: "POST",
  headers: {
    Authorization: `Bearer ${accessToken}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    IdentityNo: "8601015800086",
    FirstName: "John",
    LastName: "Smith",
    ConsentObtainedByDataSubject: true,
  }),
});
const result = await response.json();

const addresses = result.lookup_result?.address_history ?? [];
addresses.forEach(a => console.log(`${a.line1}, ${a.city}, ${a.province}`));
```

{% endtab %}
{% endtabs %}

## Compliance & consent

* Consent is mandatory. Requests without `ConsentObtainedByDataSubject: true` are rejected with HTTP `400`.
* Obtain explicit consent from the data subject before submitting.
* Retain proof of consent in line with POPIA requirements.

## FAQ

<details>

<summary>How current are the addresses returned?</summary>

Addresses reflect records previously reported to verified consumer credit databases. They represent known historical addresses and may not be the consumer's current residence.

</details>

<details>

<summary>How many addresses can be returned?</summary>

Up to four addresses, ordered most recent first.

</details>

<details>

<summary>What does an empty `address_history` mean?</summary>

The consumer was found but has no addresses on file. The response returns `screening_result: "REVIEW"` and is not an error.

</details>

<details>

<summary>What client timeout should I configure?</summary>

Up to 60 seconds.

</details>

## Changelog

| Date       | Version | Change           |
| ---------- | ------- | ---------------- |
| 2026-04-11 | v1.0    | Initial release. |


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.fraudcheck.co.za/consumer-service/identity/address-lookup.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
