1Create an API key

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.

2Authentication

Every request is authenticated with a key parameter appended to the URL. No custom header, no signature to compute:

GEThttps://tiles.tile.cat/styles/default.json?key=YOUR_KEY

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.

3API reference

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

Billing: TileCat meters map loads, not individual requests. Loading a style counts as one load; every tile, sprite, and glyph request that follows for that map isn't billed separately — whether your map fetches 20 tiles or 200 at a given zoom.

Styles

Returns a style document compatible with the MapLibre/Mapbox GL spec, ready to pass directly as style to your map.

GET/styles/{style}.json?key=YOUR_KEY

{style} is default or dark (the dark counterpart of the default style, built for a site or app running in dark mode).

Vector tiles

The raw tiles referenced by the styles above. Useful if you're building your own style rather than using one of ours.

GET/data/planet/{z}/{x}/{y}.pbf?key=YOUR_KEY

Sprites & fonts

Referenced automatically by the style JSON — you normally don't need to call these yourself.

GET/sprites/{style}/sprite.json?key=YOUR_KEY
GET/fonts/{fontstack}/{range}.pbf?key=YOUR_KEY

4MapLibre GL JS integration

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
});

5Leaflet integration

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

6No-code embed

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>
AttributeDescription
data-keyYour API key (required)
data-lat / data-lng / data-zoomInitial map center and zoom
data-styledefault or dark (default: default)
data-heightHeight of the created container (default: 400px)
data-targetCSS selector of an existing element to use instead of creating a new one

7Limits & errors

Every response carries two headers so you can track your usage in real time, without going back to the dashboard:

HeaderDescription
X-TileCat-Quota-LimitYour plan's total monthly quota
X-TileCat-Quota-RemainingLoads left before the month resets

Plans and limits:

PlanMonthly quotaBehavior beyond quota
Free50,000429 until next month
Growth1,000,000429, one-click upgrade from the dashboard
EnterpriseNegotiatedCustom SLA, no surprise cutoff

Error codes:

CodeMeaning
400Invalid parameter (zoom, tile coordinates…)
401Missing or invalid key
403Valid key, but origin/domain not allowed
404Style or tile not found at this zoom level
429Monthly 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.