# Address Validation API - USPS ZIP+4 and 240 Countries (`nabeelbaghoor/address-validation-api`) Actor

Validate and standardize postal addresses against USPS and international postal authority data. Returns the corrected delivery line, ZIP+4, DPV deliverability codes, county, time zone and rooftop latitude and longitude. One row per verified candidate, in over 240 countries.

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

## Pricing

$8.00 / 1,000 address checkeds

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/actors/running/actors-in-store.md#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 API - USPS ZIP+4 and 240 Countries

Validate, correct and standardize any postal address against USPS and international postal authority data, and get back the deliverable version with ZIP+4, DPV deliverability codes and rooftop coordinates.

### What it does

- **Verifies US addresses against USPS data.** Returns the standardized delivery line, the ZIP+4 add-on, the 12 digit delivery point barcode and the DPV match code that says whether mail is actually deliverable there.
- **Verifies international addresses in over 240 countries.** Returns the address formatted the way that country's postal authority writes it, either in the local script or transliterated to Latin characters.
- **Separates "wrong" from "does not exist".** DPV footnotes distinguish a missing apartment number from a building that is vacant, a commercial mail receiving agency, or a street that has no such house number.
- **Geocodes while it verifies.** Every US result carries latitude, longitude and a precision level from ZIP centroid up to rooftop, so a single call replaces a verification step and a geocoding step.
- **Returns residential or commercial.** The RDI flag is what shipping rate calculators need in order to apply residential surcharges correctly.
- **Adds county, carrier route, congressional district and time zone.** The metadata that tax lookup, territory assignment and delivery window logic are usually missing.
- **Explains every correction.** Turn on component analysis and each part of the address reports whether it was confirmed, changed, added or missing.
- **Accepts messy input.** A single line string, a spreadsheet row with a `zip` column, or the provider's own field names all work. Everyday field names are rewritten for you.
- **Never loses a row.** An address that cannot be verified still produces a row saying so, so the output lines up with the input.

### Input

Paste a list of addresses and your own credentials. Everything else has a working default.

```json
{
  "scope": "us",
  "addresses": [
    { "street": "1600 Amphitheatre Pkwy", "city": "Mountain View", "state": "CA" },
    { "street": "210 King St", "zipcode": "94107" },
    "1 Infinite Loop, Cupertino CA 95014"
  ],
  "match": "strict",
  "candidates": 1,
  "features": ["component-analysis"],
  "maxResults": 100
}
```

For addresses outside the United States, set `scope` to `international` and give every address a `country`.

```json
{
  "scope": "international",
  "country": "GBR",
  "addresses": [
    { "address1": "10 Downing St", "locality": "London", "postal_code": "SW1A 2AA" }
  ],
  "geocode": true
}
```

### Example output

One row per verified candidate.

```json
{
  "scope": "us",
  "verified": true,
  "inputIndex": 1,
  "inputSummary": "210 King St, 94107",
  "deliveryLine1": "210 KING ST",
  "lastLine": "SAN FRANCISCO CA 94107-1702",
  "deliveryPointBarcode": "941071702108",
  "primaryNumber": "210",
  "streetName": "KING",
  "streetSuffix": "ST",
  "cityName": "SAN FRANCISCO",
  "stateAbbreviation": "CA",
  "zipcode": "94107",
  "plus4Code": "1702",
  "recordType": "S",
  "zipType": "Standard",
  "countyName": "San Francisco",
  "countyFips": "06075",
  "carrierRoute": "C032",
  "congressionalDistrict": "11",
  "rdi": "Commercial",
  "latitude": 37.77597,
  "longitude": -122.39295,
  "precision": "Zip9",
  "timeZone": "Pacific",
  "utcOffset": -8,
  "dpvMatchCode": "Y",
  "dpvFootnotes": "AABB",
  "dpvCmra": "N",
  "dpvVacant": "N",
  "footnotes": "N#"
}
```

### Frequently asked questions

#### What is an address verification API?

