Developer documentation

GrachtAlert API

A REST API for the Amsterdam canals. The public endpoints serve live water level, the full canal map (bridges, segments, closures, moorings) and the same route planner that powers grachtalert.nl. The business endpoints add congestion analytics, waterway notices and fleet data for rederijen with a business account.

Getting started

All endpoints live under a single versioned base URL:

https://api.grachtalert.nl/v1

Public endpoints work without any credentials. Try the water level right from your terminal:

curl https://api.grachtalert.nl/v1/public/waterstand
Note: anonymous requests are rate-limited per IP (see rate limits). For production integrations, authenticate with an API key — keyed traffic is not IP-limited and is accounted per key.

Authentication

API keys, and an optional short-lived token exchange.

Authenticated endpoints expect a bearer credential in the Authorization header. Two credential types are accepted:

  1. API key — a long-lived key starting with gk_live_. Created self-service from your GrachtAlert business account (see API key management). The plaintext key is shown exactly once, at creation — store it securely.
  2. Short-lived access token — optionally exchange your API key for a JWT valid for 1 hour via POST /auth/token, so the long-lived key itself never travels on every request.
curl https://api.grachtalert.nl/v1/vaarweg-meldingen \
  -H "Authorization: Bearer gk_live_YOUR_KEY"
POST/auth/tokenNo auth

Exchanges a valid API key for a short-lived bearer token. The token carries the same access as the key and respects key revocation: if API access is withdrawn, outstanding tokens stop working immediately.

Body (JSON)

NameTypeDescription
apiKeyrequiredstringYour gk_live_… API key.

Example request

curl -X POST https://api.grachtalert.nl/v1/auth/token \
  -H "Content-Type: application/json" \
  -d '{"apiKey": "gk_live_YOUR_KEY"}'

Example response

{
  "data": {
    "token": "eyJhbGciOiJIUzI1NiIs...",
    "tokenType": "Bearer",
    "expiresIn": 3600
  }
}
Getting access: business endpoints require a GrachtAlert business account with API access enabled. Register a business account or contact us via the site if API access is not yet enabled on your account.

API key management

Self-service, scoped to your own account. Authenticate with an existing key, an exchanged token, or a GrachtAlert session.

GET/api-keysAPI key · Business

Lists your API keys: name, prefix (the first characters, to tell keys apart), creation date, last-used date and revocation date. The full key value is never returned after creation.

POST/api-keysAPI key · Business

Creates a new API key. The response is the only time the plaintext key is ever shown — store it immediately.

Body (JSON)

NameTypeDescription
naamrequiredstringA label for the key, e.g. the integration it will be used in.

Example response

{
  "data": {
    "id": "…",
    "naam": "Dashboard integration",
    "key_prefix": "gk_live_a1b2",
    "aangemaakt_op": "2026-08-23T11:00:00Z",
    "key": "gk_live_…"   // shown only once
  }
}
DELETE/api-keys/{id}API key · Business

Revokes a key. Revocation is immediate — requests with the key (and tokens exchanged from it) start failing with 401 right away.

Path parameters

NameTypeDescription
idrequireduuidKey id, from the key list.

Responses & errors

Authenticated endpoints wrap their payload in a { "data": … } envelope. Public endpoints return their payload directly. Errors always share one shape:

{ "error": "Human-readable message" }
StatusMeaning
200 / 201Success. 201 is returned when a resource was created.
400Invalid request — a missing or malformed parameter, or a validation error.
401Missing, invalid or revoked credential.
403Authenticated, but not allowed to access this resource (e.g. not your rederij or boat).
404Resource not found.
429Rate limit exceeded — retry later.
500 / 502Server error, or an upstream data source (e.g. Rijkswaterstaat) failed.

Rate limits

Requests to public endpoints are limited per endpoint, per minute — per IP for anonymous requests, per account for requests authenticated with an API key or exchanged token.

