REST API

InstaMaps API

Geocoding, road distances, route plans, drive-time areas, flood and crime risk, official facts, places nearby and plain-English questions over a table, as one REST API. Free for 2,500 lookups a day, and the results are yours to keep.

Quick answer

The InstaMaps API is a REST API for location data on lists of addresses. Send a POST to https://get-instamaps.com/v1/<endpoint> with your key in Authorization: Bearer and a JSON body, and get JSON back. It geocodes addresses with a confidence for every row, measures road miles and drive times, plans routes for up to 10 drivers, checks flood zones, crime and natural-hazard risk, and answers plain-English questions about a table (the =ASK formula, as an API). The first 2,500 lookups each day are free, keys are free with a Google sign-in, and there is no 30-day cache rule: store the results for as long as you like. It is strongest in the US and Great Britain, on InstaMaps' own address index, roads and official data.

Start in a minute

  1. Get a key in the developer portal (sign in with Google; free). The portal also shows your usage and lets you name and revoke keys.
  2. POST JSON to an endpoint with the key in the Authorization header.
  3. Read the answer: every row you sent comes back, under your own id, with a confidence and its sources.
curl https://get-instamaps.com/v1/geocode_batch \
  -H "Authorization: Bearer $INSTAMAPS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"records": [{"id": "hq", "address": "10 Downing Street, London SW1A 2AA"},
                   {"id": "wh", "address": "1600 Pennsylvania Ave NW, Washington DC 20500"}]}'

Answer: 3 rows: 2 placed, 0 to review, 1 unplaced · 2 of 3 high confidence (0 medium, 1 low). Caveats: not placed (1 row).

{
  "confidence": {
    "summary": "2 of 3 high confidence (0 medium, 1 low). Caveats: not placed (1 row).",
    "levels": {
      "high": 2,
      "medium": 0,
      "low": 1
    },
    "caveats": [
      {
        "basis": "not_placed",
        "level": "low",
        "rows": 1,
        "ids": [
          "x"
        ],
        "meaning": "This row could not be placed.",
        "next": "Leave it out of totals, say so, and ask the user for a postcode or coordinates."
      }
    ]
  },
  "records": [
    {
      "id": "hq",
      "input": "10 Downing Street, London SW1A 2AA",
      "record_key": "rk1_e9ec1ea25045e3a5e393",
      "address_quality": {
        "value": "full_street",
        "basis": "rule"
      },
      "status": "placed",
      "location": {
        "value": {
          "lat": 51.5034878,
          "lng": -0.1276965
        },
        "precision": "rooftop",
        "confidence": {
          "value": 0.95,
          "basis": "rule",
          "evidence": [
            "named site matched (10 Downing Street)",
            "house number 10 matched",
            "street matched (Downing Street)",
            "… 5 more"
          ]
        }
      },
      "admin": {
        "value": {
          "house_number": "10",
          "street": "Downing Street",
          "city": "London",
          "county": "Greater London",
          "state": "England",
          "postcode": "SW1A 2AA",
          "country": "GB",
          "council": "Westminster"
        },
        "basis": "rule",
        "evidence": [
          "open map data",
          "council from the official postcode directory"
        ]
      },
      "map_version": "osm-2026-10-03",
      "uprn": {
        "value": "100023336956",
        "distance_m": 6,
        "basis": "nearest"
      },
      "confidence": {
        "level": "high",
        "score": 0.95,
        "basis": "geocode_checked",
        "why": "rooftop"
      }
    },
    {
      "id": "wh",
      "input": "1600 Pennsylvania Ave NW, Washington DC 20500",
      "record_key": "rk1_0579e7bc70379e42dce9",
      "address_quality": {
        "value": "full_street",
        "basis": "rule"
      },
      "status": "placed",
      "location": {
        "value": {
          "lat": 38.8976387,
          "lng": -77.0365525
        },
        "precision": "rooftop",
        "confidence": {
          "value": 0.95,
          "basis": "rule",
          "evidence": [
            "house number 1600 matched",
            "street matched (Pennsylvania Avenue Northwest)",
            "postcode agrees (20500)",
            "… 4 more"
          ]
        }
      },
      "admin": {
        "value": {
          "house_number": "1600",
          "street": "Pennsylvania Avenue Northwest",
          "city": "Washington",
          "county": "District of Columbia",
          "state": "DC",
          "postcode": "20500",
          "country": "US"
        },
        "basis": "rule",
        "evidence": [
          "open map data"
        ]
      },
      "map_version": "osm-2026-10-03",
      "confidence": {
        "level": "high",
        "score": 0.95,
        "basis": "geocode_checked",
        "why": "rooftop"
      }
    },
    {
      "id": "x",
      "input": "asdfgh",
      "record_key": "rk1_8588310a98676af6e225",
      "address_quality": {
        "value": "town_only",
        "basis": "rule"
      },
      "status": "unplaced",
      "location": {
        "value": null,
        "precision": "none",
        "confidence": {
          "value": 0.2,
          "basis": "rule",
          "evidence": [
            "town differs (The Municipal District of Newcastle West on the map)",
            "position: the centre of the town",
            "nothing about it matches the input"
          ]
        },
        "why": "unreadable address: no street, town or postcode we recognise"
      },
      "admin": {
        "value": null,
        "basis": "rule",
        "evidence": [
          "open map data"
        ]
      },
      "map_version": "osm-2026-09-19",
      "confidence": {
        "level": "low",
        "score": 0.2,
        "basis": "not_placed",
        "why": "unreadable address: no street, town or postcode we recognise"
      }
    }
  ],
  "summary": {
    "records": 3,
    "status": {
      "placed": 2,
      "review": 0,
      "unplaced": 1
    },
    "precision": {
      "rooftop": 2,
      "none": 1
    },
    "vs_paid_reference": null,
    "vs_live_product": null,
    "declined_but_placed_by": {
      "paid_reference": [],
      "live_product": []
    },
    "sent": 3
  },
  "ms": 1875,
  "run": {
    "tool": "geocode_batch",
    "at": "2026-10-13T15:59:09.444Z",
    "rows": 3,
    "placed": 2,
    "review": 0,
    "unplaced": 1,
    "not_placed": 1,
    "sources": [
      {
        "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io",
        "as_of": "2026-10-08"
      }
    ],
    "run_id": "run_30182f16c73e3d50",
    "confidence": {
      "high": 2,
      "medium": 0,
      "low": 1
    }
  }
}