An address verification API takes an address as a person typed it and checks it against the authoritative postal database for that country. It returns the corrected, standardized form of the address, a flag saying whether mail can actually be delivered there, and the reason when it cannot. In the United States that authority is the USPS, and the specific check is called Delivery Point Validation.

#### What does the DPV match code mean?

The DPV match code is the USPS verdict on deliverability. `Y` means every part of the address, including the apartment or suite, was confirmed as a real delivery point. `S` means the street address is real but the secondary unit number is not, so mail may not reach the intended person. `D` means the street address is real but a required apartment number is missing entirely. `N` means the address was not confirmed. Anything other than `Y` is worth acting on before you post to it.

#### Can it verify addresses outside the United States?

Yes. Set the coverage option to international and the actor calls the provider's international service, which covers more than 240 countries and territories. Every international address must carry a country, given as a name or an ISO code such as GBR, DEU or JPN. The international service returns a verification status, an address precision level, and the address formatted the way that country's postal authority writes it.

#### Does it return latitude and longitude?

Yes. Every US result includes latitude, longitude and a precision level that tells you what the coordinates actually describe, from a ZIP code centroid up to a rooftop point on the building. For international addresses coordinates are an extra entitlement on most plans, so they are off by default and are turned on with the geocode option.

#### How do I tell a residential address from a business address?

The RDI field on every US result reports Residential or Commercial. This is the field shipping calculators need, because most carriers charge a residential delivery surcharge and quoting without it produces rates that are wrong at invoice time.

#### What is ZIP+4 and why does it matter?

ZIP+4 is the five digit ZIP code plus a four digit add-on that narrows delivery down to roughly one side of one city block, a single building, or a single floor. Presorted postage discounts require it, and it is the difference between a mailing that qualifies for bulk rates and one that does not.

#### Do I need my own API key?

Yes. This actor is bring your own key: it calls the address verification API using your own account's auth ID and auth token, so you keep your own plan, your own rate limits and your own data agreement. Use a secret key pair rather than an embedded key, because embedded keys are locked to a website host and will not authenticate from a server.

#### What happens to an address that cannot be verified?

It is still written to the dataset, with `verified` set to false and a note explaining that the provider found no matching address. That is deliberate: for most people the whole point of running a check is finding the bad rows. Set `skipUnverified` to true if you only want the deliverable ones.

#### How much does a run cost?

Charging is per row. Every address the provider answered is charged, including addresses confirmed not to exist, because the provider bills that lookup either way. Addresses this actor refuses before sending, such as a row with no street line, are never charged. Set `maxResults` to cap what a run can spend.

#### Can one address return more than one result?

Yes. Raise `candidates` above one and an ambiguous input, such as a street name with no house number or an address that exists in two ZIP codes, returns every possibility rather than nothing. Each candidate is its own row and is charged as its own row.

### Keyword map

address verification API, address validation API, USPS address verification, address standardization API, ZIP+4 lookup API, DPV delivery point validation, CASS address checking, international address verification, global address validation, address autocomplete data, residential delivery indicator, RDI lookup, address geocoding API, rooftop geocoding, county FIPS lookup, carrier route lookup, congressional district by address, bulk address cleaning, mailing list hygiene, deliverability checking

# Actor input Schema

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

One object per address, using this provider's own field names. For the US service those are street, street2, secondary, city, state, zipcode, lastline, addressee and urbanization. For the international service they are address1 to address4, locality, administrative\_area, postal\_code, organization and a required country. Everyday names are accepted too and rewritten for you, so line1, zip, town, province, company and postcode all work. A plain string is treated as a single line address. Add input\_id to carry your own reference onto the row.

## `scope` (type: `string`):

Which of the provider's two services to call. The US service checks against USPS data and returns ZIP+4 and DPV deliverability. The international service covers over 240 other countries and requires a country on every address. The two take different field names, so pick the one that matches your list.

## `authId` (type: `string`):

Your own account's auth ID for this provider. Bring your own credentials: nothing is shared between runs and the credentials are never written to the dataset. Use a secret key pair rather than an embedded key, because an embedded key is bound to a website host and will not authenticate from a server.

