Sign up for free and grab your key from the dashboard. The free tier includes 50,000 map loads a month, free forever, no credit card required. No sales email, no demo call to book.
Every request is authenticated with a key parameter appended to the URL. No custom header, no signature to compute:
A key can be restricted to one or more origins (your domain, your mobile app) from the dashboard — so you can expose it client-side without risking it being reused elsewhere. An unrestricted key should never be committed to a public repo.
Every route accepts the key parameter and returns JSON, MVT (Mapbox Vector Tile), or PNG depending on the endpoint. Base URL: https://tiles.tile.cat
Returns a style document compatible with the MapLibre/Mapbox GL spec, ready to pass directly as style to your map.
{style} is default or dark (the dark counterpart of the default style, built for a site or app running in dark mode).
The raw tiles referenced by the styles above. Useful if you're building your own style rather than using one of ours.
Referenced automatically by the style JSON — you normally don't need to call these yourself.
Install the library, then initialize the map with your key.
// npm install maplibre-gl import maplibregl from 'maplibre-gl'; new maplibregl.Map({ container: 'map', style: 'https://tiles.tile.cat/styles/default.json?key=YOUR_KEY', center: [2.3522, 48.8566], zoom: 11 });
Leaflet doesn't speak vector natively: use the @maplibre/maplibre-gl-leaflet plugin, which renders a TileCat style (vector) directly inside a Leaflet map.
// npm install leaflet maplibre-gl @maplibre/maplibre-gl-leaflet const map = L.map('map').setView([48.8566, 2.3522], 11); L.maplibreGL({ style: 'https://tiles.tile.cat/styles/default.json?key=YOUR_KEY', }).addTo(map);
No JavaScript to write: one <script> tag is enough. It creates the map container right after itself on the page, and loads MapLibre GL JS on its own if needed.
<script src="https://tile.cat/embed.js" data-key="YOUR_KEY" data-lat="48.8566" data-lng="2.3522" data-zoom="11" data-height="400px" ></script>
| Attribute | Description |
|---|---|
data-key | Your API key (required) |
data-lat / data-lng / data-zoom | Initial map center and zoom |
data-style | default or dark (default: default) |
data-height | Height of the created container (default: 400px) |
data-target | CSS selector of an existing element to use instead of creating a new one |
Every response carries two headers so you can track your usage in real time, without going back to the dashboard:
| Header | Description |
|---|---|
X-TileCat-Quota-Limit | Your plan's total monthly quota |
X-TileCat-Quota-Remaining | Loads left before the month resets |
Plans and limits:
| Plan | Monthly quota | Behavior beyond quota |
|---|---|---|
| Free | 50,000 | 429 until next month |
| Growth | 1,000,000 | 429, one-click upgrade from the dashboard |
| Enterprise | Negotiated | Custom SLA, no surprise cutoff |
Error codes:
| Code | Meaning |
|---|---|
| 400 | Invalid parameter (zoom, tile coordinates…) |
| 401 | Missing or invalid key |
| 403 | Valid key, but origin/domain not allowed |
| 404 | Style or tile not found at this zoom level |
| 429 | Monthly plan quota reached |
A 429 response means the free tier's monthly quota has been reached. Upgrade to the Growth plan from the dashboard to lift the limit, with no service interruption.