BeMapAPI
BeMap 4.1.0

BeNomad Tiles

Overview & access#

BeNomad Tiles is BeNomad's hosted vector map data: MVT tiles served over HTTPS from a JWT-authenticated worker, consumed either as a PMTiles archive in the browser or as individual {z}/{x}/{y}.pbf tiles on mobile and fleet back-ends.

Current scope: cartographic data only. BeNomad Tiles delivers the map data (vector tiles, styles, glyphs) and the access mechanism described on this page. The BeMap map server comes later; until then, routing, geocoding and EV services keep running on the BeMap API host (host), while tiles come from the tiles host (tilesHost). Two backends, one BeMap account.

At a glance#

  • One BeMap account gives access to both backends, no separate tiles subscription or API key.
  • Access in one line: POST /api/login with HTTP Basic → a JWT valid ~1 hour → every tile, style, glyph and discovery request carries it. Detail: Sessions & tokens.
  • Three integration paths: Web SDK (recommended), raw MapLibre + pmtiles.js, or mobile/fleet z/x/y. Pick one from the table below.
  • Vector tiles are MapLibre-only: bemap.MapLibreMap. Leaflet and OpenLayers stay on the WMS raster background and silently ignore tilesHost.
  • Three public environments (production, preprod, beta): always pair a BeMap host with its matching tiles host.
  • Address tiles through the alias default; the worker resolves the real tileset server-side.

Usage#

Set tilesHost on the Context and instantiate bemap.MapLibreMap. The SDK logs in, caches the JWT, renews it before expiry, attaches it to every tile request, loads the live BeNomad style and caches tiles in the browser.

js
var ctx = new bemap.Context({
    login:     'YOUR_LOGIN',
    password:  'YOUR_PASSWORD',
    secure:    true,
    host:      'bemap.benomad.com',        // BeMap API - routing, geocoding, EV
    tilesHost: 'mptiles-api.benomad.net'   // BeNomad Tiles - vector basemap
});

var map = new bemap.MapLibreMap(ctx, 'map').move(2.3412, 48.85693, 12);

pmtiles.js is required alongside MapLibre whenever tilesHost is set: the library prints the exact missing tag in the console if you forget it.

html
<link rel="stylesheet" href="dist/maplibre-gl.css">
<script src="dist/maplibre-gl.js"></script>
<script src="dist/pmtiles.js"></script>
<script src="dist/bemap-js-api.js"></script>

Pick your integration path#

PathWho it's forHow tiles are fetchedWhere to go next
A: Web SDK (recommended)Web apps that want the map plus geocoding / routing / EV from one libraryThe SDK owns login, JWT, transformRequest and cache; nothing to wireWeb: PMTiles, MapLibre map
B: Web rawApps already running MapLibre GL that only want the BeNomad basemappmtiles:// on /default.pmtiles via HTTP Range, or cacheable ?r= 200 slicesWeb: PMTiles, Cache & slices
C: Mobile / fleetNative mobile apps and server-to-server consumersIndividual GET /default/{z}/{x}/{y}.pbf MVT tiles, token in the query stringMobile & fleet z/x/y

If you are unsure, take path A: least code, fewest ways to get it wrong.

Reference#

Environments#

Never mix a BeMap host with the tiles host of another environment; credentials and tilesets are per-environment.

Environmenthost (BeMap API)tilesHost (BeNomad Tiles)Use for
Production (default)bemap.benomad.commptiles-api.benomad.netLive customer traffic
Preprodbemap-preprod.benomad.commptiles-api-preprod.benomad.netStaging, pre-release validation
Betabemap-beta.benomad.commptiles-api-beta.benomad.netIntegration testing

Access contract#

