# ZIP Codes API — notes for AI agents using a person's credits

Best practices for an agent calling https://api.zip-codes.com on someone's behalf. The overview is
https://api.zip-codes.com/llms.txt; the complete reference is https://api.zip-codes.com/llms-full.txt.
Plans, packs, limits and formulas as JSON: https://api.zip-codes.com/pricing.json. Updated 2026-10-03.

## Before spending credits

1. **Try the demo key first.** `zc_test_DEMOAPIKEY000000000000` answers the demo ZIPs, postal codes and
   addresses listed in llms-full.txt, at 5 requests/minute per IP, with no account. Use it to confirm the
   response shape before using the person's own key.
2. **Know the cost of a call before making it.** Every response reports `meta.credits` (`used`, `remaining`,
   `breakdown`), so the cost of one call tells you the cost of a thousand. Formulas:
   - `/v2/zip`: 1 + one per billable enrichment flag + reverse_geocode (a coordinate input).
   - `/v2/quick-zip`: base × (1 + timezone + reverse_geocode); base 2 for ZIP+4, otherwise 1.
   - `/v2/address`: 1 + coordinates (if requested) + each delivered boundary flag + each delivered tract ACS tag.
     A no-match costs 1 (+1 for coordinates).
   - `/v2/radius`: distance-band base × (1 + timezone/ACS requests + auto_radius).
   - `/v2/distance`: 1 per pair. `/v2/suggest`: 1, 2, 3 or 5 by limit band (≤15, 50, 150, 500).
3. **Worked examples** (measured 2026-10-03):

   | Call | Credits |
   |---|---|
   | `/v2/zip?code=90210&include=census,cd,state_leg,school_district` | 5 |
   | `/v2/zip?code=90210&include=census,cd,state_leg,school_district,acs_demographic,acs_demographic_2022` | 7 |
   | `/v2/address` with `coordinates,census,cd,state_leg,school_district,acs_tract_demographic` | 7 |
   | `/v2/radius?code=90210&max=5&include=acs_demographic` | 2 |
   | `/v2/zip?code=34.0901,-118.4065` (coordinate → ZIP+4) | 2 |

4. **Tell the person the expected cost before a batch or a recurring job**, and how much of their daily
   allowance it uses (free accounts: 2,500 credits/day, 60 requests/minute).

## Choosing the cheapest way to pay

Prices as of 2026-10-03; https://api.zip-codes.com/pricing.json is the live source.

- **Credit packs** are one-time purchases that **never expire** and **stack on top of the free daily allowance**:
  Starter 25,000 credits $19 · Standard 65,000 $49 · Growth 150,000 $99 · Pro 300,000 $179 · Enterprise 2,000,000 $799.
- **Subscriptions** are monthly: Developer 100,000 credits $49 · Professional 350,000 $149 · Business 1,500,000 $499.
  A subscription **replaces** the free daily credits, and unlocks batch and higher rate limits.
- **Spending order:** the free daily credits first (free accounts), then subscription credits, then purchased packs.
- **Worked example:** a ZIP lookup with timezone costs 2 credits. At 50,000 lookups a month that is 100,000 credits.
  The free allowance covers about 75,000 (2,500 a day), and one Starter pack ($19) covers the other 25,000, which is
  cheaper than the $49 Developer subscription. A subscription wins once the person needs batch, higher rate limits, or
  steady volume well above the free allowance.

## Batches

5. Batch routes need a paid plan. Each item is charged, **duplicates included**: dedupe inputs first.
6. Maximum 100 items per batch (250 for `/v2/address/batch`). Spatial radius is not available in batch.

## What is free, and should not be retried

7. Unknown flags, enrichments that are unavailable for the input (for example ACS for a Canadian code) and ACS
   years Census did not publish are **not charged**. They come back as notices in `meta.notices` or as
   `published: false`. Retrying returns the same answer; it is not an error to fix.

## Errors and limits

8. Every error carries a `code`, a `message` and a `url` with the next step; `retryable` says whether to try
   again where it is known. Retry only retryable errors, with backoff.
9. Rate limits are per minute (Free 60; Developer and Professional 300; Business 600; Enterprise 1800).
   On 429, wait for the window rather than retrying in a loop.
10. Lookup not-found is HTTP 200 with a per-item `success: false`; a single-address no-match is a top-level
    `success: false`. Neither is a transport failure.

## Getting it right first time

11. The radius parameter is `max` (miles), not `radius`.
12. Send the key in the `X-Api-Key` header; `Authorization: Bearer` is not accepted.
13. For the current ACS year, use the unsuffixed flag (`acs_economic`) rather than hardcoding a year.
14. `/v2/address`: with a ZIP, city and state are optional; without a ZIP, give the city and state.

## Contact

Bugs, feature requests, apps built on the API (apps and tools we feature get 100,000 credits) and research credits:
jharris@zip-codes.com. Including the `request_id` from the response helps.
