API Documentation

Introduction

Within this page you will find all the necessary informations and examples to integrate MapBolt services seamlessly in your applications.

In case you need additional support, don't hesitate to contact us!

Authentication

After validating your subscription, you will need to use your api key (available at the dashboard > API Key section) to make requests. This is the standard way an API can identify which customer you are.

This API Key needs to stay secret, DO NOT show it publically as you could lose your monthly requests or get charged additionnal fees if you have activated the auto-upgrade feature (check documentation here).

Request Structure

All the requests you make to our services have to be in this format:

https://mapbolt.com/api/<category>/<endpoint>?<query_params>&key=<API_KEY>

The category represents one of the four services we provide which are maps, geocoding, routing and data. The endpoints supply a set of features that are each described under their category. The query_params are all the options (mandatory or not) you can add to the query in order to obtain results matching your expectations.

Maps API

GET /tiles/{z}/{x}/{y}
Returns vector tiles at specified zoom level and position coordinates.

Parameters

Parameter Type Description
z integer Zoom level
x integer X coordinate
y integer Y coordinate
In order to use MapLibre's SDK like follows, you must create a style in your Dashboard. This is necessary if you wish to integrate your customized styles to your map. However, if you only need vector tiles without styling, you can simply use the "/{z}/{x}/{y}" endpoint without creating a style.

Flutter Integration

You can quickly integrate a map to your flutter application with our API's. For that we recommend to use the Maplibre plugin for flutter for its great stability and unmatched speed.

Here's the code for a widget that displays a map on your app:


import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:http/http.dart' as http;
import 'package:maplibre_gl/maplibre_gl.dart';

void main() {
  runApp(const MyApp());
}

class MyApp extends StatelessWidget {
  const MyApp({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Mapbolt Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: const MapScreen(),
    );
  }
}

class MapScreen extends StatefulWidget {
  const MapScreen({super.key});

  @override
  State createState() => _MapScreenState();
}

class _MapScreenState extends State {
  String _styleString = '';
  MaplibreMapController? _mapController;

  @override
  void initState() {
    super.initState();
    _loadStyleFromAssets();
  }

  Future _loadStyleFromAssets() async {
    try {
      final styleContent = await rootBundle.loadString(
          'https://mapbolt.com/api/maps/style?name=&api_key='
      );
      setState(() {
        _styleString = styleContent;
      });
    } catch (e) {
      print("Error loading style: $e");
    }
  }

  void _onMapCreated(MaplibreMapController controller) {
    _mapController = controller;
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: const Text('Mapbolt Map'),
      ),
      body: _styleString == null
          ? const Center(child: CircularProgressIndicator())
          : MaplibreMap(
        styleString: _styleString,
        initialCameraPosition: const CameraPosition(
          target: LatLng(50.54664, 4.375495), // Center of Belgium
          zoom: 7.0,
        ),
        onMapCreated: _onMapCreated,
        myLocationEnabled: true,
        trackCameraPosition: true,
        minMaxZoomPreference: const MinMaxZoomPreference(0, 18),
        tiltGesturesEnabled: true,
        rotateGesturesEnabled: true,
      ),
    );
  }
}

Android Integration

We recommand using MapLibre SDK on your android's app. Below is an example code of a basic Mapview using the stylesheet of your choice. Note that you need to install and configure your android project to support MapLibre SDK integration first.

Documentation on that can be found at the following: https://maplibre.org/maplibre-native/android/examples/getting-started/


import androidx.appcompat.app.AppCompatActivity
import android.os.Bundle
import android.view.LayoutInflater
import org.maplibre.android.MapLibre
import org.maplibre.android.camera.CameraPosition
import org.maplibre.android.geometry.LatLng
import org.maplibre.android.maps.MapView

class MainActivity : AppCompatActivity() {

    // Declare a variable for MapView
    private lateinit var mapView: MapView

    override fun onCreate(savedInstanceState: Bundle?) {
        super.onCreate(savedInstanceState)

        // Init MapLibre
        MapLibre.getInstance(this)

        // Init layout view
        val inflater = LayoutInflater.from(this)
        val rootView = inflater.inflate(R.layout.activity_main, null)
        setContentView(rootView)

        // Init the MapView
        mapView = rootView.findViewById(R.id.mapView)
        mapView.getMapAsync { map ->
            map.setStyle("https://demotiles.maplibre.org/style.json")
            map.cameraPosition = CameraPosition.Builder().target(LatLng(0.0,0.0)).zoom(1.0).build()
        }
    }

