# Docs

## Quickstarts

- [Leaflet](https://mapiron.com/docs/leaflet) — raster tiles and address search in Leaflet
- [MapLibre GL JS](https://mapiron.com/docs/maplibre) — vector tiles and styles
- [OpenLayers](https://mapiron.com/docs/openlayers) — raster and vector tiles in OpenLayers
- [WordPress (WP Go Maps)](https://mapiron.com/docs/wp-go-maps) — MapIron tiles in the WP Go Maps plugin, no code
- [No-code setups](https://mapiron.com/docs/no-code) — map code for website builders, Google Sheets, CSV batch geocoding, Zapier, Make and n8n
- [AI assistants (MCP)](https://mapiron.com/docs/mcp) — connect Claude, Cursor, VS Code and other MCP clients

Machine-readable: [OpenAPI 3.1 spec](https://mapiron.com/openapi.json) · [llms.txt](https://mapiron.com/llms.txt) · [this page as Markdown](https://mapiron.com/docs.md)

## Getting started

Get a key from the [dashboard](https://mapiron.com/dashboard). Every request takes it as `?key=ps_…` or as an `Authorization: Bearer ps_…` header. The base URL is `https://api.mapiron.com`.

```bash
curl "https://api.mapiron.com/v1/geocode?q=Oswego%20IL&limit=1&key=YOUR_KEY"
```

JavaScript:

```
const r = await fetch("https://api.mapiron.com/v1/geocode?q=" + encodeURIComponent("Oswego IL") + "&limit=1", {
  headers: { Authorization: "Bearer YOUR_KEY" }
});
const { features } = await r.json();
const [lng, lat] = features[0].geometry.coordinates;
```

Python:

```
import requests
r = requests.get("https://api.mapiron.com/v1/geocode", params={"q": "Oswego IL", "limit": 1},
                 headers={"Authorization": "Bearer YOUR_KEY"}, timeout=10)
lng, lat = r.json()["features"][0]["geometry"]["coordinates"]
```

PHP (for example in WordPress):

```
$url = "https://api.mapiron.com/v1/geocode?" . http_build_query(["q" => "Oswego IL", "limit" => 1, "key" => "YOUR_KEY"]);
$data = json_decode(file_get_contents($url), true);
[$lng, $lat] = $data["features"][0]["geometry"]["coordinates"];
```

## Static images

`GET /v1/static` returns an image. Give a `center` and `zoom`, or let us fit the view to your markers, path or area.

| Parameter | Meaning | Default |
| --- | --- | --- |
| `center` | `lat,lng` | fitted |
| `zoom` | 0 to 20, decimals allowed | fitted |
| `size` | `WIDTHxHEIGHT`, each 16 to 1280 | `600x400` |
| `scale` | `2` for high-density screens | `1` |
| `style` | `light`, `dark`, `white`, `grayscale` | `light` |
| `format` | `png`, `jpg`, `webp` | `png` |
| `markers` | Up to 25 points: `lat,lng\|lat,lng` |  |
| `marker_color` | Hex colour | `e11d48` |
| `path` | A line through 2 to 200 points: `lat,lng\|lat,lng\|…` |  |
| `path_color`, `path_width` | Hex colour; 1 to 12 px | `2563eb`, 4 |
| `padding` | Pixels kept clear around fitted content | 40 |

```html
<img src="https://api.mapiron.com/v1/static?markers=41.8781,-87.6298|41.6828,-88.3515&size=600x300&scale=2&key=YOUR_KEY"
     width="600" height="300" alt="Map from Chicago to Oswego">
```

Images are deterministic: the same URL gives the same picture, so cache them for as long as your plan allows. On the Free plan, images carry a small "Map by mapiron.com" mark in the bottom-left corner; paid plans have none.

## Privacy area mode

For listings, deliveries or anything where the exact address should stay private. Send the real point as `area`; we snap it to a grid, draw a shaded circle, and add no pin.

| Parameter | Meaning | Default |
| --- | --- | --- |
| `area` | The point as `lat,lng`, ideally already rounded to the grid (below) |  |
| `radius` | Circle radius in metres, 100 to 25000. Raised if needed so the circle always contains the real point. | 1000 |
| `snap` | Grid size in degrees, 0.005 to 0.1 (anything smaller, including 0, uses 0.005). 0.01 is about 1 km. | 0.01 |
| `color` | Hex colour of the circle | `0f766e` |

```
https://api.mapiron.com/v1/static?area=41.68,-88.35&size=640x300&key=YOUR_KEY
```

Try it without a key

Every address in the same grid cell gets the identical image, so viewers can't narrow the location down by comparing maps. Whatever you put in `area` is visible to anyone who views the page, so round it to the grid on your server first: `Math.round(lat / snap) * snap`, and the same for lng (41.6843 becomes 41.68 with the default 0.01). The image is identical, and the page shows only the grid point. See [privacy-safe listing maps](https://mapiron.com/privacy-maps) for a full walkthrough.

## Address search

`GET /v1/geocode?q=…` returns GeoJSON features, best match first. `/v1/autocomplete` takes the same parameters and suits type-ahead boxes; each call counts as one lookup, so wait for a short pause in typing (about 250 ms) before calling it.

| Parameter | Meaning |
| --- | --- |
| `q` | Text to search for (required) |
| `limit` | 1 to 20, default 5 |
| `lat`, `lon` | Prefer results near this point |
| `bbox` | `minLon,minLat,maxLon,maxLat` to restrict results |
| `lang` | `en`, `de`, `fr` or `default` (local names) |
| `layer` | Filter: `house`, `street`, `city`, `county`, `state`, `country` and more |

```bash
curl "https://api.mapiron.com/v1/geocode?q=4%20Yorkville%20Rd%20Oswego&limit=1&key=YOUR_KEY"
```

Try it without a key

```

```

Paid plans may store and reuse results indefinitely; Free results may be stored for up to 30 days. Each response carries a `license` field that says which applies. US house-number coverage follows OpenStreetMap and varies by area; street and town results are reliable everywhere.

## Reverse lookup

`GET /v1/reverse?lat=…&lon=…` returns the nearest address or place. Optional `radius` (km), `limit`, `lang`.

## Schools & districts

`GET /v1/schools?lat=…&lon=…` returns the US public school districts at a point and, grade by grade, the assigned public school with its attendance zone. It comes with platform and enterprise contracts, not with self-serve plans. See [Schools & districts](https://mapiron.com/docs/schools).

## Texas special districts

`GET /v1/districts?lat=…&lon=…` returns the Texas municipal utility districts, water control and improvement districts, management districts and PIDs that contain a point, with each district's self-reported tax rate and debt, its website and the statute for the purchaser's notice. Growth plans and up. See [Texas special districts](https://mapiron.com/docs/districts).

## Parcel lines

`GET /v1/parcels?lat=…&lon=…` returns the property parcel at a point: its boundary, the county parcel number (APN) and its area, from open government records. Draw parcel lines on static images with `parcels=1`, highlight one with `parcel=…`, or add the vector or raster parcel overlay to an interactive map. Growth plans and up. See [Parcel lines](https://mapiron.com/docs/parcels).

## Raster tiles

256-pixel PNG tiles, with `@2x` for sharp screens. Use them with Leaflet, OpenLayers or anything that takes an XYZ URL. A typical map view loads about 16 tiles.

```
L.tileLayer("https://api.mapiron.com/v1/tiles/light/{z}/{x}/{y}@2x.png?key=YOUR_KEY", {
  tileSize: 256, maxZoom: 19,
  attribution: '&copy; <a href="https://www.openstreetmap.org/copyright">OpenStreetMap contributors</a>'
}).addTo(map);
```

## Vector tiles & styles

For MapLibre GL, point the map at a style. Fonts, icons and tile URLs inside it already carry your key.

```
new maplibregl.Map({
  container: "map",
  style: "https://api.mapiron.com/v1/styles/light.json?key=YOUR_KEY",
  center: [-88.35, 41.68], zoom: 12
});
```

Styles: `light`, `dark`, `white`, `grayscale`. Raw tiles are at `/v1/tiles/vector/{z}/{x}/{y}.pbf` (Protomaps schema, zoom 0 to 15), described by `/v1/tiles/vector.json`.

## Keys & websites

Keys used in web pages are visible to visitors. In the dashboard, limit such a key to your websites (for example `example.com, *.example.com`); requests from other sites are refused. Keep an unrestricted key on your server only. Revoking a key takes effect within a minute. Free accounts have 1 key, the 14-day Growth trial 3, and paid plans up to 20.

## Plans, caps & errors

Each plan has a monthly cap per product (see [Pricing](https://mapiron.com/pricing)). Caps reset on the 1st of each month (UTC). We email the account at 80% and at 100% of a cap. Paid plans can raise a month's caps with a one-time top-up pack from the dashboard ($20 for 100,000 images, 100,000 lookups and 1,000,000 tiles; never automatic). The Free plan also allows 5 requests a second per account, with bursts up to 60, and the Growth trial 25 a second; paid plans have no per-second limit.

Errors are JSON with an `error` code and a readable `message` you can show to people. 429 answers carry `Retry-After` in seconds. Every code, with what to do about it: [openapi.json](https://mapiron.com/openapi.json) (`Error` schema).

| Status | `error` | Meaning and what to do |
| --- | --- | --- |
| 400 | `bad_request` | A parameter is missing, malformed or out of range, or the query string or path couldn't be parsed. Fix the request. Don't retry unchanged. |
| 401 | `missing_key` | A metered endpoint got no API key. Add the key. |
| 401 | `invalid_key` | The key is unknown, revoked, or is a management token (psm_) used on a map endpoint. Use a live ps_ key from the dashboard. |
| 403 | `referer_denied` | The key is limited to other websites and the request's Origin/Referer isn't one of them. Add the site to the key's websites in the dashboard, or use a server-side key. |
| 403 | `plan_upgrade_required` | A data product the plan doesn't include (parcel lines, Texas special districts on Free/Starter). Upgrade (Growth or higher). |
| 404 | `not_found` | No such path, tile, style, key, webhook, release or record (also every admin, edge and ops path to anyone not allowed to see it, so they look like unknown paths). Check the URL or ID. |
| 405 | `method_not_allowed` | The path exists but not with this HTTP method (also GET/DELETE on the MCP endpoint, which is POST-only). Use a method from the Allow header. |
| 409 | `privacy_mode_active` | A static map asked for parcel lines together with a privacy area. Drop one of the two. |
| 413 | `payload_too_large` | The request body is over the endpoint's size limit. Send a smaller body (split batches). |
| 415 | `unsupported_media_type` | A POST/PATCH endpoint that takes JSON got another Content-Type. Set Content-Type: application/json. |
| 422 | `invalid_body` | A JSON body is valid JSON but is missing a field or has a value of the wrong type. Fix the body. Don't retry unchanged. |
| 429 | `monthly_cap_reached` | The account's (scope account) or the key's own (scope key) hard monthly cap for this product is used up. Nothing is ever billed for overage. Includes `product`, `cap`, `resets`, `upgrade_url`, `scope`. Upgrade, buy a top-up pack, raise the key's cap, or wait for resets (1st of the month, UTC). |
| 429 | `slow_down` | A short-window rate limit: the Free/trial per-second limit, key creation rate, too many sign-in or checkout attempts, passkey requests, or downloads running at once. Wait for Retry-After (1 second for per-second limits; up to an hour for sign-in and checkout limits). |
| 429 | `daily_limit_reached` | A per-day limit: school-data pipeline downloads per licence, test-kit requests per address or network. Wait for Retry-After (up to 24 hours) or contact sales. |
| 500 | `internal` | A bug or database error on our side. The cause is logged on the server and never sent to the client. Retry once; if it persists, email support@mapiron.com with the time of the request. |
| 502 | `engine_error` | The map renderer or geocoder didn't answer (overloaded or restarting). Retry with backoff (1 s, 2 s, 4 s). |
| 503 | `unavailable` | A feature isn't configured or is switched off on this server (billing, email, a data release), or sign-ups are closed. Retry later or contact support. |

## Attribution

Map data comes from OpenStreetMap under the Open Database License. Show © OpenStreetMap contributors near any map or results you display, linked to [openstreetmap.org/copyright](https://www.openstreetmap.org/copyright). Static images already include it in the corner. MapIron is not affiliated with or endorsed by the OpenStreetMap Foundation.

---
Source: https://mapiron.com/docs · Map data © OpenStreetMap contributors · Index: https://mapiron.com/llms.txt