Every answer has a message (the answer in a sentence), the data, a run block (sources with their dates, confidence counts and a run_id any endpoint can take as source: {"{"} "run": … {"}"}), and usage (lookups this call cost and what's left today, also in the X-Lookups-Used and X-Lookups-Remaining headers). Errors are an HTTP status with {"{"} "error": "…" {"}"}: 400 can't answer, 401 key, 404 endpoint, 429 out of lookups.

Endpoints

The same tools as the InstaMaps MCP server, as plain HTTP. The body is the tool's input, as below.

Place

POST /v1/geocode_batch

Geocode a list of addresses

Turn a list of addresses, business names, postcodes or coordinates into points, with a confidence and the address parts for every row.

Coverage: Worldwide; strongest in the US and Great Britain (house-level address data); council and UPRN in Great Britain.

Inputs and an example
FieldTypeWhat it is
addressesarray, up to 100Addresses, one per row.
recordsarray, up to 100Or rows with your own ids.
formatstringcsv: also return every row as CSV text (csv), one line per row in the order sent, to save as a file in Drive or paste into a sheet. One of: json, csv.
columnsarrayThe fields for the CSV and for write_to_sheet, in order (CSV default: status, lat, lng, precision, confidence, reason, house_number, street, city, county, state, postcode, country, council, uprn, record_key; write_to_sheet default: lat, lng, status, address, city, county, state, postcode, country, precision, confidence). ID and input always lead the CSV. council (Great Britain: the local authority) and uprn (Great Britain: the nearest UPRN to a pin on a building, within 15 m) are blank elsewhere.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 100 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "records": [
    {
      "id": "hq",
      "address": "10 Downing Street, London SW1A 2AA"
    },
    {
      "id": "wh",
      "address": "1600 Pennsylvania Ave NW, Washington DC 20500"
    },
    {
      "id": "x",
      "address": "asdfgh"
    }
  ]
}

Answer: 3 rows: 2 placed, 0 to review, 1 unplaced · 2 of 3 high confidence (0 medium, 1 low). Caveats: not placed (1 row).

Full reference: when to use it, sources, what's been measured →

Measure

POST /v1/filter_by_location

Filter records by distance to sites

Which records are within N miles or km of one or more sites, or the nearest sites to each record, by straight-line distance.