    override fun onStart() {
        super.onStart()
        mapView.onStart()
    }

    override fun onResume() {
        super.onResume()
        mapView.onResume()
    }

    override fun onPause() {
        super.onPause()
        mapView.onPause()
    }

    override fun onStop() {
        super.onStop()
        mapView.onStop()
    }

    override fun onLowMemory() {
        super.onLowMemory()
        mapView.onLowMemory()
    }

    override fun onDestroy() {
        super.onDestroy()
        mapView.onDestroy()
    }

    override fun onSaveInstanceState(outState: Bundle) {
        super.onSaveInstanceState(outState)
        mapView.onSaveInstanceState(outState)
    }
}

iOS Integration

Integrate maps into your iOS application using MapLibre's SDK for iOS. The example below shows how to create a basic map view in Swift. You'll need to install and configure the MapLibre SDK first.


import UIKit
import MapLibre

class MapViewController: UIViewController {

    var mapView: MLNMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // Initialize the map view
        mapView = MLNMapView(frame: view.bounds)
        mapView.autoresizingMask = [.flexibleWidth, .flexibleHeight]

        // Set map style URL
        let styleURL = URL(string: "https://mapbolt.com/api/maps/style?name=&api_key=")
        mapView.styleURL = styleURL

        // Set initial position
        let initialPosition = CLLocationCoordinate2D(latitude: 50.54664, longitude: 4.375495) // Center of Belgium
        mapView.setCenter(initialPosition, zoomLevel: 7, animated: false)

        // Add map view to the view controller
        view.addSubview(mapView)

        // Enable user location tracking
        mapView.showsUserLocation = true
        mapView.userTrackingMode = .follow
    }

    override func viewWillAppear(_ animated: Bool) {
        super.viewWillAppear(animated)
        mapView.styleURL = mapView.styleURL // Refresh style
    }

    // Add annotations to the map
    func addAnnotation(at coordinate: CLLocationCoordinate2D, title: String) {
        let annotation = MLNPointAnnotation()
        annotation.coordinate = coordinate
        annotation.title = title
        mapView.addAnnotation(annotation)
    }

    // Add a custom marker to the map
    func addCustomMarker(at coordinate: CLLocationCoordinate2D) {
        let marker = MLNMarker()
        marker.position = coordinate
        marker.icon = MLNIcon(image: UIImage(named: "custom-marker")!)
        marker.title = "Custom Marker"
        marker.map = mapView
    }
}

Web Integration

Integrate MapBolt maps into your web application using MapLibre GL JS. This lightweight JavaScript library allows you to display interactive maps with vector tiles and custom styling.

Below is a simple example of how to integrate a MapLibre map in a web page using HTML, CSS, and JavaScript:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>MapBolt Web Integration</title>

    <!-- MapLibre GL JS CSS -->
    <link href="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.css" rel="stylesheet" />

    <style>
        body {
            margin: 0;
            padding: 0;
        }

        #map {
            position: absolute;
            top: 0;
            bottom: 0;
            width: 100%;
            height: 100%;
        }

        .map-overlay {
            position: absolute;
            top: 10px;
            left: 10px;
            background: rgba(255, 255, 255, 0.8);
            padding: 10px;
            border-radius: 4px;
            z-index: 1;
            font-family: Arial, sans-serif;
        }

        .map-overlay h3 {
            margin: 0 0 10px 0;
        }

        .map-controls {
            position: absolute;
            top: 10px;
            right: 10px;
            display: flex;
            flex-direction: column;
            gap: 5px;
        }

        .map-control-btn {
            background: white;
            border: none;
            border-radius: 4px;
            padding: 8px;
            cursor: pointer;
            box-shadow: 0 0 10px rgba(0,0,0,0.1);
        }

        .map-control-btn:hover {
            background: #f0f0f0;
        }
    </style>
