# USPS API

> USPS provides package tracking, ZIP code details, and postage estimates as a workflow and API.

USPS returns package status and delivery details from a tracking number. Get zip code standardizes a US street address; Get city for zip finds city details from a ZIP Code. Estimate postage compares domestic retail options using ZIP Codes, weight, package shape, and mailing date.

- Page: https://fous.com/workflows/usps
- Handle: `@usps`
- Category: [Logistics](https://fous.com/workflows/category/logistics)
- Source website: https://usps.com
- Last verified: Sep 29, 2026
- Fous is not affiliated with USPS.

## Methods

### Estimate postage

Operation `estimate_postage`, version 1. 1 credit per call.

Estimate domestic USPS Post Office retail postage by ZIP Codes, weight, shape, and mailing date. Shows available ordinary services or flat-rate packaging options; a zero-pound letter with no extra ounces is treated as a one-ounce letter. Media Mail is excluded because eligibility depends on contents. Delivery dates are estimates, and prices exclude optional paid extras.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `width_in` | number | no |  | Package width in inches, for example 6; defaults to a small box. |
| `height_in` | number | no |  | Package height in inches, for example 4; defaults to a small box. |
| `length_in` | number | no |  | Package length in inches, for example 8; defaults to a small box. |
| `ship_date` | string | no |  | Planned mailing date, for example 2026-10-01; defaults to today. |
| `weight_lb` | number | yes | `0` | Weight in pounds, for example 2; enter 0 for a letter under a pound. |
| `weight_oz` | number | no | `1` | Additional ounces beyond the whole pounds, for example 8. |
| `origin_zip` | string | yes | `"10001"` | Five-digit ZIP Code where the item is mailed, for example 10001. |
| `package_type` | string | no | `"letter"` | Mailpiece or USPS flat-rate packaging type, for example package. |
| `destination_zip` | string | yes | `"94105"` | Five-digit destination ZIP Code, for example 94105. |

**Input schema**

```json
{
  "type": "object",
  "required": [
    "origin_zip",
    "destination_zip",
    "weight_lb"
  ],
  "properties": {
    "width_in": {
      "type": "number",
      "default": 6,
      "description": "Package width in inches, for example 6; defaults to a small box.",
      "exclusiveMinimum": 0
    },
    "height_in": {
      "type": "number",
      "default": 4,
      "description": "Package height in inches, for example 4; defaults to a small box.",
      "exclusiveMinimum": 0
    },
    "length_in": {
      "type": "number",
      "default": 8,
      "description": "Package length in inches, for example 8; defaults to a small box.",
      "exclusiveMinimum": 0
    },
    "ship_date": {
      "type": "string",
      "format": "date",
      "description": "Planned mailing date, for example 2026-10-01; defaults to today."
    },
    "weight_lb": {
      "type": "number",
      "minimum": 0,
      "description": "Weight in pounds, for example 2; enter 0 for a letter under a pound.",
      "examples": [
        0,
        2
      ]
    },
    "weight_oz": {
      "type": "number",
      "default": 0,
      "minimum": 0,
      "description": "Additional ounces beyond the whole pounds, for example 8.",
      "examples": [
        1
      ]
    },
    "origin_zip": {
      "type": "string",
      "title": "From ZIP",
      "pattern": "^[0-9]{5}$",
      "description": "Five-digit ZIP Code where the item is mailed, for example 10001.",
      "examples": [
        "10001",
        "60601"
      ]
    },
    "package_type": {
      "enum": [
        "letter",
        "large_envelope",
        "package",
        "flat_rate_envelope",
        "flat_rate_box"
      ],
      "type": "string",
      "default": "package",
      "description": "Mailpiece or USPS flat-rate packaging type, for example package.",
      "examples": [
        "letter",
        "flat_rate_box"
      ]
    },
    "destination_zip": {
      "type": "string",
      "title": "To ZIP",
      "pattern": "^[0-9]{5}$",
      "description": "Five-digit destination ZIP Code, for example 94105.",
      "examples": [
        "94105",
        "90001"
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "weight_lb": 0,
      "weight_oz": 1,
      "origin_zip": "10001",
      "package_type": "letter",
      "destination_zip": "94105"
    },
    {
      "weight_lb": 2,
      "origin_zip": "10001",
      "destination_zip": "94105"
    },
    {
      "weight_lb": 2,
      "origin_zip": "60601",
      "package_type": "flat_rate_box",
      "destination_zip": "90001"
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `note` | string or null |  |  |
| `services` | array |  | Available retail postage options, cheapest first. |
| `services[].currency` | string | `"USD"` |  |
| `services[].page_link` | string | `"https://postcalc.usps.com/Calculator/ExtraServices?country=0&ccode=US&oz=10001&omil=False&dz=94105&dmil=False&retail=Fa` |  |
| `services[].retail_price` | number | `0.82` |  |
| `services[].service_name` | string | `"First-Class Mail Stamped Letter"` |  |
| `services[].included_extras` | array |  |  |
| `services[].expected_delivery_date` | string or null | `"2026-10-03"` |  |
| `services[].estimated_delivery_time` | string or null | `"Sat, Oct 3"` |  |

**Example input**

```json
{
  "weight_lb": 0,
  "weight_oz": 1,
  "origin_zip": "10001",
  "package_type": "letter",
  "destination_zip": "94105"
}
```

**Example output**

```json
{
  "note": null,
  "services": [
    {
      "currency": "USD",
      "page_link": "https://postcalc.usps.com/Calculator/ExtraServices?country=0&ccode=US&oz=10001&omil=False&dz=94105&dmil=False&retail=False&mdt=9/28/2026&mdz=8:00 AM&m=1&hscode=False&p=0&o=1&rect=True&l=0&h=0&w=0&g=0&…",
      "retail_price": 0.82,
      "service_name": "First-Class Mail Stamped Letter",
      "included_extras": [],
      "expected_delivery_date": "2026-10-03",
      "estimated_delivery_time": "Sat, Oct 3"
    },
    {
      "currency": "USD",
      "page_link": "https://postcalc.usps.com/Calculator/ExtraServices?country=0&ccode=US&oz=10001&omil=False&dz=94105&dmil=False&retail=False&mdt=9/28/2026&mdz=8:00 AM&m=1&hscode=False&p=0&o=1&rect=True&l=0&h=0&w=0&g=0&…",
      "retail_price": 16.95,
      "service_name": "Priority Mail",
      "included_extras": [
        "USPS Tracking",
        "Insurance up to $100"
      ],
      "expected_delivery_date": "2026-10-01",
      "estimated_delivery_time": "Thu, Oct 1"
    },
    {
      "currency": "USD",
      "page_link": "https://postcalc.usps.com/Calculator/ExtraServices?country=0&ccode=US&oz=10001&omil=False&dz=94105&dmil=False&retail=False&mdt=9/28/2026&mdz=8:00 AM&m=1&hscode=False&p=0&o=1&rect=True&l=0&h=0&w=0&g=0&…",
      "retail_price": 53.35,
      "service_name": "Priority Mail Express",
      "included_extras": [
        "USPS Tracking",
        "Insurance up to $100"
      ],
      "expected_delivery_date": "2026-09-29",
      "estimated_delivery_time": "Tue, Sep 29 by 6:00 PM"
    }
  ]
}
```

### Get city for zip

Operation `get_city_for_zip`, version 1. 1 credit per call.

Find the USPS recommended city and state, other recognized city names, names to avoid, and ZIP type for a five-digit US ZIP Code. ZIP+4 is reduced to its first five digits.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `zip_code` | string | yes | `"90210-1234"` | Five-digit ZIP Code or ZIP+4, for example 10001 or 10001-1234. |

**Input schema**

```json
{
  "type": "object",
  "required": [
    "zip_code"
  ],
  "properties": {
    "zip_code": {
      "type": "string",
      "description": "Five-digit ZIP Code or ZIP+4, for example 10001 or 10001-1234.",
      "examples": [
        "90210-1234",
        "10001",
        "22102"
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "zip_code": "90210-1234"
    },
    {
      "zip_code": "10001"
    },
    {
      "zip_code": "22102"
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `page_url` | string | `"https://tools.usps.com/zip-code-lookup.htm?citybyzipcode"` | USPS Cities by ZIP Code page. |
| `zip_code` | string | `"90210"` | The five-digit ZIP Code. |
| `zip_type` | string or null | `"Standard"` | ZIP classification when provided, such as PO Box only or Military. |
| `state_code` | string | `"CA"` | Two-letter state or territory abbreviation. |
| `state_name` | string | `"California"` | Full state or territory name. |
| `cities_to_avoid` | array |  | City names USPS says to avoid for this ZIP Code. |
| `recommended_city` | string | `"BEVERLY HILLS"` | USPS recommended city name. |
| `other_accepted_cities` | array |  | Other city names USPS recognizes for addresses in this ZIP Code. |

**Example input**

```json
{
  "zip_code": "90210-1234"
}
```

**Example output**

```json
{
  "page_url": "https://tools.usps.com/zip-code-lookup.htm?citybyzipcode",
  "zip_code": "90210",
  "zip_type": "Standard",
  "state_code": "CA",
  "state_name": "California",
  "cities_to_avoid": [],
  "recommended_city": "BEVERLY HILLS",
  "other_accepted_cities": []
}
```

### Get zip code

Operation `get_zip_code`, version 1. 1 credit per call.

Standardize a US street address with USPS and find its ZIP+4. When several addresses match, the main address is the first result and all choices appear in matches. A ZIP Code result does not confirm who lives at an address.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `city` | string | yes | `"Washington"` | City name, such as Washington. |
| `state` | string | yes | `"DC"` | State name or two-letter code, such as District of Columbia or DC. |
| `zip_code` | string | no | `"10118"` | ZIP Code if known, such as 20500. |
| `street_address` | string | yes | `"1600 Pennsylvania Ave NW"` | Street number and name, such as 1600 Pennsylvania Ave NW. |
| `apartment_or_suite` | string | no | `"Ste 4750"` | Unit or suite, such as Apt 4B. |

**Input schema**

```json
{
  "type": "object",
  "required": [
    "street_address",
    "city",
    "state"
  ],
  "properties": {
    "city": {
      "type": "string",
      "description": "City name, such as Washington.",
      "examples": [
        "Washington",
        "New York"
      ]
    },
    "state": {
      "type": "string",
      "description": "State name or two-letter code, such as District of Columbia or DC.",
      "examples": [
        "DC",
        "New York",
        "NY"
      ]
    },
    "zip_code": {
      "type": "string",
      "default": "",
      "description": "ZIP Code if known, such as 20500.",
      "examples": [
        "10118"
      ]
    },
    "street_address": {
      "type": "string",
      "description": "Street number and name, such as 1600 Pennsylvania Ave NW.",
      "examples": [
        "1600 Pennsylvania Ave NW",
        "350 5th Ave",
        "99999 Madeup Street"
      ]
    },
    "apartment_or_suite": {
      "type": "string",
      "default": "",
      "description": "Unit or suite, such as Apt 4B.",
      "examples": [
        "Ste 4750"
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "city": "Washington",
      "state": "DC",
      "street_address": "1600 Pennsylvania Ave NW"
    },
    {
      "city": "New York",
      "state": "New York",
      "street_address": "350 5th Ave"
    },
    {
      "city": "Washington",
      "state": "DC",
      "street_address": "99999 Madeup Street"
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `city` | string or null | `"WASHINGTON"` | USPS-formatted city. |
| `note` | string or null | `"Check the street number, street name, city, state, ZIP Code, and apartment or suite if applicable."` | What to check when no address is recognized. |
| `state` | string or null | `"DC"` | Two-letter USPS state abbreviation. |
| `county` | string or null | `"DISTRICT OF COLUMBIA"` | USPS county name. |
| `matches` | array |  | All USPS address choices when multiple results are found; otherwise empty. |
| `matches[].city` | string or null |  | USPS-formatted city. |
| `matches[].state` | string or null |  | Two-letter USPS state abbreviation. |
| `matches[].county` | string or null |  | USPS county name. |
| `matches[].page_url` | string |  | USPS lookup page for this address. |
| `matches[].zip_code` | string or null |  | Five-digit ZIP Code. |
| `matches[].zip_plus_4` | string or null |  | Nine-digit ZIP+4 in five-plus-four format. |
| `matches[].street_line` | string or null |  | USPS-formatted street address, including unit when present. |
| `matches[].carrier_route` | string or null |  | USPS mail carrier route. |
| `matches[].delivery_point` | string or null |  | USPS delivery point code. |
| `page_url` | string | `"https://tools.usps.com/zip-code-lookup.htm?byaddress"` | USPS lookup page for this address. |
| `zip_code` | string or null | `"20500"` | Five-digit ZIP Code. |
| `recognized` | string | `"yes"` | Whether USPS returned an address match. |
| `zip_plus_4` | string or null | `"20500-0005"` | Nine-digit ZIP+4 in five-plus-four format. |
| `street_line` | string or null | `"1600 PENNSYLVANIA AVE NW"` | USPS-formatted street address, including unit when present. |
| `carrier_route` | string or null | `"C000"` | USPS mail carrier route. |
| `delivery_point` | string or null | `"00"` | USPS delivery point code. |

**Example input**

```json
{
  "city": "Washington",
  "state": "DC",
  "street_address": "1600 Pennsylvania Ave NW"
}
```

**Example output**

```json
{
  "city": "WASHINGTON",
  "note": null,
  "state": "DC",
  "county": "DISTRICT OF COLUMBIA",
  "matches": [],
  "page_url": "https://tools.usps.com/zip-code-lookup.htm?byaddress",
  "zip_code": "20500",
  "recognized": "yes",
  "zip_plus_4": "20500-0005",
  "street_line": "1600 PENNSYLVANIA AVE NW",
  "carrier_route": "C000",
  "delivery_point": "00"
}
```

### Track package

Operation `track_package`, version 1. 1 credit per call.

Track a USPS package or letter by its tracking number. Returns the latest status, delivery details, and available tracking history; unavailable or ambiguous numbers may need additional details on USPS.

**Input**

| Field | Type | Required | Example | Description |
|---|---|---|---|---|
| `tracking_number` | string | yes | `"9489 0178 9820 3036 9522 01"` | Tracking number on the receipt or label, such as 9400 1000 0000 0000 0000 00 or EC123456789US. |

**Input schema**

```json
{
  "type": "object",
  "required": [
    "tracking_number"
  ],
  "properties": {
    "tracking_number": {
      "type": "string",
      "description": "Tracking number on the receipt or label, such as 9400 1000 0000 0000 0000 00 or EC123456789US.",
      "examples": [
        "9489 0178 9820 3036 9522 01",
        "9489017898203036952201"
      ]
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "tracking_number": "9489 0178 9820 3036 9522 01"
    },
    {
      "tracking_number": "9489017898203036952201"
    }
  ]
}
```

**Output**

| Field | Type | Example | Description |
|---|---|---|---|
| `events` | array |  |  |
| `events[].event` | string | `"Delivered, Left with Individual"` |  |
| `events[].location` | string or null | `"LAS VEGAS, NV 89119"` |  |
| `events[].date_time` | string or null | `"2026-01-31T14:21:00-08:00"` | Local date and time of the event, ISO 8601 with UTC offset when the location can be resolved. |
| `status` | string | `"Delivered, Left with Individual"` |  |
| `delivered_at` | string or null | `"2026-01-31T14:21:00-08:00"` |  |
| `mail_service` | string or null | `"First-Class Mail®"` |  |
| `last_location` | string or null | `"LAS VEGAS, NV 89119"` |  |
| `tracking_link` | string | `"https://tools.usps.com/go/TrackConfirmAction?tLabels=9489017898203036952201"` |  |
| `last_event_time` | string or null | `"2026-01-31T14:21:00-08:00"` |  |
| `tracking_number` | string | `"9489017898203036952201"` |  |
| `expected_delivery_date` | string or null |  |  |
| `expected_delivery_time_window` | string or null |  |  |

**Example input**

```json
{
  "tracking_number": "9489 0178 9820 3036 9522 01"
}
```

**Example output**

```json
{
  "events": [
    {
      "event": "Delivered, Left with Individual",
      "location": "LAS VEGAS, NV 89119",
      "date_time": "2026-01-31T14:21:00-08:00"
    },
    {
      "event": "Arrived at USPS Facility",
      "location": "LAS VEGAS NV DISTRIBUTION CENTER",
      "date_time": "2026-01-30T08:29:00-08:00"
    },
    {
      "event": "Arrived at USPS Facility",
      "location": "RENO NV DISTRIBUTION CENTER",
      "date_time": "2026-01-29T09:30:00-08:00"
    }
  ],
  "status": "Delivered, Left with Individual",
  "delivered_at": "2026-01-31T14:21:00-08:00",
  "mail_service": "First-Class Mail®",
  "last_location": "LAS VEGAS, NV 89119",
  "tracking_link": "https://tools.usps.com/go/TrackConfirmAction?tLabels=9489017898203036952201",
  "last_event_time": "2026-01-31T14:21:00-08:00",
  "tracking_number": "9489017898203036952201",
  "expected_delivery_date": null,
  "expected_delivery_time_window": null
}
```

## Quick start

Call the API with a Fous API key (`FOUS_API_KEY`). To create one, turn on Developer mode in Fous Studio, then open Keys & connections → API keys (https://app.fous.com/keys).

```bash
# First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
: "${FOUS_API_KEY:?Set FOUS_API_KEY before running this example}"

curl 'https://api.fous.com/v1/query' \
  --fail-with-body --silent --show-error --max-time 120 \
  -H "Authorization: Bearer $FOUS_API_KEY" \
  -H 'Content-Type: application/json' \
  --data-raw '{
  "api": "@usps",
  "visibility": "public",
  "operation": "estimate_postage",
  "version": 1,
  "input": {
    "weight_lb": 0,
    "weight_oz": 1,
    "origin_zip": "10001",
    "package_type": "letter",
    "destination_zip": "94105"
  },
  "response": {
    "format": "json"
  }
}'
```

```python
# Save as fous.py and run with python3 fous.py. No packages needed.
# First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
import json
import os
import urllib.error
import urllib.request

api_key = os.environ.get("FOUS_API_KEY")
if not api_key:
    raise RuntimeError("Set FOUS_API_KEY before running this example")

body = json.loads("{\n  \"api\": \"@usps\",\n  \"visibility\": \"public\",\n  \"operation\": \"estimate_postage\",\n  \"version\": 1,\n  \"input\": {\n    \"weight_lb\": 0,\n    \"weight_oz\": 1,\n    \"origin_zip\": \"10001\",\n    \"package_type\": \"letter\",\n    \"destination_zip\": \"94105\"\n  },\n  \"response\": {\n    \"format\": \"json\"\n  }\n}")
request = urllib.request.Request(
    "https://api.fous.com/v1/query",
    data=json.dumps(body).encode("utf-8"),
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
    },
    method="POST",
)
try:
    with urllib.request.urlopen(request, timeout=120) as response:
        result = json.load(response)
except urllib.error.HTTPError as error:
    raise RuntimeError(f"HTTP {error.code}: {error.read().decode('utf-8', errors='replace')}") from error
if result.get("success") is False:
    raise RuntimeError(result.get("error", {}).get("message", "Request failed"))
print(json.dumps(result["data"]["output"], indent=2))
```

```typescript
// Save as fous.mts and run with npx tsx fous.mts.
// First set your key: export FOUS_API_KEY='YOUR_FOUS_API_KEY'
const apiKey = process.env.FOUS_API_KEY;
if (!apiKey) throw new Error("Set FOUS_API_KEY before running this example");

const response = await fetch("https://api.fous.com/v1/query", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${apiKey}`,
    "Content-Type": "application/json",
  },
  signal: AbortSignal.timeout(120_000),
  body: JSON.stringify({
  "api": "@usps",
  "visibility": "public",
  "operation": "estimate_postage",
  "version": 1,
  "input": {
    "weight_lb": 0,
    "weight_oz": 1,
    "origin_zip": "10001",
    "package_type": "letter",
    "destination_zip": "94105"
  },
  "response": {
    "format": "json"
  }
}),
});
type ApiResult = { success: boolean; data?: { output: unknown }; error?: { message: string } };
const result: ApiResult = await response.json();
if (!response.ok || result.success === false) {
  throw new Error(result.error?.message ?? `HTTP ${response.status}`);
}
if (!result.data) throw new Error("Missing API response data");
console.log(result.data.output);
```

Or describe the data in plain language: send `{"api":"@usps","prompt":"Describe the data you need, with every detail"}` to the same URL. Fous fills in the input, runs the method that fits and returns only the fields you asked for; `data.route.calls[].request` is the exact call it made. Routing is free; the run costs the same.

## Use cases

- Check package status and delivery details using a tracking number.
- Standardize street addresses and find ZIP+4 codes.
- Find recommended and accepted city names for a ZIP Code.
- Compare domestic retail postage options by price and service.
- Estimate postage for a planned mailing date and package size.

## FAQ

### Is Fous affiliated with USPS?

No. Fous is not affiliated with USPS. This workflow reads the public usps.com website and returns its data.

### How much does it cost?

Each run costs 1 credit. With pay-as-you-go, a credit costs 1¢; monthly plans cost less per credit.

### Do I need a USPS account?

No. You only need a Fous account.

### How current is the data?

Fous gets the data from usps.com when you run it; repeating the same request within a day may return the saved result. Fous checks this workflow automatically; it last passed a check on Sep 29, 2026.

### What is the latest status of a package?

Track package returns the latest status, delivery details, and available tracking history for a tracking number.

### What ZIP+4 matches a US street address?

Get zip code standardizes the address and returns a ZIP+4; when several addresses match, it also returns the choices.

### What city and state does a ZIP Code use?

Get city for zip returns the USPS recommended city and state, other accepted city names, names to avoid, and ZIP type.

## Related

- [UPS API](https://fous.com/workflows/ups.md): UPS ships and delivers packages, provides available tracking status and history, and estimates guest retail prices and delivery times, with end-of-day shown as 23:59 local time and counter prices varying.
- [Zippopotam.us API](https://fous.com/workflows/zippopotam-us.md): Zippopotam.us returns places, regions and coordinates for postal codes in supported countries, and finds postal codes, places and coordinates by town and region.
- [US Census Bureau API](https://fous.com/workflows/us-census-bureau.md): US Census Bureau returns statistics from varying Census years, population estimates through July 1, and address geographies using Census vintages that may differ from representation.
- [FedEx API](https://fous.com/workflows/fedex.md): Shipping and package tracking.
- [Parcels API](https://fous.com/workflows/parcels.md): Worldwide package tracking with automatic carrier detection.
- [17TRACK API](https://fous.com/workflows/17track.md): Worldwide parcel tracking across multiple carriers.
- [DHL API](https://fous.com/workflows/dhl.md): Track DHL shipments across its delivery services.
- [India Post PIN Codes API](https://fous.com/workflows/india-post-pin-codes.md): India Post PIN Codes returns Indian six-digit PIN codes and matching post offices, with branch types, delivery status, postal areas, districts, and states.
- [All Logistics workflows](https://fous.com/workflows/category/logistics)