Coverage: Worldwide (straight-line distance).

Inputs and an example
FieldTypeWhat it is
recordsarrayThe list to filter: {id, address} or {id, lat, lng}.
sitesarray, up to 25Depots, stores, offices: {id, address} or {id, lat, lng}.
within_milesnumberKeep records within this many miles of any site.
within_kmnumberOr the same in kilometres.
nearest_nintegerAlso list the N nearest records to each site.
renderbooleanAlso keep the map (the sites, their radius and the records): a link to share, GeoJSON and KML.
titlestringThe kept map's title when render is on.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.
sites_sourceobjectThe sites by reference, the same way as source.

Example body

{
  "records": [
    {
      "id": "a",
      "name": "Leeds Town Hall",
      "address": "Leeds Town Hall, Leeds LS1 3AD"
    },
    {
      "id": "b",
      "name": "York Minster",
      "address": "York Minster, York YO1 7HH"
    },
    {
      "id": "c",
      "name": "Manchester Piccadilly",
      "address": "Manchester Piccadilly station, Manchester M1 2BN"
    }
  ],
  "sites": [
    {
      "id": "depot",
      "name": "Leeds depot",
      "address": "Leeds LS1 4AP"
    }
  ],
  "within_miles": 30
}

Answer: within 30 miles of the site; straight-line distance, not driving distance. 2 of 3 placed records match · 2 of 3 high confidence (1 medium, 0 low). Caveats: placed, less sure (1 row).

Full reference: when to use it, sources, what's been measured →

POST /v1/get_road_distances

Road distance and drive time for journeys

Road distance and drive time for each from–to journey, on our own road network, with typical weekday traffic.

Coverage: Great Britain and the US by road; elsewhere straight line, labelled as such.

Inputs and an example
FieldTypeWhat it is
journeysarray, up to 100{id, from, to}; from/to are text (address, postcode) or {lat, lng}.
regionstringOptional; worked out from the postcodes when left out. One of: uk, us.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 100 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
trafficstringweekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. One of: weekday, free_flow.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "journeys": [
    {
      "id": "1",
      "from": "Leeds LS1 4AP",
      "to": "York YO1 7HH"
    },
    {
      "id": "2",
      "from": "Austin TX 78701",
      "to": "Dallas TX 75201"
    }
  ]
}

Answer: 2 journeys: 2 by road (228.3 road miles) · 0 of 2 high confidence (2 medium, 0 low). Caveats: postcode centre (2 rows); street or named place (1 row).

Full reference: when to use it, sources, what's been measured →

POST /v1/get_travel_time_area

Area reachable within a travel time

The area reachable from a place within N minutes by car, on foot or by bike, and which of your records fall inside each band.

Coverage: Great Britain and the US on our roads, with measured weekday traffic for driving.

Inputs and an example
FieldTypeWhat it is
originrequiredobjectAn address or {lat, lng}.
minutesarray, up to 3
modestring One of: drive, walk, cycle.
recordsarray, up to 500{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 500Or plain addresses/postcodes, numbered from 1.
include_geometryboolean
renderbooleanAlso keep the map (the bands, the origin and the records): a link, GeoJSON and KML.
titlestringThe kept map's title when render is on.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
trafficstringweekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. One of: weekday, free_flow.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "origin": "Leeds LS1 4AP",
  "minutes": [
    15,
    30
  ],
  "addresses": [
    "York YO1 7HH",
    "Harrogate HG1 1HN"
  ]
}

Answer: drive from Leeds LS1 4AP: 15 min 155 km² (0 records inside), 30 min 1023 km² (0 records inside) · 0 of 2 high confidence (2 medium, 0 low). Caveats: street or named place (1 row); postcode centre (1 row).

Full reference: when to use it, sources, what's been measured →

POST /v1/find_postcodes_in_radius

Every ZIP code or postcode within a radius

Every US ZIP code, or UK postcode sector or district, within a radius of a place, nearest first.

Coverage: US (Census ZIP code areas) and the UK (postcode sectors and districts).

Inputs and an example
FieldTypeWhat it is
centerrequiredstringA ZIP ("10001"), a UK postcode, sector or district ("SW1A 1AA", "SW1A 1", "SW1A"), an address, or "lat,lng".
radiusrequirednumberUp to 500 miles or 800 km.
unitstring One of: mi, km.
granularitystringUK only: postcode sectors ("SW1A 1") or districts ("SW1A"). One of: sector, district.
countrystringOptional: worked out from the centre. One of: us, gb.
limitnumberMost areas to list, nearest first (up to 2,500); the total found is always given.
renderboolean
titlestring

