Atlas API and MCP
World in Layers gives your software and your AI agent the same data the atlas shows: weather and air-quality forecasts, reanalysis history, sea temperature and waves, seasonal climate, fire detections, earthquakes, volcano records and Earth's magnetic field. You reach it in two ways that return identical payloads:
- MCP at
https://worldinlayers.com/mcp, for Claude Code, Cursor, VS Code, Gemini CLI and the Anthropic and OpenAI APIs. - REST at
https://worldinlayers.com/api/v1/agent/<tool>, for scripts, notebooks and your own services. JSON by default, CSV for lists and series.
The service returns data only. It does not write answers; your agent does the reasoning. Every number arrives with its units, data kind, valid time, provider and a public link that reproduces it, so a person can check what the agent said.
Who it is for
The job is the same for everyone: trustworthy numbers about a place and a time, where they came from, and a link a person can open to check them. The examples below use REST so you can see the exact call; an agent connected over MCP makes the same calls.
Recorded responses. Every response shown on this page was recorded from a local run on the date given beside it. Responses for the three environmental examples (Portugal's gusts, the earthquakes and the Brno forecast) depend on live forecast and catalogue snapshots and will be added after the first deployment.
In every example, $ATLAS_API_KEY holds your key.
Newsrooms and data journalists
How much of Portugal sees gusts of 60 km/h or more today? One call returns the area-weighted mean, the minimum and maximum with the nearest named place (none over open ocean far from land), and the share of land at or above the threshold, across the frames of the local day.
curl -s "https://worldinlayers.com/api/v1/agent/atlas_area_stats?layer=gusts&country=PT&time=now&period=day&tz=Europe/Lisbon&threshold=60" \
-H "Authorization: Bearer $ATLAS_API_KEY"
period=day costs 10 units per forecast frame used, at most 40. The method field describes the grid, weights, cells and frames, and reproduce lets an editor re-run the same figure while the snapshot is retained.
Researchers and students
Declination at the Hurbanovo observatory in Slovakia, yearly from 1900 to 2026, as CSV.
curl -s "https://worldinlayers.com/api/v1/agent/atlas_get_time_series?format=csv" \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"points":[{"lat":47.87,"lon":18.19}],"layers":["magnetism"],"model":"igrf14","start":"1900","end":"2026","samples":127}'
Recorded from a local run on 25 October 2026: the header and the first rows of 635 (127 years for each of the five components F, D, I, H and Z, in that order; the declination rows are magnetism:D). predictive is false for the model years up to 2025 and true only on the 2026 rows, where IGRF-14 extrapolates; status is ok on every answered row:
place,place_id,lat,lon,layer,time,value,units,provider,data_kind,preliminary,stale,predictive,snapshot_version,source_url,status,error
"47.8700, 18.1900",,47.87,18.19,magnetism:F,1900.0,45850,nT,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
"47.8700, 18.1900",,47.87,18.19,magnetism:F,1901.0,45838,nT,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
"47.8700, 18.1900",,47.87,18.19,magnetism:F,1902.0,45827,nT,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
…
"47.8700, 18.1900",,47.87,18.19,magnetism:D,1900.0,-7.36,degrees,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
"47.8700, 18.1900",,47.87,18.19,magnetism:D,1901.0,-7.28,degrees,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
"47.8700, 18.1900",,47.87,18.19,magnetism:D,1902.0,-7.21,degrees,IGRF-14 (NOAA NCEI / IAGA),model,false,,false,,https://worldinlayers.com/api/v1/timeseries?lat=47.87&lon=18.19&model=igrf14&start=1900.0&end=2026.0&samples=127,ok,
…
A series costs 2 units per place. Before asking for environmental dates, call atlas_layer_coverage to see the archive range and which dates are retained.
Public sector, NGOs and humanitarian teams
Earthquakes of magnitude 4.5 or more in a box over Greece and western Turkey in the last 30 days, with their USGS event ids.
curl -s "https://worldinlayers.com/api/v1/agent/atlas_find_events?kind=earthquakes&bbox=19,34,30,42&window=30d&min_magnitude=4.5" \
-H "Authorization: Bearer $ATLAS_API_KEY"
Each event carries its USGS id, so you can cross-check it with the source. A page of events costs 1 unit; follow next_cursor for more. Add format=csv for a table.
Product developers and hobby projects
A home weather bot: temperature, wind and rain in Brno for the forecast hours, with local times.
curl -s https://worldinlayers.com/api/v1/agent/atlas_get_time_series \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"points":[{"place":"Brno","place_country":"CZ"}],"layers":["temperature","wind","precipitation"],"tz":"Europe/Prague"}'
Two units per place, whatever the number of layers up to 8. The response names the place it resolved (Brno, CZ). To pin one place for later calls, look it up once with atlas_find_place and send its place_id instead of the name.
Plans and quotas
Keys are part of the Plus (EUR 9 a month or EUR 79 a year) and Pro (EUR 19 a month or EUR 190 a year) plans, plus applicable tax. There is no free tier. See pricing.
Quotas are per account, not per key or per IP address, and reset at 00:00 UTC.
| Limit | Plus | Pro |
|---|---|---|
| Units per day | 3,000 | 10,000 |
| Requests per minute (burst) | 120 | 240 |
| Requests running at the same time | 2 | 4 |
| Cold archive loads per day (ERA5, OISST, NCEP) | 16 | 16 |
| Map cards per day | 10 | 30 |
| Places per batch call | 10 | 20 |
| API keys per account | 5 | 10 |
Calls cost units, weighted by the work they cause:
| Call | Units |
|---|---|
atlas_find_place, atlas_list_layers, atlas_layer_coverage, atlas_status, atlas_my_places, atlas_map_link | 1 |
atlas_get_point_values | 1 per place (any number of layers up to 8) |
atlas_get_magnetic_field | 1 |
atlas_get_time_series | 2 per place |
atlas_find_events | 1 per page |
atlas_area_stats | 10 (period: day: 10 per frame used, at most 40) |
atlas_japan_hazards | 1 per place |
| Cold archive load, per layer family and date, added to the call that needed it (at most 2 per call) | 25 |
atlas_make_map_card with dry_run: true | 5 |
atlas_make_map_card | 50 |
atlas_make_map_card for a magnetic date whose field map is not prepared yet (answers busy; at most 5 dates a day) | 5 |
A cold archive load happens when you ask for a historical date the atlas does not already hold: it fetches that date's map from the ERA5, OISST or NCEP archive. One map serves a family of layers, so a call pays one cold load per layer family and date. The families that share a map are temperature, humidity, feels_like, dew_point and wet_bulb; solar, precipitation, clouds and cape; wind, gusts and pressure; and snow_depth and soil_moisture. Every other layer that can be loaded (sea temperature, waves and each climate layer) is a family of its own. Dates listed as retained by atlas_layer_coverage need no cold load. A single call makes at most two: temperature, wind and clouds at one uncached date cost 1 + 2 × 25 = 51 units, and clouds comes back in unavailable[] with quota_exceeded (reason cold_load_limit).
Archive loads are shared with everyone who uses the atlas, so one account may make at most 5 an hour and 16 a day, whatever its plan: a third of the atlas's hourly allowance for the API and half of its daily one. Past them a load is refused with quota_exceeded (reason cold_load_limit) and quota cold_loads_account_hourly (retry_after runs to the next UTC hour) or cold_loads_account_share (until 00:00 UTC). When the atlas's own hourly or daily allowance runs out first, quota names that instead.
Every response reports what the call cost and what remains today. The same figures are on your account page, and GET /api/v1/agent/usage with your key returns today's and this month's usage for your account.
Getting a key
- Sign in and open your account page.
- Under API keys, choose Create key and give it a name you will recognise, such as "laptop Claude Code".
- Copy the key. It is shown once. We store only a hash of it; if you lose it, revoke it and create another.
- The same section lists each key's first characters, name, creation time, when it was last used and by which client, and today's usage against your plan.
- Revoke stops a key at once. Revoking cannot be undone.
Keys start with wil_. When a paid period ends, the plan continues for three days while the renewal is processed, and keys keep full access. If the subscription is not restored by then, your keys stay but return 402 plan_required until it is; the account page still lists them so you can revoke them. Deleting your account deletes its keys.
Authentication
Send the key in the Authorization header on every request:
Authorization: Bearer wil_…
Never put a key in a URL or query string; it would end up in logs and browser history. A key in the URL, in the query string or in the path, is refused with 401, even next to a valid header, and the hint asks you to revoke it because it may have been logged. Treat a key like a password: keep it in an environment variable or your client's secret store, not in a repository.
Report a security issue or a leaked key
If a key has leaked, for example into a public repository, a log or a shared transcript, first revoke it on your account page and create a new one; revoking takes effect on the next request. To report a security issue, or a key of someone else's that you have found, write to the contact in /.well-known/security.txt ([email protected]).
Quickstarts
Replace <key> with your key, or use an environment variable where the client supports one.
Claude Code
claude mcp add --transport http atlas https://worldinlayers.com/mcp --header "Authorization: Bearer <key>"
Then ask, for example, "What are the PM2.5, temperature and sea temperature in Lisbon, Portugal now? Give me a map link."
claude mcp get atlas prints the stored header, including the whole key. Do not run it on a shared screen or in a recorded terminal. To try the server without saving the key in a project's configuration, add it with --scope local from a scratch directory. If a key has been shown or logged, revoke it on your account page and create a new one.
Cursor
In ~/.cursor/mcp.json, or .cursor/mcp.json in a project. Cursor reads ATLAS_API_KEY from the environment it was started from, so set it in your shell profile or start Cursor from a terminal where it is set:
{
"mcpServers": {
"atlas": {
"url": "https://worldinlayers.com/mcp",
"headers": { "Authorization": "Bearer ${env:ATLAS_API_KEY}" }
}
}
}
VS Code
In .vscode/mcp.json. VS Code asks for the key once and stores it securely:
{
"inputs": [
{
"type": "promptString",
"id": "atlas-key",
"description": "World in Layers API key",
"password": true
}
],
"servers": {
"atlas": {
"type": "http",
"url": "https://worldinlayers.com/mcp",
"headers": { "Authorization": "Bearer ${input:atlas-key}" }
}
}
}
Gemini CLI
gemini mcp add --transport http -H "Authorization: Bearer <key>" atlas https://worldinlayers.com/mcp
Anthropic Messages API
Claude connects to the server for you through the MCP connector. Pass the key as authorization_token:
curl -s https://api.anthropic.com/v1/messages \
-H "x-api-key: $ANTHROPIC_API_KEY" \
-H "anthropic-version: 2023-06-01" \
-H "anthropic-beta: mcp-client-2025-11-20" \
-H "content-type: application/json" \
-d '{
"model": "claude-opus-5-5",
"max_tokens": 4096,
"mcp_servers": [{
"type": "url",
"url": "https://worldinlayers.com/mcp",
"name": "atlas",
"authorization_token": "'"$ATLAS_API_KEY"'"
}],
"tools": [{ "type": "mcp_toolset", "mcp_server_name": "atlas" }],
"messages": [{ "role": "user", "content": "Wind gusts in Porto, Portugal now, with the source of each number." }]
}'
OpenAI Responses API
Pass the key as authorization on an mcp tool:
curl -s https://api.openai.com/v1/responses \
-H "Authorization: Bearer $OPENAI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"model": "<model>",
"tools": [{
"type": "mcp",
"server_label": "atlas",
"server_url": "https://worldinlayers.com/mcp",
"authorization": "'"$ATLAS_API_KEY"'",
"require_approval": "never"
}],
"input": "Wind gusts in Porto, Portugal now, with the source of each number."
}'
curl and REST
curl -s https://worldinlayers.com/api/v1/agent/atlas_get_point_values \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-d '{"points":[{"place":"Lisbon","place_country":"PT"}],"layers":["temperature","pm25","sst"],"time":"now","tz":"Europe/Lisbon"}'
Every tool is at /api/v1/agent/<tool>. Use POST with a JSON body for several places and for cards; simple calls also accept GET with query parameters (repeat a parameter or separate values with commas for lists). Add format=csv to point values, series and events for a table.
Point values and series take their places as a list, even for one place: "points": [{"lat": 47.87, "lon": 18.19}] or "points": [{"place": "Brno"}]. In a JSON body, top-level lat, lon or place are refused as unknown properties. Only GET accepts them, as a shorthand for a single place: ?lat=47.87&lon=18.19&layers=temperature.
CSV is UTF-8 without a byte order mark, with CRLF line endings and a header row. Text cells that begin with =, +, -, @, a tab or a carriage return are prefixed with a single quote ('), so a spreadsheet shows them as text instead of running them as formulas; numbers are written as plain numbers, negative values with their minus sign. The full OpenAPI description is at /api/v1/openapi.json, and the tool schemas at /api/v1/agent/tools (no key needed for either).
MCP over curl
/mcp is stateless and answers JSON only (no event stream, no session id), so every request below stands alone. It speaks two protocol versions. Every request needs your key in Authorization. Send Content-Type: application/json and an Accept that includes application/json, as the examples do: a request without them is accepted, but a different body type is refused with 415 and an Accept without JSON with 406.
Protocol 2025-11-25 and earlier. Start with initialize, then send any request with the negotiated version in MCP-Protocol-Version:
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{"jsonrpc":"2.0","id":1,"method":"initialize","params":{"protocolVersion":"2025-11-25","capabilities":{},"clientInfo":{"name":"curl","version":"1.0"}}}'
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2025-11-25" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/list"}'
A notifications/initialized notification (no id) is acknowledged with HTTP 202 and can be sent in between; nothing is kept between requests either way.
Protocol 2026-07-28. There is no initialize. Every request carries params._meta with io.modelcontextprotocol/protocolVersion and io.modelcontextprotocol/clientCapabilities (io.modelcontextprotocol/clientInfo is optional), and three headers that must match the body: MCP-Protocol-Version (the version in _meta), Mcp-Method (the method) and, for tools/call and prompts/get, Mcp-Name with params.name, for resources/read with params.uri. A mismatch is refused with HTTP 400 and JSON-RPC error -32020. server/discover replaces the handshake:
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: server/discover" \
-d '{"jsonrpc":"2.0","id":1,"method":"server/discover","params":{"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
Call a tool:
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: tools/call" \
-H "Mcp-Name: atlas_get_point_values" \
-d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"atlas_get_point_values","arguments":{"points":[{"place":"Lisbon","place_country":"PT"}],"layers":["temperature"]},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
Read a resource:
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: resources/read" \
-H "Mcp-Name: atlas://layers/temperature" \
-d '{"jsonrpc":"2.0","id":3,"method":"resources/read","params":{"uri":"atlas://layers/temperature","_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
Get a prompt:
curl -s https://worldinlayers.com/mcp \
-H "Authorization: Bearer $ATLAS_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/json, text/event-stream" \
-H "MCP-Protocol-Version: 2026-07-28" \
-H "Mcp-Method: prompts/get" \
-H "Mcp-Name: atlas_explain_place" \
-d '{"jsonrpc":"2.0","id":4,"method":"prompts/get","params":{"name":"atlas_explain_place","arguments":{"place":"47.87, 18.19"},"_meta":{"io.modelcontextprotocol/protocolVersion":"2026-07-28","io.modelcontextprotocol/clientCapabilities":{}}}}'
In both versions tools/call takes arguments as an object; leave it out for a tool without arguments. Any other value, such as null, [] or false, is refused with JSON-RPC error -32602 before the tool runs, and costs nothing.
Claude.ai and ChatGPT
Available once sign-in is added. Claude.ai and ChatGPT connect to remote servers by having you sign in through OAuth; they cannot send a personal key header (Claude.ai only through a limited beta, ChatGPT not at all). Sign-in is planned, not built.
Tools
The live reference on this page lists every parameter, generated from the same registry the server uses. In short:
| Tool | Answers | Units |
|---|---|---|
atlas_find_place | Which place is this? Names, postcodes and countries in any language, or the nearest places to a coordinate; reports ambiguity with candidates | 1 |
atlas_list_layers | What can the atlas read? Layers by group, with units, licence, attribution and history start | 1 |
atlas_layer_coverage | Which dates exist for a layer? Current snapshot, archive range and retained dates | 1 |
atlas_status | How fresh is each source? Model-run and retrieval times | 1 |
atlas_get_point_values | Up to 8 layers at one or more places for one time | 1 per place |
atlas_get_magnetic_field | Field strength, declination, inclination and their change at a point and date | 1 |
atlas_get_time_series | Up to 8 layers over time at one or more places | 2 per place |
atlas_find_events | Earthquakes, fire detections or volcanoes near a place or in a box | 1 per page |
atlas_area_stats | Mean, minimum, maximum and share above a threshold over a country, box or circle | 10 (day: up to 40) |
atlas_japan_hazards | Official hazard zones, projected population, earthquake shaking probability and nearby official land prices at places in Japan | 1 per place |
atlas_map_link | A worldinlayers.com link that opens the same layers, time and place | 1 |
atlas_my_places | Your saved places (needs the places scope) | 1 |
atlas_make_map_card | A shareable map card, marked as made through the API (needs the cards scope) | 5 dry run, 50 |
Every tool except atlas_make_map_card only reads. Cards accept the template titles offered by a dry run, never free text, and cannot include satellite layers. Japan hazard cards show the current editions; a Japan population card shows the year of time (2030, 2040, 2050 or 2070; 2050 by default). Repeating a card request with the same client_request_id returns the same card free of charge; a request for a card identical to one that already exists returns that card for 5 units and does not count as a new card. (If that earlier card was deleted in the meantime, the repeat answers busy, reason card_replay_gone, free of charge; retrying makes a new card at the normal price.) Earthquake cards show the latest 7 days of earthquakes of magnitude 4.5 or more. A magnetic field card for a date whose field map has not been calculated yet answers busy (reason magnetic_map_preparing, retry_after 15) and costs 5 units while the map is prepared; retry with the same arguments, which costs nothing more until the map is ready and then the card's 50 units. Each account may start at most 5 such maps a day; after that the call is refused with quota_exceeded (quota: magnetic_preparations) until 00:00 UTC, free of charge. A dry run for such a date queues nothing and answers not_available (reason magnetic_map_not_prepared), also free.
atlas_find_events refuses an argument its kind does not use, with invalid_input: window and min_magnitude apply to earthquakes only, start and end to earthquakes and fires. Volcano rows give the latest significant eruption as time when the catalogue dates it to the day (otherwise time is empty) and, around a point, the distance in distance_km. atlas_map_link refuses a time that any of its layers cannot show, a future time more than 3 hours after its forecast's last frame: outside_snapshot (reason outside_forecast); with several layers, the error's layer field names the one that cannot.
Over MCP the server also offers two prompts, atlas_explain_place and atlas_compare_places, which carry the house style (cite every number, name the data kind, no verdicts, end with a map link), and resources (atlas://guide, atlas://layers, atlas://layers/{id}, atlas://attribution) so your agent can read the layer notes and licences once instead of asking every turn.
Units, time and data kinds
Units
Metric only, exactly as the atlas shows them: °C, %, km/h, hPa, mm/h, mm/day, J/kg, cm, m³/m³, W/m², UV index, µg/m³, aerosol optical depth at 550 nm, m, MW (fire radiative power), magnitude, nT, nT/year and degrees. Every value names its unit; convert on your side if you need to.
Time
- All times are ISO 8601 and UTC unless they carry an offset.
timeaccepts:now;- a date,
2026-10-23, meaning 12:00 UTC, or local noon when you passtz; - a date and time,
2026-10-23T15:00Zor2026-10-23T17:00+02:00; - for the seasonal climate layers, a month
01–12(the 1991–2020 average), orYYYY-MMfor one past month. tztakes an IANA time zone such asEurope/Lisbon. With it, rows also carrylocal_time, andperiod: dayin area statistics means that place's local day.startandendof series and event searches are read against the current snapshot: a range that runs past its first or last frame is answered for the part inside it, with a note naming both ranges; a range wholly outside it is refused (outside_snapshotfor events,not_availablefor series).
Places and countries
Places are coordinates (lat and lon), names (place) or place_ids from atlas_find_place. Give each place one way: place with lat/lon, place with place_id, place_id with lat/lon, and place_country without place are refused with invalid_input (reason conflicting_place). A place_id names exactly one place.
A name resolves like this:
- The largest clear match wins. A name shared by several places resolves to the largest clear match: a capital with twice, or a place of at least 50,000 people with five times, the population of the next namesake elsewhere (Lisbon, Portugal over the Lisbons in the United States). The others come back in
candidates[], each with itsplace_id, region, country,matchandpopulation, so your agent can mention them or choose another. - Local names such as Lisboa, Wien, München or Roma resolve as well as the English ones, but an alternate name never beats a place bearing the name itself when
place_countrynarrows it, nor a namesake of 50,000 people or more. - No clear match returns
ambiguous_placewith the candidates and theirplace_ids (Springfield, for example). - Partial matches never resolve silently. A name that only starts with or contains your text returns
ambiguous_placewith the closest names, never one of them.
Common names exist in many countries, so add an ISO 3166-1 alpha-2 code to narrow one: place: Porto with place_country: PT. Every tool that takes place accepts place_country, and so does each item of points[]. country means something else and exists in two tools only: in atlas_find_place it narrows the query, and in atlas_area_stats it is the area itself (country: PT gives statistics over all of Portugal; there place_country narrows the name of the place at the centre of a circle).
valid_timeis the UTC time a value is valid for; a count of fire detections gives the window it counted as an interval,2026-10-21T11:00:00Z/2026-10-22T11:00:00Z. In the detailed format itslabelis "Active fire detections in the snapshot window" and itstime_labelreads "Detections from 2026-10-21T11:00:00Z to 2026-10-22T11:00:00Z", because the newest snapshot may have ended up to a day before you ask. Gridded layers come in frames (forecast hours, analysis days); when the frame used is not exactly the time you asked for,offset_minutessays how far apart they are, to the minute, and from 3 hours apart a note names the time you asked for, the frame's time and the distance, written like "(2 days 1 h 40 min earlier)" or "(3 h 20 min later)". The atlas never picks a nearby frame without saying so, and never swaps a forecast in for a missing historical value.- The archive trails the present by a few days and a new forecast run drops the hours before it, so a recent time can fall between the two. Then the answer is
not_available(reasonno_data) with a message naming both edges, for example "the archive runs through 2026-10-19 and the current forecast starts at 2026-10-25T12:00:00Z", and the error'sgapobject holdsarchive_endandforecast_start. When an earlier forecast snapshot that is still retained holds the time,gap.snapshot_versionnames it and the hint tells you to send it assnapshot_version.
Data kinds
Every value names one of these:
| Data kind | Meaning | Examples |
|---|---|---|
forecast | A model's prediction for a future or current time | NOAA GFS weather, FMI SILAM air quality, NOAA CPC UV |
analysis | A best estimate of a past day from observations, on a grid | NOAA OISST sea surface temperature |
reanalysis | A consistent reconstruction of the past from observations and a model | Copernicus ERA5, CAMS EAC4, NCEP/NCAR |
observation | Something a satellite or network detected or recorded | NASA FIRMS fire detections, USGS earthquakes, OMI UV |
climatology | A long-term average | 1991–2020 monthly temperature, rain and humidity |
model | A value computed from a published model within its validity period | IGRF-14 and other magnetic field models |
official_designation | An official zone under Japanese law; a scenario, not a prediction | Japan hazard zones (MLIT KSJ) |
official_projection | An official projection by a government agency | Japan's residents per 1 km mesh (MLIT KSJ) |
Magnetic values are always model on the API. For dates beyond a model's main-field epoch they also carry predictive: true: they extrapolate the model's predicted secular variation (for IGRF-14 and WMM, dates after 2025). Dates outside a model's published validity are refused, never extrapolated further. The example below, for 24 October 2026, is one.
Values may also be marked preliminary (recent ERA5T or OISST days, recent earthquake solutions, near-real-time fire detections), which the source can still revise.
The response envelope
Every tool returns the same envelope. This is a recorded response, from a local run on 24 October 2026, to the magnetic field at the Hurbanovo observatory in Slovakia:
curl -s "https://worldinlayers.com/api/v1/agent/atlas_get_magnetic_field?lat=47.87&lon=18.19&date=2026-10-24" \
-H "Authorization: Bearer $ATLAS_API_KEY"
{
"ok": true,
"tool": "atlas_get_magnetic_field",
"data": {
"point": {
"lat": 47.87,
"lon": 18.19,
"name": "47.8700, 18.1900",
"altitude_km": 0.0
},
"model": {
"id": "igrf14",
"version": "IGRF-14",
"kind": "model",
"attribution": "NOAA NCEI / IAGA",
"uncertainty": "Model estimates; local and external fields are not fully represented.",
"valid_from": "1900-01-01",
"valid_to": "2030-01-01",
"predictive_from": "2025-01-01",
"predictive": true
},
"date": "2026-10-24",
"columns": ["quantity", "value", "units", "valid_time", "cite"],
"rows": [
["Total field intensity F · IGRF-14", 49246, "nT", "2026-10-24", "c59a259-1"],
["Declination D (east positive) · IGRF-14", 5.69, "degrees", "2026-10-24", "c59a259-1"],
["Inclination I (down positive) · IGRF-14", 64.64, "degrees", "2026-10-24", "c59a259-1"],
["Horizontal intensity H · IGRF-14", 21089, "nT", "2026-10-24", "c59a259-1"],
["Vertical intensity Z (down positive) · IGRF-14", 44502, "nT", "2026-10-24", "c59a259-1"],
["Yearly change of F at 2026-10-24 · IGRF-14", 50.4, "nT/year", "2026-10-24", "c59a259-2"]
]
},
"citations": [
{
"id": "c59a259-1",
"layer": "magnetism",
"provider": "IGRF-14 (NOAA NCEI / IAGA)",
"data_kind": "model",
"preliminary": false,
"source_url": "https://worldinlayers.com/api/v1/point?lat=47.87&lon=18.19&model=igrf14&date=2026-10-24",
"model": "igrf14",
"predictive": true
},
{
"id": "c59a259-2",
"layer": "magnetism",
"provider": "IGRF-14",
"data_kind": "model",
"preliminary": false,
"source_url": "https://worldinlayers.com/api/v1/point?lat=47.87&lon=18.19&model=igrf14&date=2026-10-24",
"model": "igrf14",
"predictive": true
}
],
"attribution": [
"Magnetic field: IGRF-14, International Association of Geomagnetism and Aeronomy (IAGA); coefficients distributed by NOAA NCEI."
],
"notes": [
"Model values, not certified navigation or aeronautical guidance. Official charts and national survey values take precedence; local anomalies from rocks, buildings or vehicles are not included."
],
"links": {
"map": "https://worldinlayers.com/magnetic-field?date=2026-10-24¢er=18.1900%2C47.8700&zoom=6.00&places=%5B%7B%22id%22%3A%22ask-47.8700-18.1900%22%2C%22name%22%3A%2247.8700%2C+18.1900%22%2C%22latitude%22%3A47.87%2C%22longitude%22%3A18.19%2C%22kind%22%3A%22place%22%7D%5D"
},
"usage": {
"units": 1,
"units_today": 1193,
"units_limit": 10000,
"cold_loads_today": 1,
"cold_loads_limit": 16,
"cards_today": 0,
"cards_limit": 30
}
}
Magnetic models are files held by the atlas, so their citations have no snapshot_version or retained_until; values from forecasts, analyses and archives carry both. usage shows the limits of the plan the key belongs to (Pro here).
| Field | What it holds |
|---|---|
ok, tool | Whether the call succeeded, and which tool answered. |
data | The answer. By default (response_format: concise) a table: columns and rows, with a cite id on each row. response_format: detailed returns full objects instead, such as points[]{place, values[], unavailable[]}. |
citations[] | One entry per distinct source (in the concise format, one per layer and snapshot): data_kind, provider, snapshot_version (the data snapshot the value came from), retained_until (how long that snapshot is kept), and source_url, an absolute public link that returns the same value while the snapshot is retained (or source_url_template, filled from each row, when the rows were read at different places). Derived figures such as area means and shares carry reproduce{tool, args, snapshot_version} instead of a link. |
attribution[] | The credit line for each provider in the response, once each. Show it wherever you publish the numbers; see Attribution and citing. |
notes[] | Caveats you should pass on: preliminary data, coastal points read from the nearest open water, a frame 3 hours or more from the requested time, a range cut to the snapshot, a local day that daily area statistics cover only in part, and the reminder that the atlas shows data, not verdicts. Every frame offset is also in its row's offset_minutes. |
links.map | A worldinlayers.com link that opens this layer, time and place, so a person can look. A layer of atlas_get_point_values that had no value for the requested time is left out of it, and a note says so. |
usage | Units this call cost, units used today and your daily limit, and the same for cold archive loads. Over MCP the same object is in the result's _meta.usage. |
Citation ids look like c3f9a2b-1: a random six-hex-digit prefix for the call and a number, so they are unique within one response and differ between responses. Cite them exactly as returned, and when an answer combines several responses, keep each id together with its source_url.
The concise format keeps citations short: there is one citation per layer and snapshot, so the rows of one layer share its id. In a series or a batch of places, every row of a layer cites the same id, not one id per row (a series whose days mix final and preliminary values has two, one for each, and so has a magnetic series that mixes model and predictive years). When the rows citing an id were read at different coordinates or times, or are different events, the citation carries source_url_template instead of source_url (earthquakes also provider_url_template instead of provider_url), with {lat}, {lon}, {id} and {frame} placeholders. Fill them from the row's own lat, lon and id cells, and {frame} from its frame cell (or, when the table has no frame column, its time), to get the exact link for that row. The concise tables have these columns:
- point values:
place,lat,lon,layer,value,units,data_kind,valid_time,local_time(withtz),offset_minutes,cite; - series:
place,place_id,lat,lon,layer,time,frame(only when a frame's id differs from its time, as for daily sea temperature, read from the 00:00 frame and valid at 12:00),local_time(withtz),value,units,cite.
Point values and series also return places[], the places as resolved, in the order you sent them. A place that did not resolve keeps what you sent (place, place_country, place_id, or lat and lon) and adds status, its error code such as invalid_place; its values are in unavailable[].
lat and lon are where the value was read, which for a sea layer at a coastal place is the nearest open water. REST CSV (format=csv) replaces cite with the citation's provider, data_kind, preliminary (true or false), stale (true while the source's refresh is overdue, else empty), predictive (true or false for magnetic values, else empty; per row, so a magnetic series that runs past a model's main-field epoch has two citations, one for the model years and one for the predictive years), snapshot_version and source_url (columns the table already has are not repeated), and fills the template, so every CSV row has its exact source_url. Event CSVs add the provider's own page, provider_url, after it. Point-value and series CSVs end with two more columns, status (ok, or the error code such as no_coverage) and error (the message), and add one row with an empty value for each layer or place that could not be answered (with its place and layer; a place that did not resolve is named as you sent it), so a partial export cannot pass for a complete one; JSON lists those in unavailable[] instead, with retry_after when a retry may succeed. response_format: detailed is unchanged: every value has its own citation with its own source_url.
Derived values (area statistics, series, event counts, volcano distances) also carry reproduce: the call, with resolved times, coordinates and snapshot_version, that returns them again while the snapshot is retained. It covers only that citation's layers: a series of temperature and PM2.5 gives the weather citation a call for temperature and the air-quality citation one for PM2.5. The volcano catalogue keeps only its current version, which each volcano citation states in retention. An earthquake count also carries provider_url: the USGS FDSN query for the same window, area and minimum magnitude, to check the count against USGS's live catalogue (which revises automatic solutions, so its answer can change later; reproduce replays the atlas's snapshot).
Rows and citations are in a stable order. A JSON answer is at most 60,000 characters, about 20,000 tokens, so an MCP result stays under the 25,000-token default limit of common clients such as Claude Code. In the concise format that is plenty: 20 places × 8 layers of point values is about 22,000–31,000 characters, and a page of 100 events about 16,000–24,000. A detailed answer holds about 40 values or events. One call also returns at most 500 rows in the concise format, 100 in the detailed format and 20,000 as CSV (places × layers × frames or samples; a magnetic layer is five rows), and a CSV download is at most 8,000,000 characters, measured on the CSV text.
A call that would be larger is refused before it runs, free of charge, with too_large (reason too_many_rows or response_size) and a hint: fewer places or layers, a cursor for events, or format=csv on REST. Only a detailed caller is told to switch to the concise format. Nothing is cut off silently.
Errors
An error has the same outer shape, with ok: false. This is the recorded response to the same call with lat=200:
{
"ok": false,
"tool": "atlas_get_magnetic_field",
"error": {
"code": "invalid_input",
"reason": "invalid_arguments",
"message": "args.lat: must be at most 90.",
"hint": "Check the arguments against this tool's inputSchema at /api/v1/agent/tools."
}
}
Errors that a different call can resolve also carry next, for example {"tool": "atlas_layer_coverage", "args": {"layer": "pm25"}}, and busy, timeout and quota_exceeded carry retry_after in seconds.
code is the stable public vocabulary below. reason is the more specific internal cause, useful in bug reports. hint says what to change, and next, when present, is a call your agent can make to recover.
Over MCP, a tools/call error is a tool result (HTTP 200) marked isError: true, with the same envelope in structuredContent, so your agent sees the hint and retry_after. That includes too_large, the daily and per-minute quotas (quota_exceeded, reason quota_burst for the per-minute limit), a lapsed plan (plan_required) and a suspended account (suspended). Other MCP methods, such as tools/list, answer those three account refusals with JSON-RPC error -32000, the envelope's error object in data, and HTTP 402, 403 or 429 with Retry-After.
Over MCP, only these refusals are plain HTTP errors ({"error": {...}}, no JSON-RPC envelope): a missing or unknown key, or a key in the URL (HTTP 401 invalid_key), too many failed key attempts from one address (429 quota_exceeded with retry_after 600 and Retry-After), a request from a web page (403 invalid_origin) or to another host name (421 invalid_host), a method other than POST (405), a path other than /mcp (404) and a switched-off API (503 disabled). Everything else is JSON-RPC: the per-address limits (HTTP 429, error -32000, reason ip_burst), a body over 64 KiB (HTTP 413, error -32000, code too_large), a request without application/json in Accept (406) or as its body type (415), all with id: null, and malformed JSON (-32700), which includes a string that escapes an unpaired UTF-16 surrogate (HTTP 400, "Parse error: a string escapes an unpaired UTF-16 surrogate.", id: null). An unknown tool is not_available with reason unknown_tool: HTTP 404 on REST, JSON-RPC error -32602 over MCP.
Some invalid_input reasons worth knowing: invalid_cursor for a find_events cursor that this server did not write for the same search (repeat the search with the same arguments and the cursor it returned, or without a cursor); invalid_text on REST for a string argument or key with an unpaired UTF-16 surrogate, such as "\ud83d" from text cut in the middle of an emoji (whole characters and paired escapes are fine; over MCP the request is the -32700 parse error above); and control_character for C0 or C1 control characters. None of them costs units.
| Code | HTTP | Meaning | What to do |
|---|---|---|---|
invalid_key | 401 | The key is missing, malformed, revoked, or not in the Authorization header. | Send Authorization: Bearer <key>; create a new key if it was revoked. |
invalid_input | 400 | A parameter is missing, unknown or out of range. | Read hint; check the tool's schema at /api/v1/agent/tools. |
invalid_place | 400 | The place could not be found. | Try another spelling, add place_country, or call atlas_find_place. |
ambiguous_place | 409 | Several places match. | Choose one of the candidates and send its place_id. |
no_coverage | 404 | The layer has no value at that place or time (for example, sea temperature on land). | Call atlas_layer_coverage; pick another point or time. |
not_retained | 404 | That historical date is not held and cannot be loaded now, or the snapshot_version you sent is no longer kept. | Check the retained dates with atlas_layer_coverage, or use another layer; for a snapshot, use one the hint names or leave snapshot_version out. |
outside_snapshot | 404 | The time or window is outside the snapshot: past a forecast's last frame, outside a pinned snapshot_version, or an event window wholly outside the current snapshot (for example, earthquakes older than 30 days). | Narrow the dates to the snapshot that atlas_layer_coverage reports. |
frame_too_far | 404 | The newest data is too old to stand for now: a fire snapshot that ended more than 24 hours ago (also for today's date), a newest sea-temperature day more than 4 days old, or a forecast whose last frame is more than 3 hours before now. | Say the data is not current, or ask for an explicit time inside the snapshot. |
not_available | 404 | The atlas does not offer this, for example a multi-year environmental series. | Read hint; see What the atlas does not answer. |
too_large | 413 | The request or its answer is too big: more places than your plan's batch, a body over the size limit, or an answer over the limits. | Use fewer places or layers, a smaller area, or follow the cursor. |
licence_pending | 451 | The source's terms do not yet allow us to pass this on through the API. | Read hint; the website may still show it on the map. |
plan_required | 402 | The key's account has no active Plus or Pro subscription. reason says why: no_subscription, lapsed, restricted or deleting. | Renew at /pricing; the key works again once the plan is active. |
scope_required | 403 | Reserved: the key lacks the scope this tool needs (read, cards or places). Not returned today, because every key carries all three scopes. | — |
suspended | 403 | API access for this account is suspended. | Write to [email protected]. |
quota_exceeded | 429 | A daily, burst, cold-load, card or magnetic-map preparation quota is used up. The error names which. | Wait retry_after seconds, or until 00:00 UTC for daily quotas. |
busy | 503 | As many of your calls are running as your plan allows, the shared capacity or the archive loader is in use, an archive's provider did not answer, or a map card's magnetic field map is still being calculated. | Retry after retry_after seconds. |
timeout | 504 | The call ran past its 30-second budget. The charge stands, because the archive map it loaded is kept for your retry. | Retry the same call after retry_after. |
disabled | 503 | This tool, or the whole API, is switched off for maintenance. | Try later, or use another tool for the same data. |
internal | 500 | Something failed on our side. | Retry once; if it repeats, tell us at [email protected] with the time and reason. |
Limits and headers
- Units per day, cold archive loads and map cards reset at 00:00 UTC.
- Burst: 120 requests a minute on Plus, 240 on Pro, per account.
- Concurrency: 2 requests at the same time on Plus, 4 on Pro. One more is refused with
busy(reasonaccount_concurrency,retry_after2) and costs nothing. A call counts until it has finished on our side, even if your client gave up, and is charged as usual. - Batch size: up to 10 places per call on Plus, 20 on Pro; more is refused with
too_large(reasonbatch_limit). - Time budget: 30 seconds per call.
- Shared guards protect the website for everyone, whatever your plan: at most 15 cold archive loads an hour across all keys, at most 32 a day (half of the 64-map history cache), of which one account may take at most 5 an hour and 16 a day; at most 6 API calls running at once across all keys; and at most 2 area-statistics calls at once, one per account. When one is reached you get
busyorquota_exceededwithretry_after. - Per address: an address is an IPv4 address or an IPv6 /64 network. Requests to the tools and
/mcpwithout a valid key are limited to 1,200 a minute per address; requests with a valid key answer to your account's burst instead, so other people's failed attempts behind a shared address, such as a hosted connector's, do not use up yours. A much higher safety ceiling (12,000 a minute) counts every request. Both answer429 quota_exceededwith reasonip_burstand aretry_afterof 60 seconds. Failed authentication is limited to 30 attempts per 10 minutes per address; after that the address gets429 quota_exceededwithretry_after600. - Request size: a REST body may be up to 256 KiB (262,144 bytes) and an MCP request up to 64 KiB (65,536 bytes); larger requests are refused with HTTP 413
too_large(reasonbody_too_large) before they run. UsePOSTfor long arguments: aGETURL over about 16 KiB may be refused by the server with a plain HTTP 400 before the API sees it.
Every keyed REST tool response for a known account carries these headers, refusals included: invalid arguments (also a body that is not a JSON object), the per-minute burst and a method the tool does not take (405). The key is checked before the arguments, so a missing or invalid key gets 401 whatever the arguments. Without a known account only X-Atlas-Cost: 0 is sent, and the quota headers are left out rather than sent as 0: for 401, the failed-key 429, 402, 403 suspended and an unknown path, and for refusals made before the key is read (a wrong method, a body over the size limit or nested too deeply, the per-address limits, a switched-off API):
| Header | Meaning |
|---|---|
X-Atlas-Units-Limit | Your daily units. |
X-Atlas-Units-Remaining | Units left today. |
X-Atlas-Units-Reset | Seconds until 00:00 UTC. |
X-Atlas-Cost | Units this call cost. |
X-Atlas-Burst-Limit | Requests allowed per minute. |
X-Atlas-Burst-Remaining | Requests left in the current minute. |
Responses are never cached (Cache-Control: private, no-store). There is no CORS: call the API from a server or an agent, not from a web page, so your key stays private.
Attribution and citing
The data comes from public agencies and research groups whose licences ask for credit. Those terms pass through to you: when you publish numbers from the atlas, show the credit for each provider involved. Each response already lists them in attribution[]; the full table is at /api/v1/agent/attribution. The copy-ready lines are below; the API fills in [year] with the current year.
| Provider | Credit line (exactly as in attribution[]) | Licence | Also cite in research |
|---|---|---|---|
| Copernicus ERA5 | Contains modified Copernicus Climate Change Service information [year]. Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains. | CC BY 4.0 | Hersbach, H. et al. (2023): ERA5 hourly data on single levels from 1940 to present. Copernicus Climate Change Service (C3S) Climate Data Store (CDS). DOI: 10.24381/cds.adbb2d47 |
| CAMS EAC4 | Contains modified Copernicus Atmosphere Monitoring Service information [year]. Neither the European Commission nor ECMWF is responsible for any use that may be made of the Copernicus information or data it contains. | CC BY 4.0 | Inness, A. et al. (2019): The CAMS reanalysis of atmospheric composition. Atmospheric Chemistry and Physics, 19, 3515–3556. DOI: 10.5194/acp-19-3515-2019 |
| FMI SILAM | Air-quality forecast: Finnish Meteorological Institute SILAM, CC BY 4.0. | CC BY 4.0 | — |
| NOAA GFS | NOAA GFS: data from the US National Weather Service, public domain; attribution requested. | US government open data | — |
| NOAA GFS-Wave | NOAA GFS-Wave: data from the US National Weather Service, public domain; attribution requested. | US government open data | — |
| NOAA CPC UV | NOAA CPC UV index forecast: data from the US National Weather Service Climate Prediction Center, public domain; attribution requested. | US government open data | — |
| NOAA NCEI OISST | NOAA OISST v2.1: NOAA National Centers for Environmental Information, public domain; attribution requested. | US government open data | Huang, B. et al. (2021): Improvements of the Daily Optimum Interpolation Sea Surface Temperature (DOISST) Version 2.1. Journal of Climate, 34, 2923–2939. DOI: 10.1175/JCLI-D-20-0166.1 |
| NOAA PSL | NCEP/NCAR Reanalysis 1 data provided by the NOAA PSL, Boulder, Colorado, USA, from their website at https://psl.noaa.gov | US government open data | — |
| NASA FIRMS | We acknowledge the use of data from NASA's Fire Information for Resource Management System (FIRMS) (https://www.earthdata.nasa.gov/firms), part of NASA's Earth Science Data and Information System (ESDIS). | NASA open data | — |
| NASA Aura OMI | UV index: NASA Aura OMI OMUVBd v003, distributed by the NASA Goddard Earth Sciences Data and Information Services Center (GES DISC). | NASA open data | — |
| USGS | Earthquakes: U.S. Geological Survey Earthquake Hazards Program and contributing seismic networks. | US public domain; retain contributing network credits | — |
| NOAA NCEI volcanoes | Volcanoes: NOAA NCEI / WDS Global Significant Volcanic Eruptions Database; volcano locations compiled from the Smithsonian Global Volcanism Program. | CC0; retain attribution | NGDC/WDS, NOAA NCEI. doi:10.7289/V5JW8BSH |
| GeoNames | Places: GeoNames (geonames.org), CC BY 4.0. Contains Royal Mail data © Royal Mail copyright and database right 2022. | CC BY 4.0 | — |
| geoBoundaries | Administrative names: geoBoundaries (www.geoboundaries.org), CC BY 4.0. | CC BY 4.0 | Runfola, D. et al. (2020): geoBoundaries: A global database of political administrative boundaries. PLoS ONE 15(4), e0231866 |
| GFZ | Geomagnetic indices: GFZ Helmholtz Centre for Geosciences, CC BY 4.0 (sunspot numbers are not included). | CC BY 4.0 | Matzka, J. et al. (2021): The geomagnetic Kp index and derived indices of geomagnetic activity. Space Weather, 19, e2020SW002641. DOI: 10.1029/2020SW002641 |
| IGRF-14 | Magnetic field: IGRF-14, International Association of Geomagnetism and Aeronomy (IAGA); coefficients distributed by NOAA NCEI. | Public reference coefficients; attribution requested | — |
| WMM | Magnetic field: World Magnetic Model WMM2025 / WMMHR2025, NOAA NCEI and the British Geological Survey; public domain. | US government open data | — |
| CHAOS-8 | Magnetic field: CHAOS-8 model, Finlay and colleagues, DTU Space; published on Zenodo under CC BY 4.0. | CC BY 4.0 | — |
| EMAG2 | Magnetic anomalies: EMAG2 v3, Meyer, Saltus & Chulliat (2017), NOAA NCEI; public domain. | US government open data | — |
| EarthRef | Magnetic field: CALS10k.2 (Constable, Korte & Panovska 2016), GGF100k (Panovska, Constable & Korte 2018) and GGFMB (Mahgoub, Korte & Panovska 2023), EarthRef Digital Archive, CC BY 4.0. | CC BY 4.0 | — |
| Natural Earth | Country outlines: Natural Earth, public domain. | Public domain | No credit required |
| MLIT KSJ (Japan) | One line per dataset: 「国土数値情報(…)」(国土交通省)(page)を加工して作成, in English too, not endorsed by MLIT; exact lines at /api/v1/agent/attribution | CC BY 4.0 (KSJ terms); A22: 商用可 | Prefecture terms: /api/v1/japan-hazards/status |
Do not use agency logos or suggest that a provider, NOAA included, endorses your work. If you change the data (convert units, average, crop), say so beside the credit.
Citing a value
To cite one number, give the provider, the data kind and valid time, the snapshot_version and the source_url. For example:
Temperature in Lisbon 19.2 °C, NOAA GFS forecast valid 23 October 2026 12:00 UTC, World in Layers snapshot 20261023T051925-bc89e777, https://worldinlayers.com/api/v1/environment/point?…
The source_url returns the same value until retained_until. After that the snapshot is gone; keep the response if you need a permanent record. For area statistics and other derived figures, cite reproduce and the method text instead: calling reproduce.tool with reproduce.args, including its snapshot_version, recalculates the same figure from the same snapshot while it is retained. atlas_get_point_values, atlas_get_time_series, atlas_area_stats and atlas_find_events all accept snapshot_version, so the same values can be read again from a cited snapshot after a newer one is published. A badly formatted snapshot_version is 400 invalid_input; a snapshot that is no longer kept answers 404 not_retained, naming the range that is retained. When the newest snapshot has itself been current for more than 7 days, retained_until is left out: it is kept until the next one is published. Earthquake citations from the current snapshot also have no retained_until; a note says the snapshot is kept while it is current. A map card is a permanent, citable snapshot of its own.
What the atlas does not answer
- No verdicts. It never says whether something is safe, healthy or advisable, issues no warnings and gives no health, safety, travel or emergency advice. Where a question invites one,
notes[]says the atlas shows data and points to national weather, marine or civil-protection services. Your agent should do the same. - No scores that combine layers, and no air-quality categories.
- No satellite pixel values. The Sentinel layers (imagery, NDVI, NBR, SO₂, land surface temperature) are images on the website only.
- No Smithsonian GVP eruption records. Volcano answers come from the NOAA significant-eruption catalogue, with links to GVP pages.
- No ESA Swarm measurements and no geomagnetic observatory series.
- No boundary geometry. geoBoundaries is used only to name the area around a point.
- No multi-year environmental series. Series cover the current snapshot (forecast hours, recent sea-temperature days, the 12 climate months); magnetic series span centuries. For single historical dates, call
atlas_layer_coveragefirst to see the archive range and retained dates. - No imperial units, Parquet or GeoJSON, and no named sub-national regions yet.
- No verdicts on Japanese hazard zones.
atlas_japan_hazardsreturns official designations and planning scenarios, never whether a place is fit to buy, rent or live in. Outside the mapped zones means only that the edition maps no zone there. It is not the municipal hazard map and cannot be used for the Important Matters Explanation (重要事項説明) in a property transaction; the official map is the Hazard Map Portal Site (重ねるハザードマップ), linked asportal_urlfor each place.
Terms in plain words
These points summarise how keys may be used; the terms of service govern.
- A key is personal. Use it yourself and in your own agents, scripts and services.
- Do not embed a key in software you distribute to other people, such as an app, a plugin or a public repository. Each person needs their own key.
- Quotas are part of the plan. Do not spread one person's use across several accounts to get around them.
- Data licences flow through to you. Show the attribution for what you publish and follow each provider's terms.
- What we record: for each call, the time, your account, the key, REST or MCP, the tool, units, outcome, duration and the client name your software sends (up to 120 characters); calls refused before they run are recorded up to 100 per account a day. Kept for 90 days for quotas, abuse prevention and your usage page. We never record coordinates, place names or other content of your requests. See the privacy policy.
- We may switch off a tool or the API for maintenance, and suspend API access or revoke a key that is abused, exposed or shared.
Changelog
Last verified: 24 October 2026, end to end against a local server of this release: keys, REST (JSON and CSV), MCP in both protocol eras, resources and prompts.
Japan hazard zones
atlas_japan_hazards: official flood, tsunami, storm-surge, landslide and heavy-snow zones in Japan (MLIT National Land Numerical Information) and the projected population of the 1 km mesh, at up to 10 places (20 on Pro), 1 unit per place. New data kindsofficial_designationandofficial_projection; the seven Japan layers open withatlas_map_link. Also returns the J-SHIS 30-year probabilities of strong shaking for the 250 m mesh (official_probability) and the nearest official land prices (official_price, MLIT KSJ L01-2026) and the municipality's vacant-home rates (official_statistics, 2023 Housing and Land Survey).
First release
- REST tools at
/api/v1/agent/<tool>and the MCP server at/mcp, with personal API keys for Plus and Pro members. - Twelve tools:
atlas_find_place,atlas_list_layers,atlas_layer_coverage,atlas_status,atlas_get_point_values,atlas_get_magnetic_field,atlas_get_time_series,atlas_find_events,atlas_area_stats,atlas_map_link,atlas_my_placesandatlas_make_map_card. - Weighted units, daily quotas, the response envelope with citations and attribution, the public error vocabulary and the
X-Atlas-*headers. - MCP prompts
atlas_explain_placeandatlas_compare_places, and resources for the guide, layers and attribution.
Tool reference
Every tool's name, description, cost in units and input schema is published live at
/api/v1/agent/tools (JSON, no key needed)
and in the OpenAPI description at /api/v1/docs.
The interactive version of this page lists them with their
parameters.