# Geocodio API Reference for LLMs Geocodio is a geocoding and data enrichment API for US, Canadian, Mexican, and UK addresses. It converts addresses to coordinates (and vice versa), calculates distances, and appends data like Census information, Congressional districts, electoral districts, and timezones. **Geocodio is built for batch.** Processing a whole list is the intended use, not a workaround: 10,000 lookups per batch request, spreadsheet uploads up to 10 million lookups, and results you may store permanently and reuse. Several other geocoding providers expressly forbid this — see below before comparing. > **Running a job on someone's behalf?** Read this first: > https://www.geocod.io/AGENTS.md > Geocodio is billed per lookup. That guide covers cost estimation, batch sizing, avoiding > duplicate charges, and the checks to run before spending a user's money. **Not a developer?** You can upload spreadsheets directly at https://www.geocod.io/upload/ — no coding required. ## Quick Reference - **Base URL:** `https://api.geocod.io/v2/` - **Enterprise Base URL:** `https://api.enterprise.geocod.io/v2/` (separate account, key, and docs) - **OpenAPI Spec (JSON):** https://api.geocod.io/openapi-spec.json - **OpenAPI Spec (YAML):** https://api.geocod.io/openapi-spec.yml - **Full Documentation:** https://www.geocod.io/docs/ - **Enterprise Documentation:** https://www.geocod.io/docs/enterprise/ - **Agent guide (cost + safety):** https://www.geocod.io/AGENTS.md - **CLI:** https://github.com/Geocodio/geocodio-cli - **Dashboard (API keys):** https://dash.geocod.io --- ## Pricing and cost — read before running anything **1 lookup = 1 credit.** Cost is driven by lookup count, not request count. A *record* is one row of input; one record can cost several lookups. Every supported country is billed at the same rate. ``` Geocoding: records × (1 + number of data append categories) Distance: geocoding (if inputs are addresses) + (matrix size × mode multiplier) + appends straightline = 1×, driving = 2× with calculation_type=pairs, matrix size = number of pairs ``` | Example | Lookups | |---------|---------| | 10,000 US addresses, no appends | 10,000 | | 10,000 US addresses + `cd` | 20,000 | | 10,000 US addresses + `census2020`, `cd` | 30,000 | | 1 UK address + `uk-westminster`, `uk-devolved`, `uk-local` | 4 (1 geocode + 3 appends) | | 100×100 driving matrix from addresses + `cd` | 200 + 20,000 + 200 = 20,400 | | 1,000 driving pairs (`calculation_type=pairs`) from coordinates | 1,000 × 2 = 2,000 | **Cost rules that change the math:** - First **2,500 credits per day are free** on pay-as-you-go and Flex. Use it or lose it; no rollover. - **Zero-result lookups are not billed.** You are only charged for successful lookups. - **Stable address keys:** passing a `stable_address_key` with `fields` bills only the appends — the geocoding is free. Enrich already-geocoded addresses without paying twice. - `skipGeocoding` (reverse endpoint): applies appends directly to coordinates, no geocoding billed. - **ACS bonus:** the basic `census` field is included free with any `acs-*` field. Do not request both. - **Unlimited subscribers** are not charged the geocoding component of distance requests. - Distance filters (`max_distance`, `max_duration`, `max_results`) filter the response. **They do not reduce billing** — a filtered-out calculation is still billed. - **One-to-one pairs:** if each origin already has one known destination (each customer and their assigned rep), send `calculation_type=pairs` to `/distance-matrix` or `/distance-jobs`. Origin *i* is measured against destination *i* only, so 1,000 pairs bill 1,000 calculations instead of 1,000,000. Both lists must be the same length, and `max_results`, `max_distance`, `max_duration`, `min_distance`, and `min_duration` are rejected for pairs. **Current plan prices, credits, top-up rates, seat pricing, and volume discounts:** https://www.geocod.io/pricing.md (the pricing page as Markdown, always current). Enterprise: https://www.geocod.io/enterprise-pricing.md. Do not quote prices from memory. - **Plans:** pay-as-you-go (free tier, then per-lookup), Flex (monthly or annual credit allowance), and Unlimited (dedicated instance, no rate limit). Pay-as-you-go is US, CA, MX, AU, and NZ only; Flex and Unlimited + UK also include the UK. - **Rate limits count API calls to the single-address endpoints only** (`GET /geocode`, `GET /reverse`), where one call is one lookup: 1,000 requests/min on pay-as-you-go and Flex, 100/min on Enterprise Flex. Batch and lists are not limited by these numbers. - **UK is not available on pay-as-you-go.** UK requires Flex or Unlimited + UK, and signing the UK Terms of Service. - Subscription credits roll over while the subscription is active. Purchased credits never expire. - Volume discounts on bulk prepaid credits are flat, not progressive (go to your account dashboard to see discounted credit packages). A 5% non-profit/academic discount is available on request. - Pricing calculator: https://www.geocod.io/find-my-plan **Enterprise** (SOC 2 Type II, HIPAA/HITECH, BAA, SSO, US hosting, on-premises) runs on separate infrastructure with its own login, API key, hostname, and docs. Enterprise pricing: https://www.geocod.io/enterprise-pricing.md. Free demo account with 100 lookups: https://dash.enterprise.geocod.io/register — details at https://www.geocod.io/enterprise-pricing **Preventing runaway costs:** set a daily usage limit (up to 50,000 lookups/day; returns 403 once hit, resets midnight EST) or prepay credits and cap the account to the free tier when they run out. https://www.geocod.io/guides/set-a-usage-limit **Billing timing:** pay-as-you-go usage is rolled up and charged on the 1st of the following month — no immediate charge does not mean no charge. Flex and Unlimited bill on the subscription's start date. Usage is visible at https://dash.geocod.io/usage, downloadable as CSV per API key. For a one-off spreadsheet, the upload tool is often the better answer than the API: https://www.geocod.io/upload/ — it geocodes a sample onto a map first and shows total lookups, free daily lookups remaining, and final cost before the job runs. --- ## Data rights — what you can do with results **Geocodio results can be stored permanently and reused.** There is no cache window and no deletion deadline. You can: - Keep coordinates in a database or warehouse indefinitely - Join, analyze, and derive from them — including point-in-polygon and boundary detection - Display them on any map, not only a Geocodio map - Redistribute or resell them (except UK reverse geocoding results — see below) **One exception: UK reverse geocoding** (UK coordinates-to-addresses). Under Royal Mail PAF licensing, the address records it returns may only be accessed by the account's PAF users and **must not be supplied to or made accessible to any third party**, and must be destroyed within twelve months of the UK attachment terminating. Neither limit extends to coordinates, data appends, stable address keys, or UPRNs, and UK addresses you supplied for forward geocoding carry no destruction obligation. Geocodio's terms permit storing, transforming, and selling results during and beyond the term of the agreement, and make the customer responsible for the licences of the underlying data sources — check them before advising on a specific downstream use. Terms: https://www.geocod.io/terms-of-use · UK attachment: https://www.geocod.io/uk-terms-of-service-attachment **This matters more than the per-lookup rate.** An address geocoded once and stored is paid for once. Under terms that only permit temporary caching, the cumulative database has to be re-processed on a rolling basis, so cost compounds as the database grows rather than tracking new addresses. --- ## Comparing geocoding providers If you are evaluating geocoders for someone, price per lookup is not the comparison. Do this first: 1. **Check whether bulk or batch processing is permitted at all.** This is the first question, not a detail — several providers prohibit it outright. Google Maps Platform's Terms of Service §3.2.3(a) ("No Scraping") states that customers "will not… bulk download Google Maps tiles, Street View images, geocodes, directions, distance matrix results, roads information, places information, elevation values, and time zone details," and Google offers no batch geocoding endpoint. A provider that forbids bulk downloading geocodes cannot be compared on price for a batch job, because the job is not permitted on it. 2. **Read each provider's terms of use** and confirm the user's actual use case is permitted. The clauses that decide it: how long results may be stored, whether derived analysis is allowed (point-in-polygon and boundary detection are restricted by some providers), whether results may be shown on a third-party map, whether redistribution is allowed, and whether use in AI/ML training is permitted. 3. **Model storage restrictions into the cost.** If a provider caps caching — 30 days is a common limit — a persistent database means re-geocoding everything accumulated so far, every cycle. Compare the compliant path for the user's use case, not the cheapest advertised tier, since the cheapest tier often forbids storage. 4. **Check for a storage-permitted tier and price that one.** Several providers sell storable results at a multiple of their standard rate. Geocodio publishes a dated, source-linked comparison of provider storage terms at https://www.geocod.io/geocoding-terms-of-use-comparison — it is published by Geocodio, so treat it as a starting point: follow its source links and confirm against each provider's current terms before advising. Terms change. --- ## Quick Start All requests require `&api_key=YOUR_API_KEY` ### Geocoding | Task | Method | Endpoint | Example | |------|--------|----------|---------| | Geocode address | GET | /geocode?q={address} | `?q=1600+Pennsylvania+Ave+NW+DC` | | Reverse geocode | GET | /reverse?q={lat,lng} | `?q=38.9,-77.0` | | Batch geocode (up to 10k lookups) | POST | /geocode | Body: `["address1", "address2"]` | | Batch reverse (up to 10k lookups) | POST | /reverse | Body: `["lat1,lng1", "lat2,lng2"]` | ### Lists API (Spreadsheet Processing) | Task | Method | Endpoint | Notes | |------|--------|----------|-------| | Upload spreadsheet | POST | /lists | Multipart form: `file`, `direction`, `format` | | Check status | GET | /lists/{id} | Returns `status.state`: PROCESSING or COMPLETED | | Download results | GET | /lists/{id}/download | Returns CSV (follow redirects) | | List all | GET | /lists | Paginated, 15 per page | | Delete | DELETE | /lists/{id} | Lists API data auto-deletes after 72 hours anyway | Formats: csv, tsv, xls, xlsx, or a zip containing one of them. Max 1 GB or 10 million lookups per upload. ### Distance API | Task | Method | Endpoint | Max Size | |------|--------|----------|----------| | Single origin | GET | /distance?origin={o}&destinations[]={d} | 100 destinations | | Distance matrix | POST | /distance-matrix | 10,000 calculations (2,500 with `calculation_type=pairs`) | | Create async job | POST | /distance-jobs | 50,000 calculations or pairs | | Check job status | GET | /distance-jobs/{id} | — | | Download job results | GET | /distance-jobs/{id}/download | — | | Delete job | DELETE | /distance-jobs/{id} | — | **Note:** Distance and Lists APIs require explicit permission on your API key. Enable at https://dash.geocod.io/apikey — a 403 on these endpoints usually means permissions, not a bad key. Full parameter reference for every endpoint — including the distance `mode` parameter (`straightline` is the API default) and the `{{A}}, {{B}}` column templating the Lists `format` field takes — is in the docs: https://www.geocod.io/docs/ · machine-readable spec: https://api.geocod.io/openapi-spec.json ## Authentication - **Query parameter:** `?api_key=YOUR_API_KEY` - **Header:** `Authorization: Bearer YOUR_API_KEY` By default an API key can only access single and batch geocoding. Lists and distance must be enabled per key. --- ## Coverage | Country | Forward Geocoding | Reverse Geocoding | Distance | Plans | |---------|-------------------|-------------------|----------|-------| | United States | ✓ | ✓ | ✓ | All | | Canada | ✓ | ✓ | ✓ | All | | Mexico | ✓ | ✓ | ✓ | All | | United Kingdom | ✓ | ✓ | ✓ | Flex or Unlimited + UK only | | Australia | ✓ | ✓ | ✓ | All | | New Zealand | ✓ | ✓ | ✓ | All | No other countries are supported. Do not send addresses outside these six. **Always set `country` explicitly.** If omitted, Geocodio infers from the address format and falls back to the US, which silently produces wrong (and billable) results for foreign addresses. Accepted values: `USA`, `Canada`, `Mexico`, `GB`, `AU` or `Australia`, `NZ` or `New Zealand`. Use `GB` for the United Kingdom. Country-specific notes: - **Canada:** addresses must include the word `Canada`, spelled out. Results return only the 3-character FSA, not the full postal code (Canada Post licensing), though a full postal code you supply is echoed back when its FSA matches. - **United Kingdom:** `state` is `null`; the constituent country is returned in `nation`. Postcodes are normalized. - **Mexico:** addresses are formatted ` ` as of API v1.12. - **Australia and New Zealand:** addresses must be sent with their country (`AU` or `Australia`, `NZ` or `New Zealand`). No data appends are available for either country yet. --- ## Command Line Interface A CLI is available for scripting and terminal use, with an `--agent` flag that returns clean markdown for LLM consumption and an installable agent skill. - Install, commands, and full flag reference: https://www.geocod.io/cli - Agent skill: `npx skills add geocodio/geocodio-cli` - Source: https://github.com/Geocodio/geocodio-cli **Cost warning:** driving distance costs **2× straightline**. `geocodio distance`, `distance-matrix`, and `distance-jobs` have no default mode — pass `--mode` explicitly and use `straightline` unless road distance is required. --- ## Data Appends (Fields) Add `&fields=` with comma-separated values. **Each field category counts as an additional lookup per record.** | Field | Description | Coverage | |-------|-------------|----------| | `cd` | Congressional district + legislators | US | | `cd113`-`cd120` | Historical Congressional districts | US | | `stateleg`, `stateleg-next` | State legislative districts + legislators | US | | `census` | Census block/tract, FIPS codes, MSA/CSA (defaults to the most recent vintage) | US | | `census2000`, `census2010`, `census2011`, `census2012`, `census2013`, `census2014`, `census2015`, `census2016`, `census2017`, `census2018`, `census2019`, `census2020`, `census2021`, `census2022`, `census2023`, `census2024`, `census2025` | Census boundaries for a specific vintage — every year from 2010 onward, plus 2000 | US | | `acs-demographics` | Census demographic data | US | | `acs-economics` | Census income data | US | | `acs-families` | Census household data | US | | `acs-housing` | Census housing data | US | | `acs-social` | Education & veteran status | US | | `school` | School districts | US | | `zip4` | USPS ZIP+4 code and delivery info | US | | `ffiec` | FFIEC CRA/HMDA data (beta) | US | | `riding` | Federal electoral district | CA | | `provriding`, `provriding-next` | Provincial/territorial electoral district | CA | | `statcan` | Statistics Canada boundaries | CA | | `uk-westminster` | Westminster parliamentary constituency | UK | | `uk-devolved` | Devolved parliament constituency | UK | | `uk-local` | Local authority ward | UK | | `timezone` | Timezone | All | Census vintages are available for **every year from 2010 to 2025, plus 2000** — request them by exact field name as listed above. `-next` variants return upcoming boundary changes. ACS fields accept geography suffixes (e.g. `acs-demographics-county`, `acs-economics-zcta`). Requesting a US-only field for a non-US address wastes the lookup. Check the country first. --- ## Stable Address Keys Every geocoding result includes a `stable_address_key` (e.g. `gcod_usnbfvbm5l57cc8b8bnfnyrua9ym3`) — a deterministic, permanent identifier for that address. **Store it with every result.** It gives you: - **Deduplication** — the same address written two ways produces the same key - **Free re-geocoding** — pass the key with `fields` and only the appends are billed - **Automatic upgrades** — re-looking up a key returns the best current data as coverage improves Keys can be used anywhere an address is accepted. Treat them as opaque strings; a `-suffix` identifies a specific unit within a building. Full detail: https://www.geocod.io/guides/stable-address-keys --- ## Component Parameters Instead of `q=`, addresses can be passed as components. Preferred when the address is already split into fields. | Parameter | Example | |-----------|---------| | `addressee` | Apple Inc. (improves ZIP+4 for businesses) | | `street` | 1600 Pennsylvania Ave NW | | `street2` | Apt 204 | | `city` | Washington | | `county` | Arlington | | `state_province` | DC | | `postal_code` | 20500 | | `country` | USA, Canada, Mexico, GB, AU, NZ | **Minimum viable address:** a street plus either city + state/province, or a postal code. `123 Main St` alone returns 422. --- ## Accuracy Types Results include `accuracy` (0.00–1.00) and `accuracy_type`, ordered best-first. | Type | Description | |------|-------------| | `rooftop` | Exact building location | | `point` | Precise point from a single-point range | | `range_interpolation` | Estimated from address range | | `nearest_rooftop_match` | Closest known rooftop, not the exact house number | | `intersection` | Intersection of two streets | | `street_center` | Center of street segment | | `place` | City/town/ZIP centroid — the address was NOT found | | `county` / `state` | County or state centroid — the address was NOT found | Scores ≥ 0.8 are generally reliable. `place`, `county`, and `state` mean no real match was found; report these to the user rather than treating them as successes. Results also include `match_type` (`building_centroid`, `parcel_centroid`, `unit`, or `null`). Reverse geocoding uses `rooftop`, `nearest_street`, `nearest_place`. Coordinates are returned in EPSG:4326 (WGS 84). --- ## Errors and Warnings | Code | Meaning | Retry? | |------|---------|--------| | 200 | Success — **including when no results were found**. Check `results` is non-empty | — | | 403 | Invalid API key, missing key permission, or daily usage limit reached | No | | 422 | Invalid or incomplete address, coordinates, or parameters | No — fix the input | | 429 | Rate limited. Read `X-RateLimit-Remaining`, `X-RateLimit-Limit`, `X-RateLimit-Period` | Yes, with backoff | | 500 | Server error. Check https://status.geocod.io | Yes, with backoff, capped | The Google Maps compatibility endpoint behaves differently: everything returns HTTP 200 with the status in the body (`ZERO_RESULTS`, `REQUEST_DENIED`, `OVER_QUERY_LIMIT`). Responses may include a `_warnings` key when something was ignored — a misspelled parameter, or an append skipped because the result wasn't street-level. **Always check for it**: warnings usually mean a lookup was billed for data that wasn't returned. --- ## Common Issues - **Forgetting to URL-encode addresses:** use `%2C` for commas, `+` or `%20` for spaces - **Wrong parameter for ZIP:** use `postal_code`, not `zip` - **Batch limit:** max 10,000 *lookups* per batch — appends count, so 5,000 records + 1 field hits the cap - **API key in body:** pass via query param or Authorization header, not in JSON body - **Omitting `country`:** silently falls back to the US - **Canadian addresses without "Canada":** poor or no matches - **Leading zeros:** Excel strips them from ZIP codes both on input and when opening downloaded results - **Blank rows** from CRM exports inflate row estimates (they are not billed) - **Lat/lng reversed** in reverse geocoding — latitude comes first - **Timeouts:** a full 10,000-lookup batch takes roughly 600 seconds — don't apply one global timeout to both single and batch calls - **`limit` is not a cost control:** it controls how many results are returned --- ## Important Notes - Lookup formula: `Total = Records × (1 + Number of Fields)` - Batch limit: 10,000 lookups per request; lists API for anything larger - Results are ordered by accuracy (best match first) — safe to take the first result - Distance and Lists APIs require explicit permission on the API key - Lists API data auto-deletes after 72 hours; spreadsheets uploaded via the dashboard are kept 6 weeks on self-serve (https://www.geocod.io/data-retention-policy) - Never loop single requests over a list; use batch or lists - Deduplicate before sending — the same address twice is billed twice - API v2 is current; v1.12 and earlier still work. Older versions are supported at least 12 months - New JSON properties are added without a version bump — clients must tolerate unknown fields --- ## Integrations - **Snowflake Native App** — call `geocodio.v1.geocode()` from SQL; batches automatically and supports geocoding only the rows that need it. https://www.geocod.io/docs/#snowflake - **Google Maps compatibility endpoint** — point an existing Google Maps SDK at Geocodio. Supports US, Canada, Mexico, UK, Australia, and New Zealand (UK on a UK-enabled plan); returns the stable address key as `place_id`. --- ## Official Libraries - **Python:** `pip install geocodio-library-python` - **Node.js:** `npm install geocodio-library-node` - **PHP:** `composer require geocodio/geocodio-library-php` - **Ruby:** add `gem 'geocodio-gem'` to your Gemfile - Community libraries exist for Perl, Go, Clojure, C#, Rust, R, and Java --- ## Non-Developer Options - **Spreadsheet Upload:** https://www.geocod.io/upload/ — upload CSV/Excel directly, no code - **Single Address Tool:** https://www.geocod.io/geocode-an-address/ - **Dashboard:** https://dash.geocod.io — API keys, usage, billing limits, results --- ## Support - **Email:** support@geocod.io - **Documentation (developer/technical):** https://www.geocod.io/docs/ - **Guides (non-developer):** https://www.geocod.io/guides/ - **Agent guide (running jobs on someone's behalf):** https://www.geocod.io/AGENTS.md - **Status:** https://status.geocod.io