</head>
<body>
    <div id="map"></div>

    <div class="map-overlay">
        <h3>MapBolt Demo</h3>
        <p>Latitude: <span id="lat"></span></p>
        <p>Longitude: <span id="lng"></span></p>
    </div>

    <div class="map-controls">
        <button class="map-control-btn" id="zoom-in">+</button>
        <button class="map-control-btn" id="zoom-out">-</button>
    </div>

    <!-- MapLibre GL JS JavaScript -->
    <script src="https://unpkg.com/maplibre-gl@3.0.0/dist/maplibre-gl.js"></script>

    <script>
        // Replace with your MapBolt API key
        const API_KEY = 'YOUR_API_KEY';

        // Initialize the map
        const map = new maplibregl.Map({
            container: 'map',
            style: `https://mapbolt.com/api/maps/style?name=${STYLE_NAME}&key=${API_KEY}`,
            center: [4.375495, 50.54664], // Center of Belgium [lng, lat]
            zoom: 9
        });

        // Add navigation controls
        map.addControl(new maplibregl.NavigationControl(), 'bottom-right');

        // Add geolocate control
        map.addControl(
            new maplibregl.GeolocateControl({
                positionOptions: {
                    enableHighAccuracy: true
                },
                trackUserLocation: true
            })
        );

        // Update coordinates display when mouse moves over the map
        map.on('mousemove', (e) => {
            document.getElementById('lat').textContent = e.lngLat.lat.toFixed(6);
            document.getElementById('lng').textContent = e.lngLat.lng.toFixed(6);
        });

        // Add a marker when the map is clicked
        map.on('click', (e) => {
            new maplibregl.Marker()
                .setLngLat(e.lngLat)
                .setPopup(new maplibregl.Popup().setHTML(`<h3>Marker</h3><p>Coordinates: ${e.lngLat.lng.toFixed(6)}, ${e.lngLat.lat.toFixed(6)}</p>`))
                .addTo(map);
        });

        // Custom zoom controls
        document.getElementById('zoom-in').addEventListener('click', () => {
            map.zoomIn();
        });

        document.getElementById('zoom-out').addEventListener('click', () => {
            map.zoomOut();
        });

        // Add a scale control
        map.addControl(new maplibregl.ScaleControl({
            maxWidth: 100,
            unit: 'metric'
        }));

        // Wait for the map to load
        map.on('load', () => {
            // You can add custom layers, sources, or other map features here

            // Example: Add a custom layer with points of interest
            map.addSource('points-of-interest', {
                'type': 'geojson',
                'data': {
                    'type': 'FeatureCollection',
                    'features': [
                        {
                            'type': 'Feature',
                            'properties': {
                                'name': 'Point A',
                                'description': 'This is point A'
                            },
                            'geometry': {
                                'type': 'Point',
                                'coordinates': [4.35, 50.55]
                            }
                        },
                        {
                            'type': 'Feature',
                            'properties': {
                                'name': 'Point B',
                                'description': 'This is point B'
                            },
                            'geometry': {
                                'type': 'Point',
                                'coordinates': [4.40, 50.53]
                            }
                        }
                    ]
                }
            });

            map.addLayer({
                'id': 'poi-layer',
                'type': 'circle',
                'source': 'points-of-interest',
                'paint': {
                    'circle-radius': 8,
                    'circle-color': '#E6F024',
                    'circle-stroke-width': 2,
                    'circle-stroke-color': '#111111'
                }
            });

            // Add popups to the points of interest
            map.on('click', 'poi-layer', (e) => {
                const coordinates = e.features[0].geometry.coordinates.slice();
                const name = e.features[0].properties.name;
                const description = e.features[0].properties.description;

                new maplibregl.Popup()
                    .setLngLat(coordinates)
                    .setHTML(`<h3>${name}</h3><p>${description}</p>`)
                    .addTo(map);
            });

            // Change cursor to pointer when hovering over points
            map.on('mouseenter', 'poi-layer', () => {
                map.getCanvas().style.cursor = 'pointer';
            });

            map.on('mouseleave', 'poi-layer', () => {
                map.getCanvas().style.cursor = '';
            });
        });
    </script>
</body>
</html>

Routing API

MapBolt's Routing API is powered by Valhalla, a modern open-source routing engine. Unlike the previous endpoints, Valhalla endpoints use JSON objects for request parameters, which are sent in the body of a POST request or as a URL-encoded JSON string in GET requests.

Note: All routing requests can be made using either GET or POST. For GET requests, the JSON request should be URL-encoded and passed as the json parameter. POST requests should include the JSON object in the request body.
POST /route
Calculate the optimal route between two or more coordinates with detailed directions.

