# Hosted tile API

> Vector tiles from api.geolith.app (India tile set today; planet tiles in development): the india tile set, its layers and zooms, the TileJSON and tile endpoints, compression, caching and status codes.

api.geolith.app serves Mapbox Vector Tiles (India tile set today; planet tiles in development) from PMTiles archives that the [geolith builder](/builder) makes from OpenStreetMap and Overture Maps. Requests use the same API keys as geocoding: `?api_key=YOUR_API_KEY` or an `Authorization: Bearer YOUR_API_KEY` header. Get a key at [console.geolith.app/signup](https://console.geolith.app/signup).

## Endpoints

| Route                                 | Answer                                                                                |
| ------------------------------------- | ------------------------------------------------------------------------------------- |
| `GET /v1/tiles/{set}.json`            | TileJSON 3.0.0 for the tile set. Not counted against the tile allowance; rate limited |
| `GET /v1/tiles/{set}/{z}/{x}/{y}.mvt` | One vector tile. `.pbf` is the same tile                                              |

An unknown tile set answers `404 not_found`.

## Tile sets

Hosted tiles: India tile set today; planet tiles in development. The one tile set:

| Set     | Area                                 | Zooms   | Built from                                                                                   |
| ------- | ------------------------------------ | ------- | -------------------------------------------------------------------------------------------- |
| `india` | India (bounds 67.9, 6.4, 97.5, 37.2) | 0 to 15 | OpenStreetMap and Overture Maps, by the geolith builder (`geolith-india-2026-11-07.pmtiles`) |

The layers follow the Protomaps basemap schema:

| Layer        | Zooms    | Fields                                                                                                                                                             |
| ------------ | -------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `earth`      | 0 to 15  | `kind`, `name`                                                                                                                                                     |
| `water`      | 0 to 15  | `kind`, `kind_detail`, `name`                                                                                                                                      |
| `bathymetry` | 0 to 15  | `kind`, `depth`                                                                                                                                                    |
| `landcover`  | 0 to 15  | `kind`, `sort_key`                                                                                                                                                 |
| `landuse`    | 4 to 15  | `kind`, `name`                                                                                                                                                     |
| `boundaries` | 0 to 15  | `kind`, `kind_detail`, `name`, `disputed`, `claimed_by`, `disputed_by`                                                                                             |
| `roads`      | 3 to 15  | `kind` (`highway`, `major_road`, `minor_road`, …), `kind_detail`, `name`, `ref`, `network`, `oneway`, `is_bridge`, `is_tunnel`, `is_link`, `sort_rank`, `min_zoom` |
| `buildings`  | 11 to 15 | `kind`, `name`, `height`, `addr_housenumber`, `addr_street`                                                                                                        |
| `places`     | 5 to 15  | `kind`, `kind_detail`, `class`, `name`, `capital`, `population`, `population_rank`, `wikidata`, `min_zoom`                                                         |
| `pois`       | 10 to 15 | `kind`, `kind_detail`, `name`, `min_zoom`, and more by kind                                                                                                        |

The TileJSON lists every layer with its fields as `vector_layers`.

## TileJSON

```bash
curl "https://api.geolith.app/v1/tiles/india.json?api_key=YOUR_API_KEY"
```

```json
{
  "tilejson": "3.0.0",
  "name": "geolith",
  "scheme": "xyz",
  "tiles": [
    "https://api.geolith.app/v1/tiles/india/{z}/{x}/{y}.mvt?api_key=YOUR_API_KEY"
  ],
  "minzoom": 0,
  "maxzoom": 15,
  "bounds": [67.9, 6.4, 97.5, 37.2],
  "center": [82.7, 21.8, 7],
  "vector_layers": [
    {
      "id": "earth",
      "fields": { "kind": "String", "name": "String" },
      "minzoom": 0,
      "maxzoom": 15
    }
  ],
  "attribution": "© OpenStreetMap contributors (ODbL), Overture Maps Foundation"
}
```

(`vector_layers` is shortened here.) When you call it with an API key, the tile URL in `tiles` carries the same key, so a map library needs only the TileJSON URL. A request authenticated with an OAuth token gets a tile URL with no key in it.

## Tiles

```bash
curl -H "Accept-Encoding: gzip" -o tile.mvt.gz \
  "https://api.geolith.app/v1/tiles/india/10/723/454.mvt?api_key=YOUR_API_KEY"
```

| Response                                                      | When                                                      |
| ------------------------------------------------------------- | --------------------------------------------------------- |
| `200` with `Content-Type: application/vnd.mapbox-vector-tile` | The tile has data                                         |
| `204 No Content`                                              | The tile is empty, or the zoom is outside the set's zooms |
| `400` with `error.code` `tile_error`                          | `x` or `y` is out of range for `z`                        |

- **Compression.** Clients that send `Accept-Encoding: gzip` (every browser does) get the tile gzipped with `Content-Encoding: gzip`; other clients get it uncompressed. Responses carry `Vary: Accept-Encoding`.
- **Caching.** Tiles carry `Cache-Control: public, max-age=86400`: browsers and CDNs may keep them for a day.
- **CORS.** Every answer allows any origin (`Access-Control-Allow-Origin: *`). A publishable key still answers only the origins it lists; see [Keys and limits](/tiles/hosted/limits).
- **Quota headers.** Every tile answer carries `X-Quota-Product: tiles`, `X-Quota-Limit` and `X-Quota-Remaining` for the monthly tile allowance.

## Attribution

Show `© OpenStreetMap contributors (ODbL), Overture Maps Foundation` on every map that uses these tiles. The TileJSON `attribution` field holds it, and MapLibre shows it in the attribution control.

## Next

- [MapLibre](/tiles/hosted/maplibre): the tile set on a map.
- [Keys and limits](/tiles/hosted/limits): allowances, rate limits and errors.
