Tileset API

Estimated reading time: 10 minutes

The Tileset API lets you create and manage your own tilesets. A tileset is a collection of raster or vector tiles that can be displayed on a map. Each tileset can have an optional TileJSON descriptor and a Recipe that defines how its tiles are generated.

Tileset object

{
  "id": "3c2de33f-7e88-4ecb-941c-0fece5ed0434",
  "ownerId": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "creationDate": "2024-01-15T10:30:00Z",
  "createdBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "lastUpdate": "2024-01-15T10:30:00Z",
  "updatedBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "private": true,
  "ttl": null
}
Field Type Description
id string Unique identifier of the tileset.
ownerId UUID UUID of the account that owns the tileset.
creationDate datetime ISO 8601 timestamp of when the tileset was created.
createdBy UUID UUID of the identity that created the tileset.
lastUpdate datetime ISO 8601 timestamp of the last modification.
updatedBy UUID UUID of the identity that last modified the tileset.
private boolean Whether the tileset is private.
ttl integer Time To Live in seconds. After this delay the tileset and all its sub-resources are deleted automatically. null means no expiry.

Access Token

Before accessing the Tileset API, you need a valid access token. You can get your access tokens in your Jawg App account.

All requests must include the access-token query parameter:

https://api.jawg.io/tilesets?access-token={your-access-token}

Create a tileset

Creates a new tileset and returns it with its generated id.

POST https://api.jawg.io/tilesets?access-token={your-access-token}

Request body

{
  "id": "my-tileset",                                 // optional — generated if absent
  "ownerId": "258728f5-cb37-491f-b345-eb2d6868cdd3",  // optional
  "ttl": 3600                                         // optional — seconds until auto-deletion
}
Field Type Required Description
id string No Desired tileset identifier. A UUID is generated if absent.
ownerId UUID No Owner of the tileset. Defaults to the authenticated user's account.
ttl integer No Time To Live in seconds. The tileset and all its sub-resources are deleted after this delay. Useful for preview tilesets.

Response

// HTTP 201 Created
// Location: /tilesets/3c2de33f-7e88-4ecb-941c-0fece5ed0434

{
  "id": "3c2de33f-7e88-4ecb-941c-0fece5ed0434",
  "ownerId": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "creationDate": "2024-01-15T10:30:00Z",
  "createdBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "lastUpdate": "2024-01-15T10:30:00Z",
  "updatedBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "private": true,
  "ttl": null
}

Error codes

HTTP Description
400 The request body is invalid.
403 The authenticated identity does not have the required permission.

Retrieve a tileset

Returns the tileset with the given id.

GET https://api.jawg.io/tilesets/{id}?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Response

// HTTP 200 OK

{
  "id": "3c2de33f-7e88-4ecb-941c-0fece5ed0434",
  "ownerId": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "creationDate": "2024-01-15T10:30:00Z",
  "createdBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "lastUpdate": "2024-01-15T10:30:00Z",
  "updatedBy": "258728f5-cb37-491f-b345-eb2d6868cdd3",
  "private": true,
  "ttl": null
}

Error codes

HTTP Description
404 No tileset found with the given id.

Delete a tileset

Deletes the tileset with the given id. This also removes its associated TileJSON and Recipe.

DELETE https://api.jawg.io/tilesets/{id}?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Response

HTTP 204 No Content

Error codes

HTTP Description
404 No tileset found with the given id.

TileJSON

A TileJSON is a JSON document that describes a tileset: its tile URL template, zoom range, bounds, and other metadata. It is the standard way to configure a tile source in MapLibre GL JS.

The TileJSON is optional. If no TileJSON has been set for a tileset, the endpoint returns HTTP 404 Not Found.

See the latest version of TileJSON specification for more details.

Retrieve the TileJSON

Returns the TileJSON descriptor for the tileset with the given id.

GET https://api.jawg.io/tilesets/{id}.json?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

The id parameter can be a concatenation of multiple ids separated by a + character.

Query parameters

  • size optional (integer): The size of the tiles in pixels. Mostly useful for raster tiles.
  • scale optional (integer): The pixel density scale factor for the tiles. Useful for high-DPI displays with raster tiles. Valid values are 1 and 2.
  • format optional (string): The format of the tiles. Examples: pbf, png.
  • lang optional (string): The language of the tile labels. Useful for raster tiles since vector tiles can choose the displayed language client-side. Valid values are de, en, es, fr, it, ja, ko, nl, ru, zh. Use int for international labels.

Example request

GET https://api.jawg.io/tilesets/3c2de33f-7e88-4ecb-941c-0fece5ed0434.json?access-token={your-access-token}

Response

// HTTP 200 OK

{
  "tilejson": "3.0.0",
  "name": "My tileset",
  "description": "A description of my tileset",
  "version": "1.0.0",
  "attribution": "© Jawg",
  "scheme": "xyz",
  "tiles": [
    "https://tile.jawg.io/3c2de33f-7e88-4ecb-941c-0fece5ed0434/{z}/{x}/{y}.pbf?access-token={your-access-token}"
  ],
  "minzoom": 0,
  "maxzoom": 14,
  "bounds": [-180, -85.05113, 180, 85.05113],
  "center": [0, 0, 2]
}