EndpointLimit
POST /public/calculate-route5 / minute
GET /public/vaarkaart-data10 / minute
All other /public/* endpoints10 / minute

Exceeding a limit returns 429. Please cache /public/vaarkaart-data responses — the underlying map data changes at most a few times per day.

Public endpoints

No-auth endpoints are open to everyone. The ones marked API key · Business power the GrachtAlert site and app; programmatic access to those requires a business account's API key.

GET/healthNo auth

Gateway health check. Useful as an uptime probe for your integration.

Example request

curl https://api.grachtalert.nl/v1/health

Example response

{ "data": { "status": "ok", "version": "v1" } }
GET/public/waterstandNo auth

Latest measured water level of the Amsterdam canals (station Amsterdam Surinamekade), sourced live from Rijkswaterstaat. Values are in centimetres relative to NAP.

Example request

curl https://api.grachtalert.nl/v1/public/waterstand

Example response

{
  "waarde": -39.0,
  "eenheid": "cm",
  "tijdstip": "2026-08-23T09:40:00.000+01:00",
  "locatieCode": "amsterdam.surinamekade",
  "locatieNaam": "Amsterdam Surinamekade"
}
GET/public/vaarkaart-dataAPI key · Business

The complete canal map dataset in one call: bridges (with clearance heights), canal segments, intersections, segment connections, moorings/boarding locations, active waterway notices & closures, points of interest, public toilets, authority vessel positions, themed routes and live per-segment congestion status. The response is large (several MB) — fetch it once and cache it.

Example request

curl https://api.grachtalert.nl/v1/public/vaarkaart-data \
  -H "Authorization: Bearer gk_live_YOUR_KEY"

Example response

{
  "bruggen": [ { "id": "…", "naam": "Magere Brug", "doorvaarthoogte_cm": 240, … } ],
  "segmenten": [ … ],
  "kruispunten": [ … ],
  "overgangen": [ … ],
  "opstapplaatsen": [ … ],
  "vaarwegMeldingen": [ … ],
  "pois": [ … ],
  "openbareToiletten": [ … ],
  "autoriteitBoten": [ … ],
  "segmentThemas": [ … ],
  "segmentStatusLive": [ … ]
}
POST/public/calculate-routeAPI key · Business

Plans a route between two points on the canal network, honouring your boat's dimensions, bridge clearances, current closures and (when enabled) live congestion delays. Stops reference canal segments by segId — segment ids come from /public/vaarkaart-data. A second mode, best_order, finds the best visiting order for a set of stops instead of a fixed A→B route.

Body (JSON)

NameTypeDescription
mode'route' | 'best_order'Defaults to 'route'. In best_order mode, van is the anchor/start, vias are the stops to order, and naar is an optional fixed final destination.
vanrequiredstopStart of the route: { "segId": "…" }, optionally with a point on the segment.
naarrequiredstopDestination. Required in 'route' mode; optional in 'best_order' mode.
viasstop[]Intermediate stops, in order (route mode) or to be ordered (best_order mode).
boatTyperequiredstringYour boat type — determines which segments are allowed.
heeftGrootVaarbewijsrequiredbooleanWhether the skipper holds a groot vaarbewijs.
boatHeightCmrequirednumberBoat height in cm — routes avoid bridges you cannot pass under.
speedMultiplierrequirednumberCruise speed as a multiplier of the segment norm (1 = normal).
maxSnelheidKmhnumber | nullHard speed cap in km/h; omit or null for no cap.
mooisteMinutennumber | nullOptional scenic detour budget in minutes (route mode).
departureAtstring | nullISO 8601 departure time; null/omitted means now (route mode).

Example request

curl -X POST https://api.grachtalert.nl/v1/public/calculate-route \
  -H "Authorization: Bearer gk_live_YOUR_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "van":  { "segId": "SEGMENT_ID_A" },
    "naar": { "segId": "SEGMENT_ID_B" },
    "boatType": "sloep",
    "heeftGrootVaarbewijs": false,
    "boatHeightCm": 180,
    "speedMultiplier": 1
  }'
Other /public/* routes you may encounter (route-log, melding-notificatie, abonnee-notificatie, text-to-speech, registreer-zakelijk-account, contact) exist for the GrachtAlert website and mobile app themselves and are not intended for third-party integrations.

Business endpoints

Require a business account with API access, authenticated with an API key or exchanged token.

Congestion analytics (drukte)

Historical and aggregated canal traffic, derived from AIS data. Available per canal segment and city-wide. Segment ids come from /public/vaarkaart-data. Time-bucketed endpoints accept an optional date window via van / tot.

GET/drukte/segmenten/{segmentId}/patroonAPI key · Business

Weekly traffic pattern for one segment: average speed and average number of active boats per weekday/time-slot, plus how many weeks of data back each value.

Path parameters

NameTypeDescription
segmentIdrequireduuidCanal segment id.

Example request

curl https://api.grachtalert.nl/v1/drukte/segmenten/SEGMENT_ID/patroon \
  -H "Authorization: Bearer gk_live_YOUR_KEY"

Example response

{
  "data": [
    {
      "weekdag": 5,
      "slot": 28,
      "gemiddelde_snelheid_kmh": 6.4,
      "som_metingen": 412,
      "aantal_weken": 8,
      "gemiddeld_aantal_actieve_boten": 11.2,
      "aantal_weken_actief": 8
    }, …
  ]
}
GET/drukte/segmenten/{segmentId}/dagAPI key · Business

Daily number of active boats on one segment.

Path parameters

NameTypeDescription
segmentIdrequireduuidCanal segment id.

Query parameters

NameTypeDescription
vandate (YYYY-MM-DD)Start of the window (inclusive).
totdate (YYYY-MM-DD)End of the window (inclusive).

Example request

curl "https://api.grachtalert.nl/v1/drukte/segmenten/SEGMENT_ID/dag?van=2026-08-01&tot=2026-08-23" \
  -H "Authorization: Bearer gk_live_YOUR_KEY"
GET/drukte/segmenten/{segmentId}/20minAPI key · Business

Active boats on one segment in 20-minute buckets — the finest granularity available.

Path parameters

NameTypeDescription
segmentIdrequireduuidCanal segment id.

Query parameters

NameTypeDescription
vantimestamp (ISO 8601)Start of the window (inclusive).
tottimestamp (ISO 8601)End of the window (inclusive).
GET/drukte/stad/patroonAPI key · Business

City-wide weekly traffic pattern: average number of active boats per weekday/time-slot across all canals.

GET/drukte/stad/dagAPI key · Business

City-wide daily number of active boats.

GET/drukte/stad/20minAPI key · Business

City-wide active boats in 20-minute buckets.

Query parameters

NameTypeDescription
vantimestamp (ISO 8601)Start of the window (inclusive).
tottimestamp (ISO 8601)End of the window (inclusive).
GET/drukte/weerAPI key · Business

Daily weather observations used in the congestion models: max temperature, precipitation, wind and weather code.

Query parameters

NameTypeDescription
dagdate (YYYY-MM-DD)Return a single day (object instead of array).
dagencomma-separated datesReturn a specific set of days.

Example response

{
  "data": [
    { "dag": "2026-08-22", "temp_max_c": 24.1, "neerslag_mm": 0.2, "windkracht_kmh": 14, "weercode": 2 }, …
  ]
}
GET/drukte/seizoensfactorAPI key · Business

Seasonal multiplier per ISO week, used to normalise traffic expectations across the year.

Example response

{
  "data": [
    { "iso_week": 34, "multiplier": 1.35, "toelichting": "Hoogseizoen" }, …
  ]
}

Waterway notices

GET/vaarweg-meldingenAPI key · Business

All current waterway notices for the Amsterdam canals — closures, works and restrictions — synced from Rijkswaterstaat Vaarweginformatie, ordered by start date.

Example request

curl https://api.grachtalert.nl/v1/vaarweg-meldingen \
  -H "Authorization: Bearer gk_live_YOUR_KEY"

Fleet (your own rederij)

Business accounts are linked to one or more rederijen at registration. These endpoints are scoped to that link: you can only read and update your own rederij and its boats. Requests for anything else return 403.

GET/botenAPI key · Business

Lists your rederij's fleet — every boat of every company (bedrijf) linked to your rederijen, including boat dimensions, MMSI and company name.

Example request

curl https://api.grachtalert.nl/v1/boten \
  -H "Authorization: Bearer gk_live_YOUR_KEY"
PATCH/boten/{id}API key · Business

Updates one of your own boats — name, type, MMSI and dimensions.

Path parameters

NameTypeDescription
idrequireduuidBoat id (must belong to your rederij).

Body (JSON)

NameTypeDescription
naamstringBoat name.
typestringBoat type.
mmsistring | nullAIS MMSI number.
lengte_m / breedte_m / diepgang_m / hoogte_cmnumber | nullDimensions in metres (height in cm).
GET/rederijen/{id}API key · Business

Your rederij's profile, including its companies (bedrijven) and a boat count per company.

Path parameters

NameTypeDescription
idrequireduuidRederij id (must be your own).
PATCH/rederijen/{id}API key · Business

Updates your rederij's name.

Path parameters

NameTypeDescription
idrequireduuidRederij id (must be your own).

Body (JSON)

NameTypeDescription
naamrequiredstringNew name.
GET/vloot/boten/{bootId}API key · Business

Full analytics detail for one of your boats over a date range: daily summaries, trips, stops, pier visits, coverage gaps, current position and home-location history.

Path parameters

NameTypeDescription
bootIdrequireduuidBoat id (must belong to your rederij).

Query parameters

NameTypeDescription
datumVandate (YYYY-MM-DD)Start of the range. Defaults to today.
datumTotdate (YYYY-MM-DD)End of the range. Defaults to today.

Example request

curl "https://api.grachtalert.nl/v1/vloot/boten/BOOT_ID?datumVan=2026-08-01&datumTot=2026-08-23" \
  -H "Authorization: Bearer gk_live_YOUR_KEY"
GET/vloot/boten/{bootId}/trailAPI key · Business

Recent AIS trail and current position of one of your boats — every position with speed, heading and the speed limit of the segment at that moment, plus the average speed over the window.

Path parameters

NameTypeDescription
bootIdrequireduuidBoat id (must belong to your rederij).

Query parameters

NameTypeDescription
venster'3u' | '24u'Window size: last 3 hours (default) or last 24 hours.

Example response

{
  "data": {
    "trail": [
      { "lat": 52.3702, "lng": 4.8952, "snelheid_kmh": 5.8, "koers_graden": 214,
        "ontvangen_op": "2026-08-23T10:42:11Z", "segment_limiet_kmh": 6 }, …
    ],
    "huidige_positie": { "lat": 52.3688, "lng": 4.8931, "snelheid_kmh": 0, "ontvangen_op": "2026-08-23T11:02:41Z" },
    "gemiddelde_snelheid_kmh": 5.1
  }
}
GET/vloot/boten/{bootId}/rit/{ritId}API key · Business

Map data for a single trip: the segments sailed, the full position trail during the trip, and the departure location.

Path parameters

NameTypeDescription
bootIdrequireduuidBoat id (must belong to your rederij).
ritIdrequireduuidTrip id, from the boat detail endpoint.
PUT/vloot/boten/{bootId}/thuislocatieAPI key · Business

Sets or clears the manual home-location override for one of your boats.

Path parameters

NameTypeDescription
bootIdrequireduuidBoat id (must belong to your rederij).

Body (JSON)

NameTypeDescription
opstapplaatsIdrequirednumber | nullMooring/boarding-location id, or null to clear the override.

Questions or missing something?

The API is under active development. If your integration needs an endpoint or field that isn't documented here, reach out via the site — we're happy to think along.