Example body

{
  "center": "10001",
  "radius": 1,
  "limit": 5
}

Answer: 9 ZIP codes within 1 mi of 10001 (nearest 5 listed; raise limit for more)

Full reference: when to use it, sources, what's been measured →

Route

POST /v1/plan_routes

Plan routes for one or more drivers

Split up to 100 stops across up to 10 drivers from one depot, in the best order on real roads, with Google Maps links per driver.

Coverage: Great Britain and the US on our roads; elsewhere straight-line estimates, labelled.

Inputs and an example
FieldTypeWhat it is
depotrequiredobjectWhere the drivers start: an address or {lat, lng}.
stopsarray, up to 100Addresses, or {id, name, address} / {id, name, lat, lng}. name labels the stop on the map and in the plan.
driversinteger
return_to_depotboolean
shift_hoursnumber
service_minutesnumberTime spent at each stop.
renderbooleanAlso keep the map: a link to share with the drivers, GeoJSON and KML.
titlestringThe kept map's title when render is on.
trafficstringweekday (default): road times with the area's measured weekday slowdown (DfT delay on local 'A' roads by council and on motorways in Great Britain; the Urban Mobility Report's Travel Time Index by US urban area). free_flow: empty roads. One of: weekday, free_flow.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "depot": "Canning Town, London E16 1DQ",
  "stops": [
    {
      "id": "0",
      "address": "Stratford Station, London E15 1AZ"
    },
    {
      "id": "1",
      "address": "Hackney Central, London E8 1LL"
    },
    {
      "id": "2",
      "address": "Bethnal Green Road, London E2 6AH"
    },
    {
      "id": "3",
      "address": "Bow Road, London E3 4DH"
    },
    {
      "id": "4",
      "address": "Leyton High Road, London E10 5NA"
    }
  ],
  "drivers": 1
}

Answer: 5 stops across 1 driver(s) · 1 of 5 high confidence (4 medium, 0 low). Caveats: street or named place (4 rows).

Full reference: when to use it, sources, what's been measured →

Ask a table

POST /v1/ask_table

Ask a question about a table

Answer a plain-English question about a whole table (filters, counts, distances to a named place or a second list), showing how it read the question.

Coverage: Any table; place questions use our UK and US geography.

Inputs and an example
FieldTypeWhat it is
questionrequiredstringThe question, as a person would ask it.
recordsarray, up to 5000The table as row objects (keys are the column names).
headersarrayOr the column names…
rowsarray, up to 5000…and the rows as arrays in the same order.
modestring One of: rows, match, why.
reference_recordsarrayOptional second list for two-list questions (depots, competitors, stores).
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "question": "Which accounts have annual revenue over 50k?",
  "records": [
    {
      "Account": "Rice University",
      "Address": "6100 Main St Houston TX 77005",
      "Annual revenue": 82000
    },
    {
      "Account": "Museum of Fine Arts",
      "Address": "1001 Bissonnet St Houston TX 77005",
      "Annual revenue": 23000
    },
    {
      "Account": "Toyota Center",
      "Address": "1510 Polk St Houston TX 77002",
      "Annual revenue": 61000
    }
  ]
}

Answer: Read as: Annual revenue > 50,000. 2 of 3 rows match

Full reference: when to use it, sources, what's been measured →

Facts and risk

POST /v1/get_location_facts

Official areas and zones for each address

The official areas each address falls in: US census tract, income level, county, metro, HUBZone, Opportunity Zone, USDA eligibility, FEMA flood zone; GB conservation area, listed buildings, nearest UPRN, England flood zone.

Coverage: US and Great Britain (England for flood zones and planning constraints; Article 4 and tree preservation orders where the council has published them: 112 and 81 councils).

Inputs and an example
FieldTypeWhat it is
recordsarray, up to 200{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 200Or plain addresses/postcodes, numbered from 1.
fieldsarrayOnly these facts (default: all that apply). flood is FEMA in the US, the Environment Agency in England.
regionstringOptional; worked out per address from its postcode or ZIP. One of: us, uk.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "addresses": [
    "10 Downing Street, London SW1A 2AA",
    "1600 Pennsylvania Ave NW, Washington DC 20500"
  ]
}

