InfraNode.dev
MCP InfraNode is also available as an MCP server for AI assistants like Claude and ChatGPT.

Pagination and limits

Most InfraNode endpoints return compact payloads. A few return large lists: all charging points, all energy installations or all public-transit stops of a major city quickly reach several megabytes. Those lists are paginatable so that AI agents (MCP) and GPT Actions do not hit their size limits, while bulk consumers of the REST API still get everything in a single call.

The key point: pagination is optional and only applies to large, static lists, never to live data. The default additionally depends on the calling channel. Both are transparent via meta.pagination in every response.

What is paginatable, what is not

Only the large, slowly changing location/inventory lists are paginated. Live data always stays complete because it is small and current, and a partial view would make no sense there.

Category Examples Paginatable
Large static lists energy, charging (locations), transit (stops), events, and OSM lists such as education, playgrounds, post-boxes Yes, optional
Live and compact data weather, air, traffic, transit/departures, charging-status, water-level, flood, power-load No, always complete

For stop lookup there is also ?q= (name) and ?near=lat,lon (radius) on transit, so you get a few targeted hits instead of the whole city.

Channel-dependent default

Without an explicit limit parameter, the default page size depends on which channel the call arrives through. This keeps the REST API unchanged for existing bulk consumers while automatically protecting the two channels with hard size limits.

Channel Default Why
Direct REST (/api/v1) full (no limit) Data pullers get everything in one call, no breaking change.
GPT Actions bound (50) Detected via the OpenAI headers, enforced server-side so the response stays under the Action size limit.
MCP server bound (50) The MCP client sets the limit itself, keeping the agent context lean.

Good to know: the same URL can return a different number of entries across two channels. This is intentional and readable from meta.pagination in every response (see below), so it is never unclear whether you have a slice or the full set.

So a shared cache never mixes up this channel-dependent response, GPT Actions responses are not cached at the edge: the API sends Cache-Control: no-store for GPT requests and Cloudflare additionally excludes that traffic from the edge cache via a rule. Otherwise the same shared cache would serve the wrong variant to the other channel under one URL: REST would get the bound 50-entry response, GPT the full, potentially multi-megabyte response.

Parameters

Parameter Meaning
limit Entries per page. Integer from 1, hard-capped at 200 (MAX_LIMIT). A larger value returns a 200-entry page instead of an error.
offset Start position for paging (default 0). An offset beyond the data set returns an empty page with status 200, not an error.
limit=all or ?all=1 Channel-independent full switch: forces the complete list, even over GPT Actions and MCP. The self-documenting way to deliberately fetch everything.

meta.pagination

Every paginatable response carries a pagination block in the meta object. It makes the slice honest and visible, there is no silent truncation.

Field Content
total Total number of entries in the full set.
returned Number of entries included in this response.
limit / offset The page size and start position actually applied.
truncated true when a slice is returned (there are more than returned), otherwise false. On full output, returned == total and truncated: false.

Full geometry for traffic

The traffic endpoint (live) is not paginated but kept lean: the raw roadworks polyline geometries are hidden by default because they multiply the response size and are irrelevant to most calls. Map applications request them explicitly:

https://infranode.dev/api/v1/cities/koeln/traffic?include=geometry

Alternatively ?full=1 has the same effect. Without this parameter the official content (title, description, location, impact) stays complete, only the polyline is omitted.

Examples

First 20 charging locations, starting at the 40th entry:

https://infranode.dev/api/v1/cities/berlin/charging?limit=20&offset=40

All energy installations in one call, regardless of channel:

https://infranode.dev/api/v1/cities/berlin/energy?limit=all

Find a stop by name (returns a few hits with stop_id):

https://infranode.dev/api/v1/cities/hamburg/transit?q=Alsterdorf