## `authToken` (type: `string`):

Your own account's auth token for this provider, the secret half of the pair. It is sent with every request and is never stored on the run.

## `match` (type: `string`):

How hard the US service tries to match. Strict returns only addresses it can confirm. Invalid also returns addresses it could not confirm, with the components it did parse. Enhanced searches an extended dataset and finds addresses strict will not, and is billed differently on most plans. Ignored by the international service.

## `candidates` (type: `integer`):

How many matching addresses the US service may return for one input, up to ten. Above one this is how an ambiguous address, such as a street with no house number, returns every possibility instead of nothing. Each candidate is a row and is charged as a row.

## `countySource` (type: `string`):

Which county to report for a US address. Postal gives the county the mail is delivered from, which is the default and is what most billing and tax lookups expect. Geographic gives the county the building physically sits in, and the provider only returns it when the match strategy is enhanced.

## `features` (type: `array`):

Optional field groups the provider adds to the response when asked. Component analysis reports, per component, whether it was confirmed, changed or missing, which is what you want when you need to explain a correction. IANA time zone adds the standard time zone identifier rather than the provider's own name.

## `geocode` (type: `boolean`):

Ask the international service for latitude and longitude. It is a separate entitlement on most plans and is billed on top of the verification, so it is off by default. The US service always returns coordinates and ignores this.

## `language` (type: `string`):

Whether the international service returns the address in its own script or transliterated into Latin characters. Native keeps the local script, for example Cyrillic or Kanji. Latin is what you want if the result has to go into a system that cannot store the local script.

## `country` (type: `string`):

A country applied to every international address that does not name its own, given as a name or an ISO code such as GBR, DEU or JPN. The international service refuses an address with no country, so setting this here saves repeating it on every row.

## `skipUnverified` (type: `boolean`):

Leave addresses that did not verify out of the dataset entirely. Off by default, because knowing that an address does not exist is usually the reason for running a check at all. They are charged either way, because the provider bills the lookup.

## `baseUrl` (type: `string`):

Overrides the host outright. Leave empty unless your account was issued a dedicated hostname or you run this provider's software on your own network, in which case the coverage setting no longer picks the host.

## `maxResults` (type: `integer`):

Stop after this many rows. Rows are charged individually, so this is the ceiling on what a run can cost.

## `requestsPerMinute` (type: `integer`):

How fast to call the provider. Lower this if your plan has a tighter rate ceiling than the default.

## Actor input object example

```json
{
  "addresses": [
    {
      "street": "1600 Amphitheatre Pkwy",
      "city": "Mountain View",
      "state": "CA"
    },
    {
      "street": "210 King St",
      "zipcode": "94107"
    }
  ],
  "scope": "us",
  "match": "strict",
  "candidates": 1,
  "countySource": "postal",
  "features": [],
  "geocode": false,
  "language": "native",
  "skipUnverified": false,
  "maxResults": 100,
  "requestsPerMinute": 120
}
```

# Actor output Schema

## `addresses` (type: `string`):

One row per verified address candidate, alongside the input it was matched from.

# 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": [
        {
            "street": "1600 Amphitheatre Pkwy",
            "city": "Mountain View",
            "state": "CA"
        },
        {
            "street": "210 King St",
            "zipcode": "94107"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("nabeelbaghoor/address-validation-api").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": [
        {
            "street": "1600 Amphitheatre Pkwy",
            "city": "Mountain View",
            "state": "CA",
        },
        {
            "street": "210 King St",
            "zipcode": "94107",
        },
    ] }

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

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).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": [
    {
      "street": "1600 Amphitheatre Pkwy",
      "city": "Mountain View",
      "state": "CA"
    },
    {
      "street": "210 King St",
      "zipcode": "94107"
    }
  ]
}' |
apify call nabeelbaghoor/address-validation-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nabeelbaghoor/address-validation-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/WrXR4v0nxvW2I8KeN/builds/lJ1GlghjD74OIGPcR/openapi.json