Answer: 2 of 2 placed and checked

Full reference: when to use it, sources, what's been measured →

POST /v1/get_area_risk

Crime, flood or natural-hazard risk for each place

One risk fact per place: recorded crime nearby (England and Wales) with the commonest types, flood zone (England, US), or FEMA natural-hazard rating (US). Flood answers also compare: base flood elevation, the neighbourhood's river and coastal flooding with its national percentile (US), the rank on the list and a sentence in words, on a map over the official flood zones.

Coverage: Crime: England and Wales (police.uk, latest month). Flood: England and US. Hazard: US census tracts (FEMA National Risk Index).

Inputs and an example
FieldTypeWhat it is
metricrequiredstring One of: crime, flood, hazard.
kindstring
recordsarray, up to 250{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 250Or plain addresses/postcodes, numbered from 1.
renderbooleanflood: also keep the map (the places by risk over the flood zones): a link to share, GeoJSON and KML.
titlestringThe kept map's title when render is on.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "metric": "flood",
  "addresses": [
    "York YO1 7HH",
    "10 Downing Street, London SW1A 2AA"
  ]
}

Answer: flood zone: 2 of 2 answered · 1 of 2 high confidence (1 medium, 0 low). Caveats: street or named place (1 row).

Full reference: when to use it, sources, what's been measured →

POST /v1/get_live_hazards

Flood, storm and earthquake warnings in force now

Warnings and events in force now: England's flood warnings, US weather warnings, and worldwide earthquake shaking, hurricanes, floods, wildfires and volcanoes, with kind, level, area, times and outline.

Coverage: England (Environment Agency), the US (National Weather Service), and worldwide: earthquakes M4.5+ of the past week with a ShakeMap (USGS), Atlantic and Pacific storms (National Hurricane Center), and GDACS floods, wildfires, volcanoes and other cyclones (automatic estimates). Refreshed every 10 minutes.

Inputs and an example
FieldTypeWhat it is
regionstringgb: England's flood warnings and world events touching Great Britain; us: National Weather Service warnings and world events touching the US; world: the earthquake, hurricane and GDACS feeds only; all: everything. One of: gb, us, world, all.
perilsarrayOnly these perils (default: all).
min_levelstringOnly this level and above (default: all). One of: severe, warning, watch, advisory.
renderboolean
titlestring

Example body

{
  "region": "us",
  "min_level": "warning"
}

Answer: 7 warnings in force (7 warning): 7 flood

Full reference: when to use it, sources, what's been measured →

POST /v1/check_live_hazards

Which of your places are inside a live warning or event

Which of your places are inside or near a warning or event now (or were hit by one), with insured values added up.

Coverage: Everything get_live_hazards covers: England and US warnings, and worldwide earthquakes, hurricanes and GDACS events. Refreshed every 10 minutes.

Inputs and an example
FieldTypeWhat it is
recordsarray, up to 500{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 500Or plain addresses/postcodes, numbered from 1.
near_kmnumberAlso flag places within this distance of a warning (0 to 50 km).
value_fieldstringThe records' field to add up (e.g. "TIV"); found automatically when it is called TIV, sum insured, insured value or value.
regionstring One of: gb, us, all.
perilsarray
min_levelstring One of: severe, warning, watch, advisory.
renderboolean
titlestring
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 500 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "records": [
    {
      "id": "leeds",
      "address": "Leeds LS1 4AP",
      "TIV": 2500000
    },
    {
      "id": "austin",
      "address": "500 Congress Avenue, Austin, TX 78701",
      "TIV": 900000
    }
  ]
}

Answer: 0 of 2 places inside a live warning, 0 within 5 km of one, 2 clear · value inside 0, near 0 (28 warnings in force) · 1 of 2 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row).

Full reference: when to use it, sources, what's been measured →

Around a place

POST /v1/find_nearby

Places of a kind near each address

The nearest, the count, or a list of places of a kind (stations, schools, supermarkets, pharmacies…) around each address.

Coverage: UK and US, from OpenStreetMap; each answer says how well that kind of place is mapped.

Inputs and an example
FieldTypeWhat it is
categoryrequiredstring
modestring One of: nearest, count, list.
radius_kmnumberDefault 10 km for nearest, 2 km otherwise.
nintegerHow many places to return per record.
recordsarray, up to 500{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 500Or plain addresses/postcodes, numbered from 1.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 150 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "category": "pharmacy",
  "addresses": [
    "Leeds LS1 4AP"
  ],
  "n": 3
}