ItemValue
LoginPOST https://<tilesHost>/api/login, header Authorization: Basic base64(login:password) → { ok, username, token }
Token lifetime~1 hour; the SDK renews 5 minutes before expiry, and a 401 triggers a transparent re-login
Token transportCookie (default, no preflight), X-Session-Token header, or ?token= query, see Sessions & tokens
DiscoveryGET /api/maps, /api/default-style, /api/styles: authenticated, not rate-limited
Rate limit100 req/s per user (429 above it)
Range reads≤ 10 MB per request; a .pmtiles request without a Range header is rejected with 403
TransportHTTPS only; browser origins must be CORS-allowlisted by BeNomad

Resources#

ResourceLinkWhat it is
GitHub repositoryBeNomadSAS/bemap-js-apiSource, dist/ bundle, install guide, release tags
Live demo dashboardbenomadsas.github.io/bemap-js-apiEvery feature runnable, with copy-paste code and an environment switcher
BeMaputnikbemaputnik.benomad.netBrowser style editor for the BeNomad charte, see Styles & BeMaputnik
JSDoc referenceAPI referenceGenerated documentation for every class and method
AI integration skillbenomad-tiles-integration/ in the repoPath templates (web SDK, raw MapLibre, native mobile, backend proxy) for Claude / Cursor / Copilot

Notes#

Demo-only credentials. The live demos on this portal authenticate with a shared account configured in documentation/context.js. It is deliberately public, provisioned for map tiles on beta only, and grants nothing else: it exists so the demo blocks on this site render. It is not a customer credential, carries no guarantee of availability, and must never be used by a customer application. Use your own BeMap account, and see The Context for keeping it out of the browser in production.

WMS vs BeNomad Tiles#

Migration is opt-in and non-breaking: a v1 app that never sets tilesHost keeps rendering WMS unchanged.

ConcernWMS (raster)BeNomad Tiles (vector)
EnginesLeaflet, OpenLayers, MapLibreMapLibre only
RenderingRaster PNG/JPG, pixelated between zoomsVector: fluid pan/zoom, crisp at every scale
3D buildings, terrain, globeNot supportedFirst-class
LabelsStatic, server-renderedBilingual, resolved per browser language at runtime
BrandingServer-side style onlyClient-side style swap at runtime
CachingBrowser defaultBrowser HTTP cache on 200 slices, or Service Worker on classic Range

Gotchas#

  • Coordinates are longitude first. new bemap.Coordinate(lon, lat) and map.move(lon, lat, zoom). Reversing them is the classic "my marker is in the Atlantic" bug.
  • tilesHost on a Leaflet or OpenLayers map is ignored: silently. The map class is the switch, not the Context field.
  • Never ship credentials in client code for production. Inline login / password is for demos and evaluations; production keeps them server-side behind a token provider or the proxy option.
  • Never patch window.fetch to inject the token. The SDK uses MapLibre's transformRequest; raw integrations use transformRequest or ?token=.
  • A 403 from a non-browser client is usually the User-Agent. The gateway filters bot-like agents (Python-urllib and friends): send an explicit, realistic User-Agent.
  • Tiles are gzipped by content negotiation. Browsers negotiate and decompress transparently: do not gunzip again. Native and server clients that do not send Accept-Encoding: gzip may receive raw gzip (1f 8b) and must decompress before parsing the MVT.
  • A 400 "Access Denied" on a service is an entitlement, not a bug. Roles are provisioned per account; ask BeNomad rather than debugging your code.

See also#

  • Sessions & tokens: login, TTL, the four token wire modes, renewal
  • Web: PMTiles: paths A and B in full, script order, raw MapLibre setup
  • Mobile & fleet z/x/y: path C, MVT, 204 on empty tiles, gzip matrix
  • Styles & BeMaputnik: style precedence, placeholders, glyphs, the style editor
  • Cache & slices: 200-slice vs Range, browser cache, resilience knobs
  • Troubleshooting: 401 / 403 / CORS / gzip / blank map, symptom to fix
  • The Context: every Context option, including tilesHost and tilesFile
  • MapLibre map: the map class that renders BeNomad Tiles