Request Format

The request is a JSON object with the following structure:

{
  "locations": [
    {
      "lat": 47.365109,
      "lon": 8.546824,
      "type": "break",
      "heading": 200,
      "heading_tolerance": 45,
      "minimum_reachability": 50,
      "radius": 200
    },
    {
      "lat": 47.368545,
      "lon": 8.540507,
      "type": "break"
    }
  ],
  "costing": "auto",
  "costing_options": {
    "auto": {
      "use_highways": 0.5,
      "use_tolls": 0.3,
      "use_ferry": 0.5
    }
  },
  "alternates": 2,
  "directions_options": {
    "units": "kilometers",
    "language": "en-US",
    "directions_type": "instructions"
  },
  "id": "my_route"
}

Key Parameters

Parameter Type Description
locations array Array of location objects with lat/lon coordinates. Must include at least 2 locations.
costing string Travel mode/costing model. Options: auto (default), bicycle, pedestrian, motorcycle, truck, bus, taxi, motor_scooter
costing_options object Options that adjust the routing behavior for the specified costing method
alternates integer Number of alternate routes to provide. Default: 0
directions_options object Options for the returned directions, including language and units
id string Optional identifier for the request

Location Object Properties

Property Description
lat Latitude in degrees
lon Longitude in degrees
type Type of location: "break" (default) for stop points, "through" for via points, "break_through" for stop that allows pass-through
heading Preferred direction of travel in degrees, 0-359
heading_tolerance How close in degrees a road must be to the heading. Default: 60
minimum_reachability Minimum number of nodes (intersections) reachable for a given edge (road between intersections)
radius Distance in meters to search for edges. Default: 0 (unlimited)
POST /isochrone
Generate isochrones (time-based or distance-based contours) around a location.

Request Format

{
  "locations": [
    {
      "lat": 47.365109,
      "lon": 8.546824
    }
  ],
  "costing": "auto",
  "contours": [
    {
      "time": 5
    },
    {
      "time": 10
    },
    {
      "time": 15
    }
  ],
  "polygons": true,
  "denoise": 0.5,
  "generalize": 50
}

Key Parameters

Parameter Type Description
locations array Origin point for the isochrone. Only one location is allowed.
costing string Travel mode/costing model. Same options as route endpoint.
contours array Array of contour objects. Each object must have either "time" (minutes) or "distance" (kilometers).
polygons boolean Whether to return polygons (true) or linestrings (false). Default: false
denoise float Value from 0 to 1 indicating how aggressively to remove noise from the isochrone. Default: 1.0
generalize float Controls Douglas-Peucker simplification of polygons. Default: 1.0
POST /sources_to_targets
Compute time and distance between a set of locations, returning a matrix of results.

Request Format

{
  "sources": [
    {
      "lat": 47.365109,
      "lon": 8.546824
    },
    {
      "lat": 47.368545,
      "lon": 8.540507
    }
  ],
  "targets": [
    {
      "lat": 47.371719,
      "lon": 8.544857
    },
    {
      "lat": 47.373405,
      "lon": 8.537876
    }
  ],
  "costing": "auto",
  "units": "kilometers"
}

Key Parameters

Parameter Type Description
sources array Array of origin location objects with lat/lon coordinates
targets array Array of destination location objects with lat/lon coordinates
costing string Travel mode/costing model. Same options as route endpoint.
units string Distance units. Options: kilometers (default), miles
POST /trace_route
Match a sequence of GPS points to the road network, returning a route that follows the roads.

Request Format

{
  "shape": [
    {
      "lat": 47.365109,
      "lon": 8.546824,
      "time": 1564160870
    },
    {
      "lat": 47.368545,
      "lon": 8.540507,
      "time": 1564160880
    },
    {
      "lat": 47.371719,
      "lon": 8.544857,
      "time": 1564160890
    }
  ],
  "costing": "auto",
  "shape_match": "map_snap",
  "filters": {
    "attributes": ["edge.names", "edge.length", "node.intersecting_edge_counts"],
    "action": "include"
  }
}

Key Parameters

Parameter Type Description
shape array Array of location objects with lat/lon coordinates and optional timestamps
costing string Travel mode/costing model. Same options as route endpoint.
shape_match string How to match points to the road network. Options: "edge_walk" (strict match), "map_snap" (snap to nearest roads), "walk_or_snap" (try edge_walk, if it fails use map_snap)
filters object Filters for the attributes returned in the response
POST /optimized_route
Optimize the order of a set of locations for the shortest overall route (traveling salesman problem).

