← All tools

Measure

Filter records by distance to sites

filter_by_location

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

Read-onlySheets, files and runs by referenceBackground jobs for big listsKeeps a shareable map

Use it when

  • ✓ "Customers within 25 miles of our depots"
  • ✓ The nearest store or branch to each customer
  • ✓ Large lists where speed matters more than road distance

Not for

Usual chain: geocode_batch (or rows with lat/lng) → filter_by_location → plan_routes or render_map

Coverage: Worldwide (straight-line distance).

Sources

  • InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io (2026-10-08)

Basis: straight-line (great-circle) distance

Inputs

records

array

The list to filter: {id, address} or {id, lat, lng}.

sites

array · up to 25

Depots, stores, offices: {id, address} or {id, lat, lng}.

within_miles

number

Keep records within this many miles of any site.

within_km

number

Or the same in kilometres.

nearest_n

integer

Also list the N nearest records to each site.

render

boolean

Also keep the map (the sites, their radius and the records): a link to share, GeoJSON and KML. Default: false

title

string

The kept map's title when render is on.

background

boolean

With 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.

source

object

Instead 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_source

object

The sites by reference, the same way as source.
The full description, as the server gives it to an agent

Which records are within a distance of any site, the nearest site to each record, and/or the N nearest records to each site. Records and sites can be addresses (placed first, up to 100 addresses per call) or lat/lng (up to 2000 records, 25 sites). Distances are straight-line (great-circle), not driving. Every record says which site it was measured to and how far; records held for review are flagged and records that could not be placed are listed, never silently counted in or out. Over 200 records the answer is compact: every record's nearest site as [id, site, miles], full detail for the matches only. The map shows in the chat by itself. Set render to true only when the user wants to keep or share the map: it returns a link, GeoJSON and KML, and update_map can change it later.

A real answer

Captured from the live server on 2026-10-13, trimmed to the first rows.

Request

{
  "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
}

The answer's first line

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).

The answer (trimmed)

{
  "confidence": {
    "summary": "2 of 3 high confidence (1 medium, 0 low). Caveats: placed, less sure (1 row).",
    "levels": {
      "high": 2,
      "medium": 1,
      "low": 0
    },
    "caveats": [
      {
        "basis": "geocode_low",
        "level": "medium",
        "rows": 1,
        "ids": [
          "c"
        ],
        "meaning": "Placed, with lower confidence than usual.",
        "next": "Mention it may be off, and confirm it if the answer depends on it."
      }
    ]
  },
  "reading": "within 30 miles of the site; straight-line distance, not driving distance",
  "matched": [
    "a",
    "b"
  ],
  "records": [
    {
      "id": "a",
      "label": "Leeds Town Hall, Leeds LS1 3AD",
      "location": {
        "lat": 53.8002679,
        "lng": -1.5497207
      },
      "nearest_site": {
        "id": "depot",
        "distance_miles": 0.4,
        "distance_km": 0.7
      },
      "within": true,
      "sites_within": [
        "depot"
      ],
      "placement": {
        "status": "placed",
        "precision": "rooftop",
        "confidence": 0.92,
        "map_version": "osm-2026-10-03"
      },
      "record_key": "rk1_497c1fa89025ba5bc79f",
      "confidence": {
        "level": "high",
        "score": 0.92,
        "basis": "geocode_checked",
        "why": "rooftop"
      }
    },
    {
      "id": "b",
      "label": "York Minster, York YO1 7HH",
      "location": {
        "lat": 53.9623561,
        "lng": -1.0820834
      },
      "nearest_site": {
        "id": "depot",
        "distance_miles": 22.5,
        "distance_km": 36.2
      },
      "within": true,
      "sites_within": [
        "depot"
      ],
      "placement": {
        "status": "placed",
        "precision": "rooftop",
        "confidence": 0.92,
        "map_version": "osm-2026-10-03"
      },
      "record_key": "rk1_fb67d1e967e22b14fe65",
      "confidence": {
        "level": "high",
        "score": 0.92,
        "basis": "geocode_checked",
        "why": "rooftop"
      }
    },
    {
      "id": "c",
      "label": "Manchester Piccadilly station, Manchester M1 2BN",
      "location": {
        "lat": 53.4778949,
        "lng": -2.2310037
      },
      "nearest_site": {
        "id": "depot",
        "distance_miles": 35.3,
        "distance_km": 56.8
      },
      "within": false,
      "sites_within": [],
      "placement": {
        "status": "placed",
        "precision": "postcode",
        "confidence": 0.75,
        "map_version": "osm-2026-10-03",
        "why": "placed in the postcode the input gives; the exact building is not certain"
      },
      "record_key": "rk1_daeb813ec04d00f1c1fc",
      "confidence": {
        "level": "medium",
        "score": 0.75,
        "basis": "geocode_low",
        "why": "postcode"
      }
    }
  ],
  "held_for_review": [],
  "could_not_place": [],
  "sites": [
    {
      "id": "depot",
      "location": {
        "lat": 53.795472,
        "lng": -1.555729
      },
      "placement": {
        "status": "placed",
        "precision": "postcode"
      }
    }
  ],
  "sites_not_placed": [],
  "run": {
    "tool": "filter_by_location",
    "at": "2026-10-13T15:59:12.161Z",
    "sources": [
      {
        "name": "InstaMaps address index (OpenStreetMap, OpenAddresses) and postcodes.io",
        "as_of": "2026-10-08"
      }
    ],
    "basis": "straight-line (great-circle) distance",
    "run_id": "run_2133642d49110140",
    "confidence": {
      "high": 2,
      "medium": 1,
      "low": 0
    }
  }
}

Use it in Claude

Add the connector https://get-instamaps.com/mcp and ask in plain words. 5,000 tool calls a day per person, reset at midnight UTC; a call counts once however many rows it carries; a sheet by reference is one call; checking a job is free.

How to add it →