# Map Tile API
> The maths behind every web map. Convert between latitude/longitude, slippy-map XYZ tile coordinates (the z/x/y scheme used by OpenStreetMap, Google Maps, Mapbox and Leaflet) and Bing/Azure quadkeys, and get the exact Web Mercator (EPSG:3857) bounding box and centre of any tile. Find which tile contains a point at a given zoom, expand a tile to its geographic bounds, translate a quadkey to z/x/y and back, and list a tile's eight neighbours (with correct antimeridian wrap-around and pole clamping). Perfect for tile servers and caches, pre-fetching map tiles, drawing tile grids and debugging map layers. Pure local computation — no key, no third-party service, instant. Live, nothing stored. 5 endpoints. Distinct from coordinate-format conversion (Plus Code/MGRS/UTM), geohash and the encoded-polyline codec.

## Authentication
All requests require your oanor API key in the `x-oanor-key` header. Get one at https://www.oanor.com/developer/keys.

```bash
curl -H "x-oanor-key: oanor_live_…" "https://api.oanor.com/maptile-api/..."
```

## Pricing
- **Free** (Free) — 1,040 calls/Mo, 2 req/s
- **Starter** ($3/Mo) — 8,900 calls/Mo, 8 req/s
- **Pro** ($22/Mo) — 139,000 calls/Mo, 20 req/s
- **Mega** ($58/Mo) — 715,000 calls/Mo, 50 req/s

## Endpoints

### Tiles

#### `GET /v1/from-latlng` — Lat/lng to tile + quadkey

**Parameters:**
- `lat` (query, required, string) — Latitude (±85.05) Example: `52.5163`
- `lng` (query, required, string) — Longitude Example: `13.3777`
- `zoom` (query, required, string) — Zoom 0-30 Example: `12`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/maptile-api/v1/from-latlng?lat=52.5163&lng=13.3777&zoom=12"
```

**Response:**
```json
{
    "data": {
        "x": 2200,
        "y": 1343,
        "lat": 52.5163,
        "lng": 13.3777,
        "zoom": 12,
        "quadkey": "120210233222",
        "tile_count_per_axis": 4096
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:49.476Z",
        "request_id": "7bb94cda-884d-457f-84c8-f1da41b46748"
    },
    "status": "ok",
    "message": "Lat/lng to tile + quadkey",
    "success": true
}
```

#### `GET /v1/neighbors` — Neighbouring tiles

**Parameters:**
- `x` (query, required, string) — Tile X Example: `2200`
- `y` (query, required, string) — Tile Y Example: `1343`
- `zoom` (query, required, string) — Zoom 0-30 Example: `12`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/maptile-api/v1/neighbors?x=2200&y=1343&zoom=12"
```

**Response:**
```json
{
    "data": {
        "x": 2200,
        "y": 1343,
        "zoom": 12,
        "neighbors": {
            "e": {
                "x": 2201,
                "y": 1343,
                "z": 12,
                "quadkey": "120210233223"
            },
            "n": {
                "x": 2200,
                "y": 1342,
                "z": 12,
                "quadkey": "120210233220"
            },
            "s": {
                "x": 2200,
                "y": 1344,
                "z": 12,
                "quadkey": "120212011000"
            },
            "w": {
                "x": 2199,
                "y": 1343,
                "z": 12,
                "quadkey": "120210232333"
            },
            "ne": {
                "x": 2201,
                "y": 1342,
                "z": 12,
                "quadkey": "120210233221"
            },
            "nw": {
                "x": 2199,
                "y": 1342,
                "z": 12,
                "quadkey": "120210232331"
            },
            "se": {
                "x": 2201,
                "y": 1344,
                "z": 12,
                "quadkey": "120212011001"
            },
            "sw": {
                "x": 2199,
                "y": 1344,
                "z": 12,
                "quadkey": "120212010111"
            }
        }
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:49.583Z",
        "request_id": "0a1d6901-5b12-431e-8141-8cad504c2001"
    },
    "status"
…(truncated, see openapi.json for full schema)
```

#### `GET /v1/quadkey` — Tile <-> quadkey

**Parameters:**
- `quadkey` (query, optional, string) — Quadkey (digits 0-3) Example: `120210233222`
- `x` (query, optional, string) — Tile X (alt)
- `y` (query, optional, string) — Tile Y (alt)
- `zoom` (query, optional, string) — Zoom (alt)

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/maptile-api/v1/quadkey?quadkey=120210233222"
```

**Response:**
```json
{
    "data": {
        "x": 2200,
        "y": 1343,
        "z": 12,
        "bbox": {
            "east": 13.447266,
            "west": 13.359375,
            "north": 52.536273,
            "south": 52.48278,
            "center": {
                "lat": 52.509527,
                "lng": 13.40332
            }
        },
        "quadkey": "120210233222"
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:49.670Z",
        "request_id": "04269951-237b-4a10-b987-3423f646239b"
    },
    "status": "ok",
    "message": "Tile <-> quadkey",
    "success": true
}
```

#### `GET /v1/to-bbox` — Tile to bounding box

**Parameters:**
- `x` (query, required, string) — Tile X Example: `2200`
- `y` (query, required, string) — Tile Y Example: `1343`
- `zoom` (query, required, string) — Zoom 0-30 Example: `12`

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/maptile-api/v1/to-bbox?x=2200&y=1343&zoom=12"
```

**Response:**
```json
{
    "data": {
        "x": 2200,
        "y": 1343,
        "bbox": {
            "east": 13.447266,
            "west": 13.359375,
            "north": 52.536273,
            "south": 52.48278,
            "center": {
                "lat": 52.509527,
                "lng": 13.40332
            }
        },
        "zoom": 12,
        "quadkey": "120210233222"
    },
    "meta": {
        "timestamp": "2026-06-02T16:51:49.769Z",
        "request_id": "7140d006-a984-4b66-b72d-83cdd1be04e5"
    },
    "status": "ok",
    "message": "Tile to bounding box",
    "success": true
}
```

### Meta

#### `GET /v1/meta` — Spec

**Example:**
```bash
curl -H "x-oanor-key: $KEY" \
  "https://api.oanor.com/maptile-api/v1/meta"
```

**Response:**
```json
{
    "data": {
        "name": "Map Tile API",
        "notes": "Latitude is limited to the Web Mercator range ±85.05112878°. Tile scheme matches OpenStreetMap / Google / Mapbox XYZ.",
        "version": "v1",
        "endpoints": [
            {
                "path": "/v1/from-latlng",
                "params": {
                    "lat": "required",
                    "lng": "required",
                    "zoom": "0-30, required"
                },
                "returns": "tile x/y/z + quadkey"
            },
            {
                "path": "/v1/to-bbox",
                "params": {
                    "x": "required",
                    "y": "required",
                    "zoom": "required"
                },
                "returns": "tile bounding box (N/S/E/W) + center + quadkey"
            },
            {
                "path": "/v1/quadkey",
                "params": {
                    "quadkey": "string of 0-3, OR",
                    "x_y_zoom": "tile coords"
                },
                "returns": "tile <-> quadkey (bidirectional)"
            },
            {
                "path": "/v1/neighbors",
                "params": {
                    "x": "required",
                    "y": "required",
                    "zoom": "required"
                },
                "returns": "8 neighbouring tiles (x wraps, poles clamped)"
            },
            {
                "path": "/v1/meta",
                "params": [],
        
…(truncated, see openapi.json for full schema)
```


---
Marketplace page: https://www.oanor.com/api/maptile-api
OpenAPI spec: https://www.oanor.com/api/maptile-api/openapi.json
