# Address Validation & Normalizer (Bulk, US/CA/UK) (`nibble/address-validation-normalizer`) Actor

Bulk-validate, parse and standardize postal addresses to clean JSON. No API keys. Pay per address.

- **URL**: https://apify.com/nibble/address-validation-normalizer.md
- **Developed by:** [Simon Fletcher](https://apify.com/nibble) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 validated addresses

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Address Validation & Normalizer (Bulk, US/CA/UK)

**Clean, parse and standardize messy postal addresses into structured JSON — in bulk, with no API keys and no external services.** Feed it a list of freeform addresses (or partial address fields) and get back a canonical single-line address, split components, a validation status, and a list of exactly what was fixed. Built for data teams, CRMs, and AI agents that need consistent address data before dedupe, geocoding, mail-merge, or analytics.

> **Scope — read this first.** This Actor performs **format & structural** validation and normalization: it parses components, standardizes casing/abbreviations/postal-code formatting (USPS-style), and checks that the required parts are present and correctly shaped for the country. It does **not** verify *deliverability or existence* (that a specific house/unit is real and receives mail) — that requires a live postal database and is intentionally out of scope. Every record is labelled honestly via its `status` and `issues`, so you always know what was and wasn't checked.

### What does Address Validation & Normalizer do?

It takes an array of addresses — each either a **freeform string** (`"1600 amphitheatre pkwy, mountain view ca 94043"`) or an **object with fields** (`{"street": "...", "city": "...", "zip": "..."}`) — and for each one returns:

- a **normalized** single-line address with standardized casing, street-suffix, directional and unit abbreviations, and a correctly formatted postal code;
- parsed **components** (house number, street, unit, city, region/state, postcode, country code);
- a **status** (`valid`, `corrected`, `needs_review`, `unparseable`, `empty`);
- the **corrections** applied and any structural **issues** found;
- a **confidence** score.

Because it runs on the **Apify platform**, you get API access, scheduling, integrations (Make, Zapier, n8n), and an [MCP endpoint](https://mcp.apify.com/) so AI agents can call it directly — with monitoring and run history for free.

### Why use it?

- **Deduplicate and match records.** Standardized addresses make fuzzy CRM/marketing lists collapse cleanly.
- **Pre-clean before geocoding or mailing.** Fix casing, abbreviations and postal-code formatting *before* you pay a geocoder or mailing house per lookup.
- **Validate form submissions in bulk.** Catch missing ZIP codes, malformed postcodes and unknown state codes across a whole file.
- **Agent-ready output.** Concise, flat JSON — no HTML, no nested junk — ideal for LLM tool use via Apify MCP.
- **No keys, no accounts, near-zero maintenance.** Fully self-contained: it doesn't scrape any website, so it doesn't break when a site changes.

### How to use Address Validation & Normalizer

1. Click **Try for free**.
2. In the **Input** tab, paste your addresses into the `addresses` array — plain strings, objects with fields, or a mix of both.
3. (Optional) Set a **Default country** if some rows don't state one, and a **Max addresses** cap as a cost guard.
4. Click **Start**. Results stream into the **Output** tab.
5. **Export** the dataset as JSON, CSV, Excel or HTML, or pull it via the API.

### Input

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `addresses` | array | ✅ | Address rows. Each item is a freeform string **or** an object with any of: `address`, `house_number`, `street`, `unit`, `city`, `state`/`region`, `postcode`/`zip`, `country`. Component fields override anything parsed from a freeform `address`. |
| `defaultCountry` | string | — | ISO code (`US`, `CA`, `GB`) applied to rows whose country can't be inferred. Default: Auto. |
| `maxAddresses` | integer | — | Hard cap on rows processed this run (0 = no cap). A cost guard alongside the run's max-charge limit. |

```json
{
  "addresses": [
    "1600 amphitheatre pkwy, mountain view, ca 94043",
    { "street": "1 infinite loop", "city": "cupertino", "state": "california", "zip": "95014" },
    "221B baker street, london, NW1 6XE, uk"
  ],
  "defaultCountry": ""
}
```

### Output

Each input row produces one dataset record. You can download the dataset in various formats such as JSON, HTML, CSV, or Excel.

```json
{
  "input": "1600 amphitheatre pkwy, mountain view, ca 94043",
  "country": "US",
  "status": "corrected",
  "normalized": "1600 Amphitheatre Pkwy, Mountain View, CA 94043",
  "components": {
    "house_number": "1600",
    "street": "Amphitheatre Pkwy",
    "unit": null,
    "city": "Mountain View",
    "region": "CA",
    "postcode": "94043",
    "country_code": "US"
  },
  "issues": [],
  "corrections": ["standardized city 'mountain view' -> 'Mountain View'"],
  "confidence": 0.95,
  "charged": true
}
```

A row that's structurally incomplete is flagged rather than silently "fixed":

```json
{
  "input": "742 evergreen terrace, springfield, or",
  "status": "needs_review",
  "normalized": "742 Evergreen Ter, Springfield, OR",
  "issues": [{ "code": "missing_postcode", "message": "Postal/ZIP code is missing." }],
  "confidence": 0.71,
  "charged": true
}
```

#### Data table

| Field | Description |
|-------|-------------|
| `input` | Original address as submitted. |
| `country` | Resolved ISO country code (`US`, `CA`, `GB`). |
| `status` | `valid`, `corrected`, `needs_review`, `unparseable`, or `empty`. |
| `normalized` | Standardized single-line address. |
| `components` | Parsed parts: house number, street, unit, city, region, postcode, country code. |
| `issues` | Structural problems found (`{code, message}`). |
| `corrections` | Normalization changes applied. |
| `confidence` | Heuristic 0–1 confidence in the parse. |
| `charged` | Whether the row was billed (empty/unparseable rows are **not** billed). |

### How much does it cost to validate addresses?

Pricing is **pay-per-address**: you're charged one event per address that produces usable output. **Empty and unparseable rows are never charged**, and you can set a **Max addresses** cap and the platform's max-charge limit as hard cost guards. Validating 10,000 addresses costs about the price of a coffee — far less than per-lookup commercial APIs when you only need parsing, standardization and structural validation. See the **Pricing** tab for the current per-address rate.

### Tips & advanced options

- **Send structured fields when you have them.** If your data already has `city`/`state`/`zip` columns, pass them as object fields — parsing is more reliable than from a single freeform string.
- **Set `defaultCountry`** for single-country lists so ambiguous rows resolve correctly.
- **Filter by `status`** downstream: keep `valid`/`corrected`, route `needs_review` to a human, drop `empty`/`unparseable`.
- **Cap costs** with `maxAddresses` when testing.

### FAQ, disclaimers & support

- **Does it verify an address is real/deliverable?** No — it validates *format and structure* and standardizes the address. Deliverability/existence checks need a live postal database (e.g. USPS / Royal Mail) and are out of scope. Use this to clean and structure data *before* such a check.
- **Which countries are supported?** Tailored rules for **US, Canada and the UK**, plus a generic best-effort fallback for other countries (casing/whitespace normalization and component splitting).
- **Do I need an API key or account with a third party?** No. The Actor is fully self-contained and makes no external calls.
- **Data privacy.** Only submit address data you're authorized to process. The Actor does not scrape or enrich from third-party sources; it only transforms the input you provide.
- **Feedback, bugs, or a country you need?** Open an issue on the **Issues** tab — custom rules and additional countries can be added.

# Actor input Schema

## `addresses` (type: `array`):

The addresses to validate and normalize. Each item is either a freeform string (e.g. "1600 amphitheatre pkwy, mountain view ca 94043") OR an object with any of these fields: address, house\_number, street, unit, city, state/region, postcode/zip, country. Component fields override anything parsed from a freeform 'address'.

## `defaultCountry` (type: `string`):

ISO country code applied to rows that don't declare their own country and whose country can't be inferred. Leave as Auto to infer per row.

## `maxAddresses` (type: `integer`):

Optional hard cap on how many addresses to process this run (0 or empty = no cap). Useful as a cost guard alongside the run's max-charge limit.

## Actor input object example

```json
{
  "addresses": [
    "221B baker street, london, NW1 6XE, uk"
  ],
  "defaultCountry": ""
}
```

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "addresses": [
        "1600 amphitheatre pkwy, mountain view, ca 94043",
        "350 Fifth Avenue, Apt 21, New York, New York 10118",
        {
            "street": "1 infinite loop",
            "city": "cupertino",
            "state": "california",
            "zip": "95014"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nibble/address-validation-normalizer").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "addresses": [
        "1600 amphitheatre pkwy, mountain view, ca 94043",
        "350 Fifth Avenue, Apt 21, New York, New York 10118",
        {
            "street": "1 infinite loop",
            "city": "cupertino",
            "state": "california",
            "zip": "95014",
        },
    ] }

# Run the Actor and wait for it to finish
run = client.actor("nibble/address-validation-normalizer").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "addresses": [
    "1600 amphitheatre pkwy, mountain view, ca 94043",
    "350 Fifth Avenue, Apt 21, New York, New York 10118",
    {
      "street": "1 infinite loop",
      "city": "cupertino",
      "state": "california",
      "zip": "95014"
    }
  ]
}' |
apify call nibble/address-validation-normalizer --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nibble/address-validation-normalizer",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/kM0gZWnT2fbw6Njap/builds/BnWGcTQjEqYfJucYp/openapi.json