Answer: Pharmacy (nearest, 10 km): 1 of 1 placed · 0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row); open map data, not the official register (1 row).

Full reference: when to use it, sources, what's been measured →

POST /v1/find_official_places

Official registers near each address (UK)

The official record: A&E departments, hospitals, GP practices, care homes and dentists with CQC ratings, NHS pharmacies, food hygiene ratings; or the record of the business at each row.

Coverage: England for CQC, England and Wales for NHS pharmacies, the UK for food hygiene.

Inputs and an example
FieldTypeWhat it is
kindrequiredstring One of: ae, hospital, urgent_care, gp, care_home, nursing_home, dentist, hospice, pharmacy, food.
modestringat: the registered place at each address itself (send name). One of: nearest, count, list, at.
radius_kmnumberHow far to look. Defaults: A&E 60, hospital 30, GP 10, care home 10, pharmacy 5, food 1.
nintegerHow many places to return per record.
ratingarrayCQC ratings to keep, e.g. ["Requires improvement", "Inadequate"]. For A&E, the rating of its urgent and emergency services.
nhsbooleanHospitals: true for NHS only, false for independent only.
include_specialistbooleanA&E: also the eye and children's hospitals' emergency departments (left out by default).
food_typestringrestaurant, takeaway, pub, supermarket, shop, hotel, school, caring, mobile or manufacturer.
min_hygieneinteger
max_hygieneinteger
recordsarray, up to 500{id, address} or {id, lat, lng}. Send your own ids to merge results back.
addressesarray, up to 500Or plain addresses/postcodes, numbered from 1.
backgroundbooleanWith source: run as a background job and answer at once with job_id (automatic past 200 rows). Check with get_job; write_to_sheet with the job_id puts the results in the sheet as they finish.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.

Example body

{
  "kind": "gp",
  "addresses": [
    "Leeds LS1 4AP"
  ],
  "n": 2
}

Answer: GP practice (nearest, 10 km): 1 of 1 records have one · 0 of 1 high confidence (1 medium, 0 low). Caveats: postcode centre (1 row).

Full reference: when to use it, sources, what's been measured →

Maps

POST /v1/render_map

Make a map to keep, share or change

A hosted, layered map to keep or share: pins, lines or areas, colours by field, a legend, GeoJSON and KML.

Coverage: Worldwide.

Inputs and an example
FieldTypeWhat it is
titlestringThe map's title (and how to find it again).
layersarray, up to 20One or more layers, drawn in order (later ones on top).
legendboolean
rowsarray, up to 2500Shortcut for a one-layer map: rows with lat/lng or addresses.
color_bystringWith rows: the field to colour the pins by.
flood_zonesbooleanDraw the official flood zones under the layers: FEMA's in the US (they show from street level) and the Environment Agency's in England.
sourceobjectInstead of typing rows: { sheet: "<Google Sheets link>", tab?: "Sites" } (shared with the InstaMaps service account, or viewable by anyone with the link), { file: "<Drive link to a CSV or Excel file>" }, or { run: "<run_id from an earlier answer>" }. Columns are found by their headers (id, name, address or its parts, lat/lng); name them if they aren't obvious (id_column, address_column, lat_column, lng_column; from_column and to_column for road distances). Rows with coordinates are used as they are.
from_runstringA run_id from an earlier answer: its rows as the map's pins (with color_by, bins and labels), in one call.
binsarrayWith from_run, source or rows and color_by on a number: band breaks.
labelsbooleanWith from_run, source or rows: names on the map.

Example body

{
  "title": "Docs example: two depots",
  "rows": [
    {
      "id": "leeds",
      "name": "Leeds depot",
      "lat": 53.7966,
      "lng": -1.5484
    },
    {
      "id": "york",
      "name": "York depot",
      "lat": 53.958,
      "lng": -1.0803
    }
  ]
}

Answer: Made "Docs example: two depots": 1 layer(s), 2 pins: https://get-instamaps.com/v/9hd9pnytqs

Full reference: when to use it, sources, what's been measured →

POST /v1/update_map

Change a kept map

Change a kept map in place: add or remove layers, move or add pins, recolour, rename; the link stays the same and earlier versions are kept.

Coverage: Worldwide.