Request Format

{
  "locations": [
    {
      "lat": 47.365109,
      "lon": 8.546824
    },
    {
      "lat": 47.368545,
      "lon": 8.540507
    },
    {
      "lat": 47.371719,
      "lon": 8.544857
    },
    {
      "lat": 47.373405,
      "lon": 8.537876
    }
  ],
  "costing": "auto",
  "directions_options": {
    "units": "kilometers"
  }
}

Key Parameters

Parameter Type Description
locations array Array of location objects with lat/lon coordinates
costing string Travel mode/costing model. Same options as route endpoint.
directions_options object Options for the returned directions, including language and units

Geocoding API

GET /api
Convert addresses or place names into geographic coordinates.

Parameters

Parameter Type Description
q string Search query

Required

lon number The lon and lat parameters enables you to prioritize addresses that are closest to the entered position. i.e location bias.

(optional)

lat number \
zoom integer Zoom level for results (optional)
location_bias_scale number Scale factor for location bias (optional)
GET /reverse
Convert coordinates into addresses or place names.

Parameters

Parameter Type Description
lon number Longitude
lat number Latitude
radius number Search radius in meters (optional)

Data API

MapBolt's data service enables you to display your geographic data on stylised maps and update this data on real-time through simple api calls. You can create datasets, fill them with your data (which are point objects with coordinates), then create a style showing the data as a customizable heatmap and show it to your users. Any update you make on the dataset will instantly be reflected on the map. Note: Datasets work like sql database tables

GET /style
Returns a stylesheet corresponding to Maplibre's style specifications. The available styles can be explored through the links below.

Parameters

Parameter Type Description
name string Style' s name as submitted during creation, you can check your style names in the Dashboard.
GET /create-table
Create a dataset (a table)

Parameters

Parameter Type Description
name string Name of the dataset. Note that the name cannot include "|", "_" nor the space character. (Required)
field string Any (nullable) text values you want to attach to your inserted data, no limited amount of them. Example:.../create-table/?field=accuracy&field=contributor&field=...
GET /delete-table
Delete a table

Parameters

Parameter Type Description
name string Name of the dataset you want to delete (Required)
GET /add-data
Add data to a specified table.

Parameters

Parameter Type Description
name string name of the dataset (required)
lat number latitude of the coordinate (required)
long number longitude of the coordinate (required)
{field} string value for each field of this dataset. Example: .../add-data/?contributor=William.L&accuracy=Medium&... Not specifying a field's value will make it null. (Optionnal)
days number This is the number of days the added data will be available before deletion. Note that the number of days additions with the below "minutes" and "seconds" parameters. Usage example: If the 21st at 09:02 you enter the data with "days" = 2 and "minutes" = 34, your data will expire the 23rd of the same month at 09:36.
minutes number
seconds number See "days"
GET /remove-data-by-key
Delete data from a specified table, that has specific fields values.

Parameters

Parameter Type Description
name string name of the dataset
{fields} string FIeld values of the data that must be deleted. For example if the request looks as follows /remove-data-by-key/?contributor=William.L then all the inserted data objects that have William.L as contributor will be removed.
GET /remove-data-by-duration
Delete from a specified table all data older than the specified parameter..

Parameters

Parameter Type Description
name string name of the dataset
days number Data that is {days} days old or older will be removed
hours number Idem than days
minutes number Idem than days
GET /remove-all-data
Deletes all data from the dataset

Parameters

Parameter Type Description
name string name of the dataset
GET /data/download-data/
Downloads your dataset with the entered name

Parameters

Parameter Type Description
name string name of the dataset
GET /data/get-data-by-key/
Gets data rows from the specified table, that has specific fields values.

Parameters

Parameter Type Description
name string name of the dataset
{fields} string Field values of the data that must be returned. For example if the request looks as follows /get-data-by-key/?contributor=William.L then all the inserted data objects that have William.L as contributor will be returned.
GET /data/get-data-by-duration/
Get from a specified table all data older than the specified parameter.

Parameters

Parameter Type Description
name string name of the dataset
days number Data that is {days} days old or older will be returned
hours number Idem than days
minutes number Idem than days