Skip to main content

Working with existing maps

There is no session. The server stores nothing between calls, and there is no map id to keep track of. The URL is the state.

create_map → svg_url

add_layers(map: svg_url) → a new svg_url, with the addition applied

add_layers(map: that URL) → another one

Every URL in that chain is a finished map. The first one still renders after the third call, because nothing was mutated — each call read a URL and wrote a longer one.

A map in three calls

1. create_map with a scope, a theme and a title.

{ "scope": "world", "theme": "dark", "title": "Asia–Europe container route", "width": 900 }
https://api.maproll.io/map.svg?scope=world&theme=dark&title=Asia%E2%80%93Europe%20container%20route&width=900
Empty dark world map titled Asia–Europe container route

2. add_layers with the two ports, passing that URL back as map.

{
"map": "https://api.maproll.io/map.svg?scope=world&theme=dark&title=Asia%E2%80%93Europe%20container%20route&width=900",
"markers": [
{ "lat": 31.23, "lon": 121.47, "icon": "anchor", "label": "Shanghai" },
{ "lat": 51.92, "lon": 4.48, "icon": "anchor", "label": "Rotterdam" }
]
}
Dark world map with anchor markers at Shanghai and Rotterdam

3. add_layers again, with the route. The markers are still there — they were never restated.

{
"map": "…&markers=31.23,121.47:anchor:Shanghai%3B51.92,4.48:anchor:Rotterdam",
"routes": [
{ "from": "31.23,121.47", "to": "51.92,4.48", "sea": true, "arrow": true }
]
}
Shanghai to Rotterdam sea route through Suez, with anchor markers at both ends

The URLs above are trimmed for reading. A real response also carries src=mcp, and the signing parameters when a key is set.

add_layers appends

add_layers adds. It does not replace, and it has no way to remove.

  • Layer parameters accumulate. New markers join the markers already on the URL; new routes join the routes.
  • Pair-list parameters accumulate too. proportional, patterns and annotations merge into the existing lists rather than overwriting them. Sending a shorter list does not delete the entries you left out.
  • Removing something means rebuilding. Go back to create_map — or hand the map to a person in the editor via editor_url, where layers can be switched off one at a time.

That asymmetry is deliberate. Appending is the common case in a conversation ("now add the ports", "now the route"), and a tool that silently dropped the previous turn's work would be worse than one that occasionally needs a restart.

Which URL to keep

Keep the last one for building on, and whichever one you liked for publishing. Some practical consequences of URLs being the state:

  • A map from three turns ago is still live. Scroll up, take the URL, pass it to add_layers, and you have branched from that point.
  • A URL survives the conversation. Paste it into a README, a Notion page, a Slack message. Nothing expires. Renders are cached and immutable, so re-using a URL costs nothing.
  • The editor is a two-way door. editor_url opens the same map in app.maproll.io, and the URL the editor produces goes back into add_layers unchanged.
  • png_url is the same map. Swap map.svg for map.png when the destination cannot render SVG.

Keyed URLs

When MAPROLL_API_KEY is set, the URLs the server returns carry two extra parameters, k and t — a key payload and a signature bound to that exact set of parameters. See how the signing works.

Passing a signed URL straight back into add_layers is safe. The server strips the old signature, adds the new layer, and re-signs the result, so t always matches the URL it is attached to. You do not need to clean anything up, and there is no point hand-editing a signed URL — changing a parameter invalidates the signature, and the wordmark comes back.

  • Tools — the full argument surface of both map tools.
  • Agent recipes — the same chain in a few concrete shapes.
  • refine_map — describe the change in plain English and let the model pick the call.