Error codes

HTTP Description
404 No TileJSON has been set for this tileset.
404 No tileset found with the given id.

Update the TileJSON

Creates or replaces the TileJSON descriptor for the tileset with the given id.

PUT https://api.jawg.io/tilesets/{id}.json?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Request body

The body must be a valid TileJSON object.

{
  "tilejson": "3.0.0",
  "name": "My tileset",
  "description": "A description of my tileset",
  "version": "1.0.0",
  "attribution": "© Jawg",
  "scheme": "xyz",
  "tiles": [
    "https://tile.jawg.io/3c2de33f-7e88-4ecb-941c-0fece5ed0434/{z}/{x}/{y}.pbf?access-token={your-access-token}"
  ],
  "minzoom": 0,
  "maxzoom": 14,
  "bounds": [-180, -85.05113, 180, 85.05113],
  "center": [0, 0, 2]
}

Response

// HTTP 200 OK

{
  "tilejson": "3.0.0",
  "name": "My tileset",
  "description": "A description of my tileset",
  "version": "1.0.0",
  "attribution": "© Jawg",
  "scheme": "xyz",
  "tiles": [
    "https://tile.jawg.io/3c2de33f-7e88-4ecb-941c-0fece5ed0434/{z}/{x}/{y}.pbf?access-token={your-access-token}"
  ],
  "minzoom": 0,
  "maxzoom": 14,
  "bounds": [-180, -85.05113, 180, 85.05113],
  "center": [0, 0, 2]
}

Error codes

HTTP Description
404 No tileset found with the given id.

Recipe

A Recipe is a JSON document that describes how a tileset's tiles are generated: the data sources, layers, zoom ranges, and rendering rules.

The Recipe is optional. If no recipe has been set for a tileset, the endpoint returns HTTP 404 Not Found.

Retrieve the recipe

Returns the recipe for the tileset with the given id.

GET https://api.jawg.io/tilesets/{id}/recipe?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Response

// HTTP 200 OK

{
  "version": "1",
  "layers": {
    "bus-stops": [
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 12,
        "maxZoom": 16
      }
    ]
  }
}

Error codes

HTTP Description
404 No recipe has been set for this tileset.
404 No tileset found with the given id.

Update the recipe

Creates or replaces the recipe for the tileset with the given id.

PUT https://api.jawg.io/tilesets/{id}/recipe?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Request body

The body must be a valid Recipe object. See the Recipe Specification for the full format.

{
  "version": "1",
  "layers": {
    "bus-stops": [
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 12,
        "maxZoom": 16
      }
    ]
  }
}

Response

// HTTP 200 OK

{
  "version": "1",
  "layers": {
    "bus-stops": [
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 12,
        "maxZoom": 16
      }
    ]
  }
}

Error codes

HTTP Description
400 The recipe body is invalid.
404 No tileset found with the given id.

Delete the recipe

Removes the recipe from the tileset with the given id. The tileset itself is not deleted.

DELETE https://api.jawg.io/tilesets/{id}/recipe?access-token={your-access-token}

Path parameters

  • id required: The unique identifier of the tileset.

Response

HTTP 204 No Content

Error codes

HTTP Description
404 No tileset found with the given id.

Recipe Specification

A Recipe is a JSON document that describes how to transform feature collections into vector tiles. It defines the layers of the output tileset, where features come from, how they are filtered and transformed, and how the tiles are built.

Top-level structure

Field Type Description
version string Recipe schema version. Must be "1".
layers object Map of layer name → array of layer definitions. Keys become the vector tile layer names.
{
  "version": "1",
  "layers": {
    "bus-stops": [ ... ],
    "train-stations": [ ... ]
  }
}

Layer

Each entry in layers is an array of layer definitions (a layer group). Using multiple definitions under the same name lets you apply different rules at different zoom levels.

Field Type Required Description
sources array Yes Feature sources to read from.
minZoom integer Yes Minimum zoom level (inclusive) at which this layer is generated.
maxZoom integer Yes Maximum zoom level (inclusive) at which this layer is generated.
features object No Input feature configuration (filtering, property transforms, etc.).
tiles object No Tile-level configuration (extent, buffer, density, aggregation, etc.).
{
  "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
  "minZoom": 9,
  "maxZoom": 14,
  "features": { ... },
  "tiles": { ... }
}

Layer group — different rules per zoom range

{
  "version": "1",
  "layers": {
    "bus-stops": [
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 8,
        "maxZoom": 11
      },
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 12,
        "maxZoom": 16,
        "features": { ... },
        "tiles": { ... }
      }
    ]
  }
}

Source

A source defines where to read features from. Multiple sources can be listed in one layer and their features are merged. Currently, only the fs2 (FeatureStorageService) sources are supported.

