Build with the CDXZipStream API
Every tool in the add-ins is a plain HTTPS/JSON endpoint you can call from any language. ZIP and postal lookup, distance and radius, Census demographics, geocoding, routing, and USPS address verification. One key header, no SDK required.
https://api.cdxzipstream.comThree views of the same reference
The reference is generated from the running service, so it is never out of date with the API you are calling.
Swagger UI
api.cdxzipstream.com/docsThe interactive reference. Click Authorize, paste your key, then use Try it out on any endpoint to run a real call from the browser with a pre-filled example body.
Open Swagger UIReDoc
api.cdxzipstream.com/redocThe same reference in a clean, readable three-column layout. No live calls, so it is the better one to read end to end or share with a colleague.
Open ReDocOpenAPI 3.1 spec
api.cdxzipstream.com/openapi.jsonThe machine-readable source of truth behind both views. Import it into Postman, Insomnia, Bruno, or Hoppscotch, or generate a typed client with openapi-generator.
View the specPostman, Insomnia, Bruno and codegen
Import https://api.cdxzipstream.com/openapi.json and your client builds the full collection with example requests automatically. Set base_url to https://api.cdxzipstream.com and api_key to your key, sent as X-API-Key on every request.
Quickstart
- 1. Create an account and activate a plan. The Free plan works to start.
- 2. Open Account, then API Keys and copy your
cdx_live_…key. - 3. Send it as
X-API-Keyon every/v1call. Keep it secret, it spends your credits.
curl
curl -s "https://api.cdxzipstream.com/v1/zip/80401" \
-H "X-API-Key: cdx_live_YOUR_KEY"Python
import requests
BASE = "https://api.cdxzipstream.com"
HEADERS = {"X-API-Key": "cdx_live_YOUR_KEY"}
# Single lookup
r = requests.get(f"{BASE}/v1/zip/80401", headers=HEADERS)
r.raise_for_status()
print(r.json())
# The X-Credits-* headers ride on the verify endpoints only.
# Anywhere else, read the balance from /v1/account, which is free to call.
print(requests.get(f"{BASE}/v1/account", headers=HEADERS).json())
# Distance between pairs
r = requests.post(
f"{BASE}/v1/distance",
headers=HEADERS,
json={"pairs": [["80401", "10001"], ["90210", "60601"]], "unit": "miles"},
)
print(r.json())JavaScript / TypeScript
const BASE = "https://api.cdxzipstream.com";
const headers = {
"X-API-Key": "cdx_live_YOUR_KEY",
"Content-Type": "application/json",
};
// Geocode a list of addresses
const res = await fetch(`${BASE}/v1/geocode`, {
method: "POST",
headers,
body: JSON.stringify({
addresses: ["1600 Pennsylvania Ave NW, Washington, DC 20500"],
}),
});
if (res.status === 402) throw new Error("Out of credits - top up your account");
if (!res.ok) throw new Error(`CDXZipStream ${res.status}`);
console.log(await res.json());
// Geocode returns no credit headers - read the balance from GET /v1/accountMixed bulk work
POST /v1/batch runs different operations over large lists in one round trip, which is cheaper on latency than looping single calls.
{
"operations": [
{ "op": "zip", "args": ["80401"] },
{ "op": "demographics", "args": ["10001"] },
{ "op": "distance", "args": ["80401", "10001"] }
]
}Endpoints at a glance
Full request and response schemas for each one are in the Swagger UI and ReDoc.
Lookup
| GET | /v1/zip/{zip_code} | City, county, state, lat/long and population for a US ZIP or international postal code |
| POST | /v1/zip/batch | The same lookup over a list of codes in one request |
| GET | /v1/demographics/{zip_code} | Census and ACS demographics: population, income, age, education, housing |
| POST | /v1/tract | Resolve a US Census Tract FIPS / GEOID |
Distance and proximity
| GET, POST | /v1/distance | Great-circle distance between pairs of codes, in miles or kilometres |
| POST | /v1/radius | Every ZIP within a radius of a center point. Priced by rows returned, so limit is the cost control |
| POST | /v1/closest | The N closest ZIPs to a point. Priced by rows returned, so n is the cost control |
| POST | /v1/closest-in-list | The closest entry from a caller-supplied list, for store and depot assignment |
| POST | /v1/find | Search ZIPs by city, county or state. Priced by rows returned, so limit is the cost control |
Geocoding
| POST | /v1/geocode | Addresses to latitude and longitude |
| POST | /v1/revgeocode | Coordinates back to an address |
| POST | /v1/staticmap-url | A signed static map image URL, single or multi-marker |
Routing
| POST | /v1/route | Driving distance and time between stops |
| POST | /v1/optimize | Multi-stop route optimization for delivery and field work. The method parameter, straight, here or aco, sets both the quality and the credit weight per stop |
Address verification
| GET, POST | /v1/verify | Validate and standardize a US address to USPS form with ZIP+4 and deliverability |
| POST | /v1/verify/batch | The same verification over a mailing list |
Bulk and account
| POST | /v1/batch | Mixed operations over large lists in a single request. Radius, closest and find are priced here exactly as on their own endpoints, and each returns its limit and a truncated flag per item |
| GET | /v1/pricing | The live rate card: credit cost per operation, rows_per_credit and the row-priced ops, plus tiers and per-call caps. Free to call |
| GET | /v1/account | Your plan, monthly grant remaining and top-up balance. Free to call |
| GET | /v1/health | Service health. Free to call |
Credits and metering
Billing is credit-based and pooled per account. Every key on an account draws from the same monthly grant plus prepaid top-up balance, so adding keys never adds capacity.
Per-item operations such as ZIP and distance cost one credit per item, address verification two, geocoding four, and routing three per pair — the operations that make a paid provider call are priced above the ones served locally. Radius, closest and find are priced by the rows they return, one credit per 25 rows with a minimum of one, so the limit you ask for is the cost control. Optimization costs stops times a method weight. GET /v1/pricing returns the live rate card and costs nothing to call, so read costs from there rather than hardcoding them.
The address verification endpoints carry the headers below, and X-Credits-Remaining is omitted on unlimited plans. Elsewhere, read the balance from GET /v1/account.
X-Credits-Charged: 2
X-Credits-Remaining: 8431Error codes
Failures are plain HTTP status codes with a JSON body explaining the cause. Refused calls are never performed and never charged.
| 401 | Missing, invalid or revoked key, or a suspended account |
| 402 | Out of credits. Both the monthly grant and the top-up balance are exhausted |
| 403 | The operation needs a plan or add-on your account does not hold |
| 413 | The request exceeds a per-call cap for your tier, such as batch size, optimize stops or radius reach in miles |
| 429 | Burst rate limit, pooled per account. A completed call also charges the bucket for the provider calls it made |
Per-item misses inside a batch are returned per item and do not fail the request.
Frequently asked questions
How do I authenticate?
Send your CDXZipStream API key in the X-API-Key header on every /v1 call. A ?key= query parameter is also accepted where a header is awkward, though the header is preferred. Keys look like cdx_live_… and are issued from your account.
Is there an OpenAPI spec I can generate a client from?
Yes. https://api.cdxzipstream.com/openapi.json is OpenAPI 3.1 and is the source of truth behind both the Swagger UI and ReDoc views. It imports directly into Postman, Insomnia, Bruno and Hoppscotch, and works with openapi-generator for typed clients in most languages.
How is the API billed?
In credits, pooled per account. An account holds one monthly grant plus an optional prepaid top-up balance, and every key on the account draws from that same pool, so issuing more keys never adds capacity. Per-item operations such as ZIP and distance cost one credit per item, address verification two, geocoding four, and routing three per pair — the operations that make a paid provider call are priced above the ones served locally. Radius, closest and find are priced by the rows they return, one credit per 25 rows with a minimum of one, so the limit you ask for is the cost control. Route optimization costs stops times a method weight. GET /v1/pricing returns the live rate card and is free to call.
How do I know how many credits a call used?
The address verification endpoints, POST /v1/verify and POST /v1/verify/batch, return X-Credits-Charged and X-Credits-Remaining headers, and X-Credits-Remaining is omitted on unlimited plans. Other endpoints do not send those headers, so read your balance from GET /v1/account, which is free to call.
What happens when I run out of credits?
The call is refused with HTTP 402 and is not performed or charged. Radius, closest and find are the exception: because they are priced by rows returned, a balance too small for the full allowance clamps the result to fewer rows instead of refusing it. Add a prepaid top-up or move to a larger plan and calls resume immediately.
Are there rate or size limits?
Yes. A burst rate limit applies per account and returns 429 when exceeded. The same bucket is also charged for the provider calls a completed request made, so a request that leans hard on geocoding or routing can leave the next one waiting even at a modest call rate; pause briefly rather than shrinking the request. Local-only work is not charged that way. Per-call caps vary by tier and return 413 when exceeded, covering batch size, optimize stops and how far a radius may reach in miles. The number of rows radius, closest and find return is clamped to your tier's maximum rather than rejected. Split oversized work across requests or use POST /v1/batch.
Do I need the Excel or Sheets add-in to use the API?
No. The API is a standalone HTTPS/JSON service. The add-ins, the Claude MCP connector and your own code all call the same endpoints with the same key and draw on the same credit pool.
Can I try calls without writing any code?
Yes. Open the Swagger UI, click Authorize, paste your key, then use Try it out on any endpoint. Each request body is pre-filled with a working example. Calls made this way are real and meter credits like any other.
Get a key and make your first call
Start free. The same key works in the API, the Excel and Sheets add-ins, and Claude.