Inputs and an example
FieldTypeWhat it is
maprequiredstringThe map_id or link render_map returned.
titlestringA new title.
add_layersarray
remove_layersarrayNames of layers to remove.
update_layersarray
upsert_pointsarrayMove, rename or re-field a pin by its id, or add a new one (new pins need lat/lng or an address).
remove_pointsarray
legendboolean
flood_zonesbooleantrue: draw the official flood zones under the layers (FEMA in the US, the Environment Agency in England); false: take them off.
revert_tointegerPut this earlier version back (it becomes the newest version; nothing is lost).

Example body

{
  "map": "9hd9pnytqs",
  "upsert_points": [
    {
      "layer": "Rows",
      "id": "harrogate",
      "name": "Harrogate depot",
      "lat": 53.9921,
      "lng": -1.5418
    }
  ]
}

Answer: Updated "Docs example: two depots" to version 2: added harrogate to "Rows". Same link: https://get-instamaps.com/v/9hd9pnytqs

Full reference: when to use it, sources, what's been measured →

POST /v1/get_map

Look at a kept map

Look at a kept map from an earlier conversation: its layers, pin ids and fields. With no map named, list the person's own maps, including the ones they made in the InstaMaps Google Sheets add-on.

Coverage: Maps made with render_map or a tool's render, and the signed-in person's own Sheets add-on maps.

Inputs and an example
FieldTypeWhat it is
mapstringThe map_id or link. Leave out to list the person's maps.
layerstringA layer whose pins to list ("pins" for a Sheets add-on map).

Example body

{
  "map": "9hd9pnytqs"
}

Answer: "Docs example: two depots" version 2: Rows (3 pins)

Full reference: when to use it, sources, what's been measured →

POST /v1/delete_map

Delete maps for good

Delete the person's own maps for good, made here or in the InstaMaps Google Sheets add-on: the link stops working and the pins, versions, logbook and photos go with it.

Coverage: Only maps the signed-in person made; anyone else's reads as not found.

Inputs and an example
FieldTypeWhat it is
mapsrequiredarray, up to 25The map_ids or links to delete.
Full reference: when to use it, sources, what's been measured →

Runs and jobs

POST /v1/combine_runs

Combine kept runs on the same places

Join two to six kept runs on the place ID every tool returns (record_key) and say what changed between them.

Coverage: Any runs from earlier answers (run_ids) or tables you send.

Inputs and an example
FieldTypeWhat it is
runsrequiredarray, up to 6Oldest first.
keystringThe place ID column every run has.
columnsarrayOnly these columns from each run (default: all).
comparearrayColumns to compare between runs: numbers get the change, text whether it changed.
only_changedboolean

Example body

{
  "runs": [
    "run_… (geocode_batch)",
    "run_… (get_area_risk flood)"
  ],
  "key": "record_key"
}

Answer: 2 places across 2 runs, 2 in every run

Full reference: when to use it, sources, what's been measured →

POST /v1/get_job

How far a background job has got

How far a background job has got: status, rows done, minutes left, and its run_id when done.

Coverage: Jobs started by the same person; checking costs no calls.

Inputs and an example
FieldTypeWhat it is
job_idrequiredstring
Full reference: when to use it, sources, what's been measured →

POST /v1/write_to_sheet

Put an answer into a Google Sheet

Put an earlier answer into a Google Sheet: new dated columns beside the rows it came from, or a new tab. Never overwrites a cell. The only tool that writes.

Coverage: Google Sheets shared with the InstaMaps service account as Editor; rows are matched by id, and a row that now holds a different place is skipped and named.

Inputs and an example
FieldTypeWhat it is
run_idstringThe run_id from an answer (run.run_id), or from get_job when a job is done.
job_idstringOr a background job's job_id.
sheetstringA Google Sheets link. Default: the sheet the rows came from.
tabstringThe tab. Default: the tab the rows came from.
modestringbeside: new columns next to the rows they came from (the default when the run came from this tab). new_tab: the rows as a table in a new tab (the default for any other sheet). One of: beside, new_tab.
columnsarrayWhich of the answer's fields to write, by name (e.g. "Latitude", "Confidence", "Nearest A&E", or geocode keys such as postcode or uprn). Default: the tool's usual columns.

Example body

{
  "run_id": "run_ae02fe5fb0d18808",
  "mode": "new_tab",
  "columns": [
    "lat",
    "lng",
    "postcode",
    "council",
    "uprn",
    "confidence"
  ]
}