fs2 source — FeatureStorageService

Reads features from a Feature Collection.

Field Type Description
type string Must be "fs2".
collectionId string Identifier of the feature collection to read.
{ "type": "fs2", "collectionId": "my-bus-stops" }

Feature configuration (features)

Controls how source features are processed before being added to tiles.

Field Type Description
filter expression Filter which features are included. Must evaluate to a boolean. Features that evaluate to false are discarded.
properties object Controls how feature properties are modified.
geometries array Controls geometry transformations applied to features.
simplification number Distance tolerance for Douglas-Peucker simplification. Value is relative to the tile extent.
limit integer Maximum number of input features to process.

Filter

The filter field is a MapLibre Expression that returns a boolean. Features where the expression evaluates to false are discarded.

{
  "filter": [
    "all",
    ["==", ["geometry-type"], "Point"],
    ["==", ["get", "type"], "shop"]
  ]
}

Properties — put

The properties.put map adds or replaces feature properties using expressions. Keys are the property names to write, values are literal values or MapLibre Expressions.

{
  "put": {
    "rank": ["match", ["get", "type"], "oak", 1, "birch", 1, "willow", 2, 4],
    "count": 1
  }
}

Geometries — center transformation

The geometries array applies geometry transformations. The center transformation reduces any geometry to a single representative point: unchanged for Point / MultiPoint, midpoint for LineString / MultiLineString, and a point-on-surface for Polygon / MultiPolygon.

{
  "geometries": [
    { "type": "center" }
  ]
}

Tile configuration (tiles)

Controls how the vector tile is built from the processed features.

Field Type Required Description
extent integer Yes Tile coordinate extent. Typical value: 4096.
buffer number Yes Tile buffer as a percentage of the extent. Avoids labels and geometries clipping at tile edges.
layerSize integer Yes Maximum layer size in bytes.
limit integer No Maximum number of features in the tile. Features are dropped once the limit is reached.
density object No Limits feature density by dividing the tile into a grid and capping features per cell.
aggregate object No Aggregates features by merging their geometries and combining their properties.
{
  "extent": 4096,
  "buffer": 10.0,
  "layerSize": 500000,
  "limit": 100000,
  "density": { ... },
  "aggregate": { ... }
}

Density

Divides the tile into a grid and limits how many features can appear in each cell. Useful for thinning out point datasets at low zoom levels.

Field Type Required Description
limit integer Yes Maximum number of features per grid cell.
size integer Yes Grid cell size in tile extent units. A size of 32 over a 4096-extent tile creates a 128×128 grid.
groupBy expression No Apply the density reduction per group. Typical use-case: group by level so features at different levels don't compete for the same cell. Default: no grouping.
global boolean No If true, the density limit is shared across all layers in the tile. Default: false (limit is local to the layer).
{
  "limit": 256,
  "size": 64,
  "groupBy": ["get", "level"],
  "global": true
}

Aggregation

Merges features together before writing them to the tile. This is useful to cluster points or union geometries.

Field Type Required Description
groupBy array No Property keys to group features by before aggregating. Features with the same values are merged.
geometry object Yes Geometry aggregation definition.
properties object No Property aggregation functions. Keys are property names, values are aggregation functions.

Properties not listed in groupBy nor in properties are removed from aggregated features.

Geometry aggregation — cluster

Merges nearby points into a single centroid and records the count.

Field Type Description
type string Must be "cluster".
size number Size of one cluster cell, relative to the tile extent.
property string Name of the property that will hold the cluster count.
{ "type": "cluster", "size": 512.0, "property": "count" }

Geometry aggregation — union

Merges line and polygon geometries that are close to each other.

Field Type Description
type string Must be "union".
threshold number Distance at which two geometries are considered touching.
{ "type": "union", "threshold": 0.5 }

Property aggregation functions

Valid values are sum, min, max, mean.

{
  "price": "mean",
  "length": "sum"
}

Complete example

{
  "version": "1",
  "layers": {
    "bus-stops": [
      {
        "sources": [ { "type": "fs2", "collectionId": "my-bus-stops" } ],
        "minZoom": 9,
        "maxZoom": 14,
        "features": {
          "filter": [
            "all",
            ["==", ["geometry-type"], "Point"],
            ["match", ["get", "line_number"], ["80", "82", "84"], true, false]
          ],
          "properties": {
            "put": {
              "rank": ["match", ["get", "speed"], "fast", 1, "medium", 2, "low", 3, 4],
              "count": 1
            }
          },
          "simplification": 4,
          "limit": 100000
        },
        "tiles": {
          "extent": 4096,
          "buffer": 10.0,
          "layerSize": 500000,
          "limit": 100000,
          "density": {
            "limit": 256,
            "size": 64
          },
          "aggregate": {
            "groupBy": ["line_number"],
            "geometry": {
              "type": "cluster",
              "size": 512.0,
              "property": "count"
            },
            "properties": {
              "price": "mean",
              "length": "sum"
            }
          }
        }
      }
    ]
  }
}