The perception layer, as an API
Call the Digital Twin Earth over MCP or plain REST. Site intelligence, live hazards, buildings, traffic, place trends and street-level vision, every figure with disclosed provenance.
The API is keyless. Every endpoint answers without a key, without a card, without a signup. A key is optional and free: it names your usage and raises the per-minute ceiling from 120 to 600 requests per minute. That is all it does.
Keys and fair use
Keyless by default. A key is optional and free: it names your usage and raises the per-minute ceiling. That is all it does.
| Tier | Rate limit | Scope | Cost |
|---|---|---|---|
| Anonymous | 120 req/min | per IP | Nothing. Just call. |
| With a free key | 600 req/min | per key | free, issued in the developer dashboard at /user/keys |
Getting and using a key
Keys are issued for free on the developer dashboard. Rotating there issues a new key and kills the old one immediately. Pass it as the X-Api-Key header or as a ?key= query parameter.
curl "https://api.solyzer.ai/earth/usage" \
-H "X-Api-Key: YOUR_KEY"GET /earth/usage returns your own consumption: owner (masked), today's total and per-path breakdown, the month total and a daily series. Without a valid key it returns 401.
Rate limits and metering
Every /earth response carries X-RateLimit-Limit and X-RateLimit-Remaining. When you cross the ceiling you get a 429 with Retry-After: 60; back off and the window resets.
X-RateLimit-Limit: 120
X-RateLimit-Remaining: 118Usage is counted at the origin. Reads served by the edge cache never reach it and are free.
Usage counts origin hits only. Reads served by the edge cache are free and are never counted, so they do not touch your usage or your per-minute ceiling.
Read this before the numbers
The layer is honest by design. These five rules hold on every response; an agent that respects them will not be misled.
Figures carry confidence: 'high' | 'low' | 'unknown'. UNKNOWN MEANS THE SOURCE COULD NOT ANSWER, never treat it as zero. 'low' means measured but from thin data or a reported sampling cap.
Every brief and score ships a caveats[] array. Read it before the numbers; it states assumptions (e.g. in-extent roads presumed impassable) and sampling limits.
Responses with health.sourcesUsable < health.sourcesQueried are served uncached and incomplete by design. Retry later for a full read.
A null score means the system refused to invent a number. Do not impute.
Per-record license fields matter: ODbL-1.0 sources are share-alike; CDLA/CC0/public-domain are permissive. Keep them separable downstream.
Two ways in
Same tools, same contract, whichever door you pick. MCP and REST are two transports over one surface.
MCP
A Model Context Protocol server over streamable HTTP, stateless. Point an MCP-speaking agent at the endpoint and the earth_* tools appear.
{
"mcpServers": {
"solyzer-earth": {
"url": "https://api.solyzer.ai/mcp"
}
}
}REST
Plain HTTP for agents and code that do not speak MCP. No SDK, no signup, just a URL.
curl "https://api.solyzer.ai/earth/site-intel?\
lat=-6.2088&lon=106.8456&radius=500"The globe on your page
The same Digital Twin Earth, live, in one tag. Embedding on your own site takes a free publishable key, and a keyless frame renders only on solyzer.ai and on localhost while you build, so swap pk_earth_live_YOUR_KEY for your own. The key names your traffic and locks the frame to the domains you register. Source credit renders inside the frame and cannot be turned off.
Script tag
<!-- Solyzer Digital Twin Earth -->
<div
data-solyzer-earth
data-lat="-6.2088"
data-lon="106.8456"
data-zoom="9"
data-layers="quakes,disasters,cyclones"
data-key="pk_earth_live_YOUR_KEY"
data-height="520"
></div>
<script src="https://www.solyzer.ai/embed.js" async></script>Plain iframe
<iframe
src="https://www.solyzer.ai/embed/earth?lat=-6.2088&lon=106.8456&zoom=9&layers=quakes%2Cdisasters%2Ccyclones&k=pk_earth_live_YOUR_KEY"
title="Solyzer Digital Twin Earth"
width="100%"
height="520"
loading="lazy"
referrerpolicy="strict-origin-when-cross-origin"
allow="fullscreen"
sandbox="allow-scripts allow-same-origin allow-popups"
style="border:1px solid #26262a;border-radius:12px;display:block"
></iframe>The full surface
16 tools, rendered live from the manifest. Each MCP tool maps 1:1 to the REST path shown next to it.
| Method | Tool / Path | Params | Returns |
|---|---|---|---|
| GET | /earth/events | - | Active GDACS events with extent bboxes (posQuality: modeled-bbox), alert levels, provenance. |
| GET | /earth/event-briefup to 60s cold | id | Exposure/lifelines/condition/observation joins for one event; every figure has confidence; caveats[] first-class. First generation ~30s, then cached 30min. |
| GET | /earth/event-changes | - | New/escalated/deescalated/resolved events, newest first, plus history-subsystem status. |
| GET | /earth/site-intelup to 60s cold | lat, lon, radius, category | Explained site score: signed contributions, per-feature confidence, caveats, evidence geometry. score:null when too little is known. |
| GET | /earth/site-scan | bbox, category | Ranked grid cells with per-cell confidence and nearest-road distance. |
| GET | /earth/places | bbox | Overture places (CDLA-permissive) in the box, sampled. |
| GET | /earth/infrastructure | bbox | Communication + power structures (ODbL, surveyed positions). Coverage is very incomplete: absence is unknown, not zero. |
| GET | /earth/w/twin_earth | - | All live twin layers plus unavailable[] naming absent layers and why. |
| GET | /earth/place-trends | bbox | Map churn between the two newest archived snapshots: appeared/disappeared by id with named samples. Conflates real change with mapping activity, the caveat ships in-band. |
| GET | /earth/street-measure | lat, lon, maxM | Phase B geometry measured from street photos (metric depth × angular extent, no lidar): road width with method and spread, per-scene calibration verdict (detected vehicles measured against physical priors, scaleTrust ships in-band), and a georeferenced object inventory (label, distance, size, bearing, derived coordinates; heightIsLowerBound when the frame cut the object). measured:false = this ground has not been measured, which is not zero. |
| POST | /earth/sweep-request | lat, lon, radius | Queue a street sweep for unswept ground. A compute node reads the Mapillary street photos here into facts (roadway, kerbs, gates, signage, never imagery) and the area goes live in seen_layer when done (typically minutes to hours). Already-covered ground returns queued:false with the reason. The queue is public at GET /earth/sweep-queue. |
| GET | /earth/node-app | - | Download manifest for the Solyzer node agent: one small program (Windows/Linux, NVIDIA GPU required) that installs its own engine and joins the sovereign compute fleet. Each build carries a sha256 for verification; the sweep engine is compiled into the binary, so a running node never downloads or executes code. Contributed sweeps are validated and reviewed before they are served. |
| GET | /earth/seen | lat, lon, radius | Street-level facts a compute node swept from Mapillary photos (roadway, kerbs, gates, entrances, fences, poles, wires, signage, drainage, vegetation), georeferenced, each carrying value, confidence, source, timestamp and whether it was measured, modelled or assumed. covered:false = this ground has not been swept, which says NOTHING about what stands on it. Imagery is read in place and never rehosted. |
| GET | /earth/environment | lat, lon, radius | The fundamental fixed furniture of a place: mapped trees + tree rows, gates, communication towers, power structures and power lines. Mapped positions only (OSM ODbL + Overture archive); health{} names which source answered, and ABSENCE IS UNKNOWN, NOT ZERO, coverage is sparse. Heights are not in the data; renderers use class priors. |
| GET | /earth/road-geometry | lat, lon, radius | Road centerlines with the street-class width prior attached (ruasWidthM = one direction of carriageway, a MODEL not a measurement; two-way is typically ~2 ruas; null = class outside the model). The spatial boundary an agent can reason and measure against; the caveat ships in-band. |
| GET | /earth/fingerprint5-60s cold (multi-image VLM; may ride out one quota window), then cached 6h | lat, lon | Hudhud v0 environmental fingerprint: passable width, sidewalk, surface, obstacles, signage, lighting, overhead clearance and flood evidence, read by a VLM from nearby street photos with the scale anchors it used, cross-checked against the street-class width prior. Figures ship confidence + source; disagreements are disclosed, not averaged. |
No parameters.
Returns: Active GDACS events with extent bboxes (posQuality: modeled-bbox), alert levels, provenance.
idevent id, e.g. FL1102983Returns: Exposure/lifelines/condition/observation joins for one event; every figure has confidence; caveats[] first-class. First generation ~30s, then cached 30min.
No parameters.
Returns: New/escalated/deescalated/resolved events, newest first, plus history-subsystem status.
latdeglondegradiusm, 100-3000categoryoptional, e.g. cafe; enables saturation factorReturns: Explained site score: signed contributions, per-feature confidence, caveats, evidence geometry. score:null when too little is known.
bboxw,s,e,n (max 0.05 deg span)categoryoptionalReturns: Ranked grid cells with per-cell confidence and nearest-road distance.
bboxw,s,e,nReturns: Overture places (CDLA-permissive) in the box, sampled.
bboxw,s,e,nReturns: Communication + power structures (ODbL, surveyed positions). Coverage is very incomplete: absence is unknown, not zero.
No parameters.
Returns: All live twin layers plus unavailable[] naming absent layers and why.
bboxw,s,e,n (max 1 deg/side, Indonesia archive coverage)Returns: Map churn between the two newest archived snapshots: appeared/disappeared by id with named samples. Conflates real change with mapping activity, the caveat ships in-band.
latdeglondegmaxMartifact search radius, 50-400 (default 150)Returns: Phase B geometry measured from street photos (metric depth × angular extent, no lidar): road width with method and spread, per-scene calibration verdict (detected vehicles measured against physical priors, scaleTrust ships in-band), and a georeferenced object inventory (label, distance, size, bearing, derived coordinates; heightIsLowerBound when the frame cut the object). measured:false = this ground has not been measured, which is not zero.
latdeglondegradiusm, 200-1000 (default 450)Returns: Queue a street sweep for unswept ground. A compute node reads the Mapillary street photos here into facts (roadway, kerbs, gates, signage, never imagery) and the area goes live in seen_layer when done (typically minutes to hours). Already-covered ground returns queued:false with the reason. The queue is public at GET /earth/sweep-queue.
No parameters.
Returns: Download manifest for the Solyzer node agent: one small program (Windows/Linux, NVIDIA GPU required) that installs its own engine and joins the sovereign compute fleet. Each build carries a sha256 for verification; the sweep engine is compiled into the binary, so a running node never downloads or executes code. Contributed sweeps are validated and reviewed before they are served.
latdeglondegradiusm, 100-1500 (default 450)Returns: Street-level facts a compute node swept from Mapillary photos (roadway, kerbs, gates, entrances, fences, poles, wires, signage, drainage, vegetation), georeferenced, each carrying value, confidence, source, timestamp and whether it was measured, modelled or assumed. covered:false = this ground has not been swept, which says NOTHING about what stands on it. Imagery is read in place and never rehosted.
latdeglondegradiusm, 100-800 (default 400)Returns: The fundamental fixed furniture of a place: mapped trees + tree rows, gates, communication towers, power structures and power lines. Mapped positions only (OSM ODbL + Overture archive); health{} names which source answered, and ABSENCE IS UNKNOWN, NOT ZERO, coverage is sparse. Heights are not in the data; renderers use class priors.
latdeglondegradiusm, 100-1000 (default 400)Returns: Road centerlines with the street-class width prior attached (ruasWidthM = one direction of carriageway, a MODEL not a measurement; two-way is typically ~2 ruas; null = class outside the model). The spatial boundary an agent can reason and measure against; the caveat ships in-band.
latdeglondegReturns: Hudhud v0 environmental fingerprint: passable width, sidewalk, surface, obstacles, signage, lighting, overhead clearance and flood evidence, read by a VLM from nearby street photos with the scale anchors it used, cross-checked against the street-class width prior. Figures ship confidence + source; disagreements are disclosed, not averaged.
The authoritative, always-current list lives at https://api.solyzer.ai/earth/agent-tools.
One server, no ceremony
The MCP server speaks streamable HTTP and is stateless: every call stands alone, nothing to session, nothing to hold open. It exposes exactly the tools in the reference above; the REST paths and the earth_* tools are the same surface.
Claude Desktop, Cursor, and friends
Add this to your client's MCP config and the tools appear. No auth step: keys are optional here too, and the fair-use limits above apply the same way.
{
"mcpServers": {
"solyzer-earth": {
"url": "https://api.solyzer.ai/mcp"
}
}
}Raw protocol
Or speak the protocol directly: POST https://api.solyzer.ai/mcp with a JSON-RPC body. Because the server is stateless you can load balance, retry and cache without ever thinking about a session.
Keyless by default. Anonymous traffic: 120 req/min per IP. A free key (X-Api-Key or ?key=) raises it to 600 req/min and names your usage at GET /earth/usage. The contract lives at GET /earth/limits.