Answer: Wrote 3 rows to "geocode_batch · 2026-10-13 17:36" (a new tab) in InstaMaps write_to_sheet test (landmarks), and a line in "InstaMaps runs".

Full reference: when to use it, sources, what's been measured →

What counts as a lookup

  • One lookup per row a call carries: an address placed, a journey measured, a stop routed, a place checked.
  • A question to ask_table is 10 lookups, however long the table.
  • A drive-time area is 10 lookups a band, plus one per place checked against it.
  • Maps, live hazards and postcode-radius lists are one lookup a call. Checking a background job (get_job) is free.
  • Rows sent by reference (a Google Sheet, a Drive file or an earlier run) are counted from the answer.

A call that fails costs nothing.

Pricing

Free

2,500 lookups a day

Every endpoint, no card. About 75,000 a month. Resets at midnight UTC.

Get a key

More than 2,500 a day

Tell us what you're building

Need more than that? Write to gbade@get-instamaps.com and tell us what you are building.

Email us

Next to the Google Maps Platform

InstaMaps APIGoogle Maps Platform
Free allowance2,500 lookups a day (about 75,000 a month), across every endpointUp to 10,000 free calls a month for each API (Geocoding, Routes and so on, counted separately)
Keeping resultsStore them in your own database for as long as you likeCoordinates may be cached for at most 30 days
Showing them on a mapAny mapOnly on a Google map
In one APIGeocoding, road distances, route plans for up to 10 drivers, drive-time areas, flood and crime risk, official facts, places nearby, questions over a table, hosted mapsSeparate APIs and keys for each
Confidence per rowEvery row: high, medium or low, with the reason and what to do about itA location type per result

Google's terms and free allowances as published by Google, October 2026 (Google Maps Platform Terms of Service; pricing page).

FAQs

Is there a free geocoding API?

Yes. The InstaMaps API geocodes 2,500 addresses a day free, with a confidence for every row and the address parts (city, county, state, postcode; in Great Britain the council and UPRN). Get a key with a Google sign-in in the developer portal, get-instamaps.com/developers/portal; no card.

What is a cheaper alternative to the Google Maps Geocoding API?

The InstaMaps API: 2,500 free lookups every day across geocoding, road distances, routes and risk, results you can store for as long as you like (Google allows 30 days), and no rule that they go on a Google map. It runs on InstaMaps' own address index and roads, strongest in the US and Great Britain.

Can I store the results?

Yes. There is no cache limit: keep the coordinates, distances and answers in your own database. Every answer names its sources and their dates; some are OpenStreetMap data (© OpenStreetMap contributors), which asks for a credit.

Is there an API for road distances and drive times between many addresses?

Yes: POST /v1/get_road_distances takes up to 100 journeys a call (bigger lists by reference run as a background job) and returns road miles, kilometres and drive time for each, as weekday estimates; plan_routes orders up to 100 stops across up to 10 drivers.

Does the API include =ASK?

Yes: POST /v1/ask_table answers a plain-English question about a whole table ("customers in Texas with revenue over 50k"), the same as the =ASK formula in the Google Sheets add-on, and shows how it read the question. A question is 10 lookups, however long the table.

How do I get an API key?

Sign in with Google in the developer portal (get-instamaps.com/developers/portal) and press Make a key. It is shown once; keep it secret and send it as Authorization: Bearer im_live_… (or X-API-Key). The portal shows your lookups today and over the last 30 days, by endpoint and by key, and lets you name, rename and revoke up to 5 keys.

How much does the InstaMaps API cost?

Nothing. It is free: 2,500 lookups a day per account, across every endpoint, reset at midnight UTC, no card. Need more? Write to gbade@get-instamaps.com.

Is it the same as the InstaMaps MCP server?

The same tools and engines. The MCP server is for AI assistants (Claude, ChatGPT and others) and counts calls; the API is for code and counts lookups. One Google sign-in covers both, so runs and maps are shared.

For agents and code generators

  • /openapi.json: OpenAPI 3.1, every endpoint with its schema and an example.
  • /v1: the endpoints, the lookup rules and the free tier, as JSON.
  • /llms-full.txt: every tool in one text file: when to use it, inputs, sources, measured accuracy, real answers.
  • Inside an AI assistant instead? Add the MCP server: the same tools, no code.