Off-Nadir Delta

MCP server

The Off-Nadir Delta MCP server lets an AI agent pull live, geolocated world event intelligence — query events, statistics, hotspots, and satellite scenes; read the Daily World Brief; and assess an event or ask an analyst. It is a stateless Streamable HTTP endpoint at /api/v1/mcp and works with any MCP-capable client.

Endpoint & transport

One Streamable HTTP (JSON-RPC 2.0) endpoint. No SSE, no session state.

text
https://offnadir-delta.com/api/v1/mcp

Authentication

Two ways to authenticate, in order of preference:

  1. OAuth 2.1 (recommended for interactive clients such as claude.ai remote connectors). The endpoint is an OAuth 2.1 resource server with discovery, dynamic client registration, and PKCE — compatible clients complete the flow automatically; you just log in and approve.
  2. Static API key (for CLIs, scripts, and servers). Pass your ond_… key as a bearer token. Create one in your Developer API settings.

Available on every plan, including Free — the only gate is your token balance. Each metered tool spends from the same monthly token allowance as the app (see each tool's cost below); get_world_brief and get_usage are free. When your balance runs out, calls return a clear error until it resets or you top up.

Client setup

Connecting from the Claude or ChatGPT apps? Those use the one-click OAuth flow (no API key to paste) — start with the two sections below. Wiring it into a CLI, editor, or script? Skip to Claude Code and use a static ond_… key. Everywhere, the endpoint is the same:

text
https://offnadir-delta.com/api/v1/mcp

Claude.ai & Claude Desktop (remote connector)

No API key needed — authentication is handled by OAuth. In claude.ai or Claude Desktop, open Settings → Connectors → Add custom connector, paste the endpoint URL above, then Connect and approve on the Off-Nadir Delta login screen. Claude registers itself automatically (dynamic client registration + PKCE) and completes the flow — you just log in and grant access. How many custom connectors you can add depends on your Claude plan (Anthropic documents the current limits); the connection then spends from your Off-Nadir Delta token balance, and you can revoke it anytime from Developer API settings.

ChatGPT (Developer Mode connector)

Also key-free via OAuth. In ChatGPT, enable Settings → Connectors → Advanced → Developer mode, then Add custom connector, paste the endpoint URL above, and complete the login on the Off-Nadir Delta approval screen. Developer Mode is not available on every ChatGPT plan — check whether yours exposes it. As with Claude, the connection is metered on your token balance and revocable from your Developer API settings.

Claude Code

bash
claude mcp add --transport http off-nadir-delta \
  https://offnadir-delta.com/api/v1/mcp \
  --header "Authorization: Bearer ond_..."

Claude Desktop & generic clients

Add to your mcpServers configuration:

json
{
  "mcpServers": {
    "off-nadir-delta": {
      "url": "https://offnadir-delta.com/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer ond_..."
      }
    }
  }
}

Cursor

One-click install, or add the same block to ~/.cursor/mcp.json manually. You complete OAuth (or add your ond_… key) on first use.

VS Code

One-click install, or add to .vscode/mcp.json manually (use the servers key with "type": "http" and the endpoint URL).

Python (programmatic)

python
from offnadir_delta import McpClient

with McpClient(api_key="ond_...") as mcp:
    mcp.initialize()
    print([t["name"] for t in mcp.list_tools()])
    result = mcp.call_tool("query_signals", {"bbox": [22, 44, 40, 53], "days": 7})

First call (free, no tokens)

Available on every plan including Free — the only gate is your token balance. Verify your key without spending anything: get_usage and get_world_brief cost zero tokens. This JSON-RPC call returns your remaining balance and plan capabilities:

bash
curl -s https://offnadir-delta.com/api/v1/mcp \
  -H "Authorization: Bearer ond_..." \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"get_usage","arguments":{}}}'

Then try get_world_brief (also free) for today's AI-synthesized world digest, and call get_usage again before any metered tool to confirm you have enough balance.

Tools

query_signalsMeteredQuery geolocated world event signals (Delta Signals: geopolitical, security, disaster, and infrastructure events distilled from global news media, AI-enriched with severity/GEOINT scores and satellite-collection recommendations).
query_statsMeteredAggregate statistics over the signal corpus — total event count plus per-category and per-day breakdown (trend) for a bounding box and date window.
query_hotspotsMeteredGeographic hotspots — signal density grid-binned into cells, ranked by event count, each with peak severity, the categories present, and up to 5 representative event_ids (trace a cell back to its signals).
get_world_briefFreeFetch the Daily World Brief — an AI-synthesized OSINT/GEOINT digest of the previous UTC day's worldwide event signals (headline, executive summary, top developments with why-it-matters and what-to-watch, per-theme roll-up, ranked signals).
get_usageFreeCheck the calling key's remaining token balance and plan capabilities — monthly allocation, tokens used this period, tokens remaining, and whether the plan includes AI tools over the API (assess_signal / ask_analyst).
search_imageryMeteredSearch the satellite imagery catalog (Sentinel-1, Sentinel-2, NISAR L-band) for scenes over an area and date window — the natural follow-up to a signal (find imagery over the event location).
plan_event_imageryMeteredPlan the imagery evidence for ONE event in a single call, instead of guessing collections one at a time.
rank_imaging_priorityMeteredWHERE — and with what class (and therefore cost) of satellite — is observation most worthwhile right now?
survey_observable_eventsMeteredWhich events in a window can a given in-app sensor actually RESOLVE?
predict_satellite_passesMeteredWHEN can this place next be imaged, and by WHAT — the timing half of collection planning.
assess_signalMeteredRun an AI RS (remote-sensing) deep-dive assessment for a specific signal: what to observe, recommended sensors, and a collection window.
ask_analystMeteredAsk the Delta Analyst an OSINT/GEOINT question.
get_analyst_jobFreeFetch the status and result of an ask_analyst run by job_id.
query_claimsFreeRead the LEDGER of claims this key has been given — every factual assertion the Analyst made, with its evidence class (CONFIRMED / REPORTED / PARTY_CLAIM / ASSESSMENT), how many INDEPENDENT source families backed it, and the publishers.
query_developmentsMeteredWhat actually CHANGED about the events in an area — not which articles are new.
get_event_threadFreeThe full history of ONE event: its current state, and every change in the order it happened.
create_standing_orderFreePut an area under CONTINUOUS watch: save a question plus a bounding box and Delta re-answers it on a schedule, notifying only when the answer actually changed.
list_layer_setsFreeList the layer sets saved on this account — the named map configurations a user builds in the app, each with how many layers it holds, its tags, when it was last changed and when it was last opened.
get_layer_setFreeRead one saved layer set by id: its name, description, layer count, size, tags and timestamps.
list_uploaded_layersFreeList the data this account uploaded to the map — name, format, size and when it was added — plus the formats the uploader actually accepts.
list_standing_ordersFreeList the standing orders on this key, with each one’s cadence, watched area, when it last checked, when it last actually fired, and how many consecutive checks found nothing (quiet_checks — a high number means the watch is not earning its place).
delete_standing_orderFreeDelete a standing order by id, or pause/resume it instead by passing active=false/true.
list_monitored_areasFreeList the places under continuous satellite measurement on this key (Delta Monitor), with each area’s metric, most recent value, change since the previous measurement, whether that value was flagged anomalous, and coverage — how many acquisitions were measured versus how many exist.
get_monitored_areaFreeFetch one monitored area with its full measurement history — every acquisition that was measured, its value, and whether it was flagged anomalous.
create_monitored_areaFreePut a place under continuous satellite measurement: pick an area and what to count, and every new Sentinel-1 / Sentinel-2 / VIIRS acquisition over it is measured automatically from then on.
lookup_elevationFreeMeasure terrain height from the Copernicus DEM GLO-30 — a point (lat + lon), an area (bbox), or a drawn polygon, for which the statistics are computed over the samples INSIDE the ring rather than its bounding box.
analyze_terrainFreeCompute FROM the terrain rather than reading heights out of it (that is lookup_elevation).
refine_locationMeteredResearch one signal's location further and, if the sources genuinely narrow it, store and return the better coordinate.
measure_index_seriesMeteredMeasure a spectral index over an area, scene by scene, back through the Sentinel-2 archive — the answer to "how has this changed since <year>".
detect_shipsMeteredCount vessel-like targets in ONE SAR scene over an area, using CFAR detection on Sentinel-1.

Every result carries a one-line natural-language summary you can relay as-is, and successful results include structuredContent (matching each tool's outputSchema) for clients that consume parsed output. query_signals and search_imagery default to a compact projection of each row — pass responseFormat: "detailed" to get every field.

Tool argument schemas

Every tool's arguments, types, constraints, and token cost — rendered from the live server definition. Required arguments are marked; everything else is optional.

query_signalsMetered · 3 tok

Query geolocated world event signals (Delta Signals: geopolitical, security, disaster, and infrastructure events distilled from global news media, AI-enriched with severity/GEOINT scores and satellite-collection recommendations). Filter by bounding box, date window, and category. Costs 3 token(s) per call, charged to the API key owner's balance.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]no4 itemsBounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide.
datestringnoWindow end date, YYYY-MM-DD (UTC). Defaults to today.
daysintegerno1…30Window length in days ending on `date`. Defaults to 1.
categoriesstring[]nokinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | otherRestrict to these categories. Omit for all.
marketsstring[]nooil | natural_gas | grain | shipping | defense | metals | semiconductors | fx | equitiesRestrict to signals AI-tagged as exposing these financial markets via a direct physical/supply channel (informational only, not investment advice). Omit for all.
limitintegerno1…500Maximum rows per page. Defaults to 100.
cursorstringnoOpaque pagination cursor from a previous response's meta.next_cursor.
minSeveritynumberno0…10Keep only signals with severity_score >= this (0-10).
escalatingbooleannoKeep only signals whose escalation_trend is "escalating".
sortstringnoseverity | recent | sources | geointResult ordering. Omit for the feed's default ranking. "geoint" ranks by the continuous GEOINT collection priority (intelligence.collection_priority) — an imageability gate times tasking value (severity, urgency, information gain, corroboration, escalation, market) — so imageable, decision-relevant events (e.g. a high-severity escalating strike) rise and non-observable news noise sinks. This is NOT the saturated geoint_score.
updatedSincestringnoDifferential fetch: only signals (re)enriched at/after this ISO 8601 timestamp. Ignores the date window. Response signals carry last_updated_at.
createdSincestringnoDifferential fetch: only signals first enriched at/after this ISO 8601 timestamp.
observabilitystringnoobservable | not-observableKeep only signals with this satellite observability — whether a physical mark is imageable at all (intelligence.satellite_observability).
observabilityStatusstringnoobservable | not_observable | insufficient_detail3-state observability filter. Unlike `observability` (binary), this exposes `insufficient_detail` — signals where imageability is unknown (no RS enrichment yet, unresolved location, or an Impossible verdict rescued because the event reads kinetic). `not_observable` = a considered "nothing to image"; neither bucket leaks insufficient_detail.
openDatastringnosufficient | commercial-recommended | not-applicableKeep only signals with this open-data sufficiency — free imagery is enough vs commercial tasking recommended (intelligence.open_data_sufficiency).
minInformationGainnumberno0…1Keep only signals whose intelligence.expected_information_gain >= this (0-1).
taskableOnlybooleannoKeep only signals whose coordinate is search_ready — GEO-READY ONLY: drops country centroids, ADM1 mismatches, reporting-dateline fallbacks and unresolved fixes (intelligence.geo_validation.search_ready). It does NOT imply observable or quality-passed, so not-observable / insufficient-detail / quality-failed signals can still appear. For automated imagery tasking use collectionReadyOnly (or combine with observability:"observable").
collectionReadyOnlybooleannoSTRICT tasking-candidate filter: search_ready AND observability=observable AND quality.status!=failed AND a concrete collection plan (rs_target + rs_reason present) AND an event coordinate. The safe input set for automated imagery tasking — a superset of every gate taskableOnly alone does not check.
responseFormatstringnoconcise | detailedPer-signal field detail. "concise" (default) returns the key decision + GEOINT fields (id, date, category, title, location, lat/lng, severity/geoint scores, collection_priority, escalation, market, rs_level/rs_sensor, observability, observability_status, verification_status, geo_status, search_ready, article_count, independent_source_count, information_gain) — cheaper to scan. "detailed" returns the full Signal object (shape per the signals://schema resource).

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
signalsobject[]yes
query_statsMetered · 1 tok

Aggregate statistics over the signal corpus — total event count plus per-category and per-day breakdown (trend) for a bounding box and date window. Cheaper than query_signals (returns roll-ups, not rows). NOTE the unit: `total` counts article-deduped events (meta.population = article_deduped_events), which is NOT cluster-collapsed, so it is >= the query_signals count for the same window. Costs 1 token(s) per call.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]no4 itemsBounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide.
datestringnoWindow end date, YYYY-MM-DD (UTC). Defaults to today.
daysintegerno1…30Window length in days. Defaults to 1.
categoriesstring[]nokinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | otherRestrict to these categories. Omit for all.

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
statsobjectyes
query_hotspotsMetered · 1 tok

Geographic hotspots — signal density grid-binned into cells, ranked by event count, each with peak severity, the categories present, and up to 5 representative event_ids (trace a cell back to its signals). Use to find WHERE activity is concentrating. NOTE the unit: cells count satellite-observable points (meta.population = rs_observable_points); meta reports source_point_count and dropped_by_geo_count / dropped_by_severity_count so point_count is fully accountable. Costs 1 token(s) per call.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]no4 itemsBounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide.
datestringnoWindow end date, YYYY-MM-DD (UTC). Defaults to today.
daysintegerno1…30Window length in days. Defaults to 1.
categoriesstring[]nokinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | otherRestrict to these categories. Omit for all.
precisionnumberno0.1…5Grid cell size in decimal degrees. Defaults to 1.
minSeveritynumberno0…10Keep only points with severity_score >= this.
limitintegerno1…500Max source points sampled before grid-binning — NOT the number of cells returned. Defaults to 500 (the max). Lower values sample fewer events and fragment clusters (each cell trends toward count 1), so leave at the default for a representative density map.

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
hotspotsobject[]yes
get_world_briefFree

Fetch the Daily World Brief — an AI-synthesized OSINT/GEOINT digest of the previous UTC day's worldwide event signals (headline, executive summary, top developments with why-it-matters and what-to-watch, per-theme roll-up, ranked signals). Free of token charges. The result includes a freshness object (brief_date, age_hours, is_stale) — if is_stale is true this is the latest published brief and a newer day is not yet available, so relay it as possibly out of date.

ParameterTypeReq.ConstraintsDescription
datestringnoBrief date, YYYY-MM-DD (UTC). Defaults to the latest available.

Result (structuredContent)

FieldTypeAlwaysDescription
briefobjectyes
freshnessobjectnoFreshness of the returned brief: brief_date, generated_at, age_hours, freshness (operational|delayed|degraded), is_stale, note.
get_usageFree

Check the calling key's remaining token balance and plan capabilities — monthly allocation, tokens used this period, tokens remaining, and whether the plan includes AI tools over the API (assess_signal / ask_analyst). Use this to pre-flight a metered call: decide whether enough balance is left before spending. Free of token charges.

No arguments.

Result (structuredContent)

FieldTypeAlwaysDescription
tokensobjectyes
planobjectyes
search_imageryMetered · 2 tok

Search the satellite imagery catalog (Sentinel-1, Sentinel-2, NISAR L-band) for scenes over an area and date window — the natural follow-up to a signal (find imagery over the event location). Returns scene metadata (id, datetime, footprint, cloud cover, platform, orbit geometry, coverage, catalog link) — no imagery bytes. Pass eventDate to classify each scene timing=pre/post/same_day_unknown (a same-day scene is same_day_unknown, never post, without a real event time) and get pre/post bracketing + window_status + SAR sar_pair_status in meta. Pass eventPoint [lon,lat] and/or eventAoi [minLon,minLat,maxLon,maxLat] to get each scene's target_relation (covers_event_geometry = pure geometry gate; usable_for_analysis additionally requires acceptable cloud for optical, so a 99%-cloud scene is geometry-covering but not analysis-usable) — so a scene that only clips the wide bbox is not mistaken for covering the event. Costs 2 token(s) per call.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]yes4 itemsBounding box [minLon, minLat, maxLon, maxLat] (WGS84). Required.
collectionstringnosentinel-1-grd | sentinel-1-rtc | sentinel-2-l2a | NISAR_L2_GCOV_PROVISIONAL_V1Catalog collection. Defaults to sentinel-2-l2a.
datestringnoWindow end date, YYYY-MM-DD (UTC). Defaults to today.
daysintegerno1…30Window length in days. Defaults to 7.
eventDatestringnoEvent date, YYYY-MM-DD (UTC). When set, each scene is tagged timing=pre/post/same_day_unknown and the search window is widened to the canonical pre/post span, so meta reports has_pre_baseline / has_post / bracketing_available / window_status; for sentinel-1-grd it also reports sar_pair_status (ready | not_ready | indeterminate_event_time) + orbit_note.
eventPointnumber[]no2 itemsEvent point [lon, lat] (WGS84). When set, each scene reports target_relation.covers_event_point / usable_for_event so a scene that only clips the wide bbox is not presented as covering the event.
eventAoinumber[]no4 itemsEvent AOI bbox [minLon, minLat, maxLon, maxLat] (WGS84). Drives target_relation.intersects_event_aoi / event_aoi_coverage_ratio.
eventTimestampstringnoFull event timestamp (ISO 8601) when known — promotes same-day scenes from same_day_unknown to pre/post by time.
cloudCoverMaxnumberno0…100Sentinel-2 only: max cloud cover %.
limitintegerno1…100Max scenes to return. Defaults to 25.
responseFormatstringnoconcise | detailedPer-scene field detail. "concise" (default) returns id, collection, datetime, timing, cloud_cover, platform, orbit_state, relative_orbit, instrument_mode, product_type, coverage_ratio, covers_event_point, usable_for_event, stac_item_url, preview. "detailed" adds the full footprint bbox/geometry, the complete target_relation, constellation, polarizations, absolute_orbit, incidence_angle, and non-signed asset hrefs.

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
scenesobject[]yes
plan_event_imageryMetered · 4 tok

Plan the imagery evidence for ONE event in a single call, instead of guessing collections one at a time. Give the event_id and what you are trying to establish (damage_assessment | flood_mapping | wildfire_assessment) and the SERVER runs the deterministic plan for that goal: it always checks BOTH in-app sensors — sentinel-1-grd (SAR: all-weather, the only look that survives cloud and night) and sentinel-2-l2a (optical, human-legible) — exactly once each, against the event’s own footprint and a pre/post window around its date. The result carries, per search, why it was made, how many scenes came back, how many actually COVER the event and are usable (cloud-obscured optical does not count), the SAR pair status, and whether a pre/post bracket exists. It also states screening / detection / identification capability: Sentinel-1/2 screen and detect at facility scale, and only object-level identification needs commercial VHR — a VHR recommendation NEVER invalidates what the free catalog already showed. Prefer this over several search_imagery calls for the same event: it cannot miss the SAR look and cannot repeat a search. An event with no resolvable footprint is refused rather than planned against a guess. Costs 4 token(s) per call (it deliberately issues two catalog searches).

ParameterTypeReq.ConstraintsDescription
event_idintegeryesThe `id` from query_signals. The server resolves its authoritative point + AOI.
analysis_goalstringyesdamage_assessment | flood_mapping | wildfire_assessmentWhat the imagery must establish — decides which collection leads and how cloud is gated.
event_datestringnoEvent date YYYY-MM-DD. Optional — the event row supplies it when known.

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
planobjectyes
rank_imaging_priorityMetered · 1 tok

WHERE — and with what class (and therefore cost) of satellite — is observation most worthwhile right now? Crosses each event’s composite IMPORTANCE (severity × source breadth × market relevance) with the SPEC CLASS its required resolution demands: coarse (≤100 m), hr (≤10 m, Sentinel-class free data) or vhr (sub-metre, commercial tasking). Returns how many imageable events fall in each class with their mean importance, plus the top targets with importance, required class and AOI. Use it to triage a theatre before spending on imagery: a high-importance event that only needs hr is answerable with free Sentinel data, while a vhr one is what a paid order is for. Deterministic — no LLM, no per-event cost. Costs 1 token(s) per call.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]no4 itemsArea [west, south, east, north] in WGS84. Omit for a global survey.
start_datestringnoInclusive start date YYYY-MM-DD. Defaults to today; clamped to your plan history floor.
end_datestringnoInclusive end date YYYY-MM-DD. Defaults to today. The window is capped at 30 days.
categoriesstring[]noRestrict to these Delta categories (kinetic, armed_conflict, maritime, natural_disaster, infrastructure, aviation, humanitarian, protest, diplomacy).
min_geoint_scorenumbernoDrop events below this GEOINT score before ranking.
top_nnumberno1…50How many top targets to return (default 12).

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
priorityobjectyes
survey_observable_eventsMetered · 1 tok

Which events in a window can a given in-app sensor actually RESOLVE? Evaluates the FULL set (not just the top few) against each event’s precomputed required resolution, and returns how many are observable vs not, the breakdown by required resolution, and the top observable events with the ready-made imaging rationale. Observability here is resolvability — whether the physical mark is large enough for the sensor: Sentinel-2 is ~10 m optical (needs daylight and clear sky), Sentinel-1 is SAR (all-weather, day or night). Prefer this over asking about events one at a time: it is exhaustive AND cheap, and it is the honest way to answer "what can we actually see" before committing collection effort. The population is deliberately UNGATED by tasking readiness — it answers "what could this sensor resolve", not "what may we task" — so its total sits above rank_imaging_priority and counts a different unit from query_signals' clusters; see population_detail, and read collection_ready per event for taskability. Deterministic — no LLM. Costs 1 token(s) per call.

ParameterTypeReq.ConstraintsDescription
sensorstringnosentinel-2 | sentinel-1Which in-app sensor to evaluate against. sentinel-2 = ~10 m optical (daylight, clear sky); sentinel-1 = SAR (all-weather, day/night). Default sentinel-2.
bboxnumber[]no4 itemsArea [west, south, east, north] in WGS84. Omit for a global survey.
start_datestringnoInclusive start date YYYY-MM-DD. Defaults to today; clamped to your plan history floor.
end_datestringnoInclusive end date YYYY-MM-DD. Defaults to today. The window is capped at 30 days.
categoriesstring[]noRestrict to these Delta categories.
min_geoint_scorenumbernoDrop events below this GEOINT score before surveying.
top_nnumberno1…50How many observable events to return (default 20).

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
surveyobjectyes
predict_satellite_passesMetered · 2 tok

WHEN can this place next be imaged, and by WHAT — the timing half of collection planning. Propagates current orbital elements (SGP4 over day-cached CelesTrak two-line elements) for seven families and returns the access windows over a target: Sentinel-1 (SAR), Sentinel-2 and Landsat (free, SYSTEMATIC — routinely collected, so near-certain), plus WorldView, ICEYE, Capella and SkySat (commercial, AGILE — taskable ACCESS opportunities that require a paid order and are NOT guaranteed collects). Each pass carries acquisition/loss times, the closest-approach instant, peak elevation, OFF-NADIR angle, ground distance, ascending/descending, solar elevation and whether the target is sunlit (optical needs light; SAR does not), and the age of the element set it was computed from. Use it to answer "when is the next chance to see this", to choose between waiting for a free systematic pass and paying to task an agile one, and to time a pre/post change-detection pair. Give lat/lon, or a bbox whose centre is used. Horizon is capped at 7 days. If elements cannot be retrieved the result says so (retrieval_ok:false) — that means timing is UNAVAILABLE, never "no passes". Every pass is a GEOMETRIC access opportunity computed from orbital elements and swath width (geometry_only:true, acquisition_plan_verified:false): no operator collection plan is consulted, so this is when a sensor COULD see the target, never a confirmed acquisition schedule. With no start_date the window begins NOW, so the first pass listed is always still ahead. Costs 2 token(s) per call.

ParameterTypeReq.ConstraintsDescription
latnumberno-90…90Target latitude (-90..90; positive = North). Required unless bbox is given.
lonnumberno-180…180Target longitude (-180..180; positive = East). Required unless bbox is given.
bboxnumber[]no4 itemsArea [west, south, east, north] in WGS84. The CENTRE is used as the target when lat/lon are omitted.
start_datestringnoInclusive start date YYYY-MM-DD (UTC). Defaults to today.
end_datestringnoInclusive end date YYYY-MM-DD (UTC). Defaults to start+2 days; the window is capped to a 7-day horizon.
satellitesstring[]nosentinel-1 | sentinel-2 | landsat | worldview | iceye | capella | skysatFamilies to consider. Omit for all seven. Use this to compare "free systematic only" against "what could I task".
max_passesnumberno1…100Maximum passes to return, soonest first (default 40).

Result (structuredContent)

FieldTypeAlwaysDescription
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
passesobject[]yes
freshnessobjectno
assess_signalMetered · 5/15 tok

Run an AI RS (remote-sensing) deep-dive assessment for a specific signal: what to observe, recommended sensors, and a collection window. `eventId` is the `id` from query_signals. The result also carries a deterministic `context` block (event id/date, normalized target, AOI bbox, observability + quality verdict, and an `imagery_handoff` giving the exact bbox + event_date to pass to search_imagery for REAL pre/post scene candidates) — turning the assessment into an actionable collection plan. Costs 5 (quick) or 15 (deep) tokens, charged to the key owner's balance. A prior assessment for the same signal is cached (no re-charge). The exact charge and remaining balance are in the result meta.tokens. Signals that are not satellite-observable (observability:"not-observable" — e.g. political statements or broad-area events with no imageable physical mark) are rejected BEFORE any charge, so pre-filter with query_signals observability:"observable" to spend only where imagery helps.

ParameterTypeReq.ConstraintsDescription
eventIdintegeryesSignal id (global_event_id) from query_signals.
kindstringnoquick | deepAssessment depth. Defaults to quick.

Result (structuredContent)

FieldTypeAlwaysDescription
kindstringyes
cachedbooleanno
modelstringno
contentobjectyes
metaobjectyesQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
ask_analystMetered · 5–123 tok

Ask the Delta Analyst an OSINT/GEOINT question. Runs an agentic multi-step analysis over the signal corpus and returns a structured brief (summary, findings with collection recommendations, assessment, citations). Costs 5–123 tokens (usage-based, metered by the compute the question actually uses; charged ONCE, when the run completes; the exact charge and remaining balance are in the result meta.tokens). Durable async: the run is ENQUEUED and returns {status:"processing", job_id} immediately, then completes in a background worker — so it is never lost to a client timeout. Timing: most questions finish in ~30–90s; a complex brief (satellite-imagery lookups or many sources) can take 2–3 minutes. Fetch the finished brief by calling get_analyst_job with the job_id (poll every ~10–20s), or ask_analyst again with the SAME idempotencyKey (no second charge).

ParameterTypeReq.ConstraintsDescription
questionstringyesThe analytic question (≤ 500 chars).
bboxnumber[]no4 itemsOptional focus bounding box [minLon, minLat, maxLon, maxLat] (WGS84).
modestringnofast | deepfast (default) or deep. Deep enables extended reasoning and wider evidence-gathering budgets — for forecasting, collection trade-offs and market-implication questions where step-by-step reasoning materially helps. It is slower and the ceiling rises from 123 to 415 tokens; charging stays metered by what the run actually consumes, so a light deep question does not cost the ceiling.
idempotencyKeystringnoOptional at-most-once key. Re-sending the SAME key resolves to the SAME run: if it finished you get the brief with NO second charge; if it is still running you get its processing status. Strongly recommended — it makes a timeout recoverable. Use a fresh key to ask again.
response_formatstringnofull | compact"full" (default) returns the prose brief alongside the structured result. "compact" omits the prose brief and returns only the structured result — which still carries the assembled structured_summary — so a completed run costs materially fewer context tokens.

Result (structuredContent)

FieldTypeAlwaysDescription
briefobjectno
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
statusstringno"processing" when the run is still going (poll get_analyst_job or re-send the same idempotencyKey).
job_idstringnoId of the analyst run — pass to get_analyst_job (also at GET /api/v1/analyst/{job_id}).
progressobjectnoPipeline progress while the job is processing. completed_steps reaches total_steps ONLY when status is "done".
estimated_chargeobjectnoThe charge ceiling quoted for THIS run, fixed at enqueue (統合改善指示書 P1-1). The completed run reports the actual charge in meta.tokens.charged and echoes this ceiling as meta.tokens.maximum_promised; actual never exceeds it.
messagestringno
get_analyst_jobFree

Fetch the status and result of an ask_analyst run by job_id. Job status is ONLY "processing" (still running — poll again in ~10-20s), "done" (with the finished brief and meta.tokens), or "error". When done, result_quality.status ("complete" | "partial", with any issues[]) reports whether the structured output is fully populated — this is SEPARATE from the job status (a done job can carry a partial result). Free of token charges — the run itself is charged once on completion. A job is visible only to the API key owner that created it.

ParameterTypeReq.ConstraintsDescription
job_idstringyesThe job_id returned by ask_analyst.
response_formatstringnofull | compact"full" (default) returns the prose brief alongside the structured result. "compact" omits the prose brief and returns only the structured result — which still carries the assembled structured_summary — so a re-fetch costs materially fewer context tokens.

Result (structuredContent)

FieldTypeAlwaysDescription
job_idstringno
statusstringno"processing" | "done" | "error".
progressobjectnoPipeline progress while the job is processing. completed_steps reaches total_steps ONLY when status is "done".
briefobjectno
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
errorstringnoFailure reason when status is "error".
messagestringno
created_atstringno
updated_atstringno
query_claimsFree

Read the LEDGER of claims this key has been given — every factual assertion the Analyst made, with its evidence class (CONFIRMED / REPORTED / PARTY_CLAIM / ASSESSMENT), how many INDEPENDENT source families backed it, and the publishers. The point is the time axis: when a later answer restated the same assertion, the claim carries the link and says which way the evidence moved — restated_only surfaces those chains, and downgraded_only isolates the cases where a later answer was LESS sure than an earlier one, which is where this product contradicted itself. Use it to audit what you were told before acting on it, or to check whether an assertion has since weakened. Scoped to your own key; no other caller’s claims are visible. Free of token charges.

ParameterTypeReq.ConstraintsDescription
sincestringnoOnly claims asserted on or after this date (YYYY-MM-DD or ISO 8601).
evidence_classstringnoCONFIRMED | REPORTED | PARTY_CLAIM | DISPUTED | ASSESSMENT | UNKNOWNRestrict to one evidence class.
restated_onlybooleannoOnly claims that sit in a restatement chain.
downgraded_onlybooleannoOnly claims a later answer restated with WEAKER evidence — read these first.
limitnumberno1…200How many claims to return (default 50).

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
claimsobject[]yes
countsobjectno
query_developmentsMetered · 3 tok

What actually CHANGED about the events in an area — not which articles are new. Polling query_signals and diffing the ids finds new REPORTING: a 2025 attack re-reported in 2026 with a fresh attribution is indistinguishable from a fresh attack. This returns changes as changes, each with what it was and what it became. Two kinds, labelled: `world` = the event's own state moved (a death toll revised, a perpetrator named, a report disputed); `measurement` = what WE can now see moved (a location resolved, post-event imagery arrived, a SAR before/after pair became ready). This is the right source for "what is new since last time" and for a standing watch. By default only changes worth a person's attention are returned — set notable_only=false for the full ledger, including changes deliberately judged too minor to notify on.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]no4 items[minLon, minLat, maxLon, maxLat]. Omit for worldwide.
datestringnoEnd of the window (YYYY-MM-DD). Defaults to today.
daysnumberno1…30Window length ending at `date` (default 7).
categoriesstring[]noRestrict to these signal categories.
development_typesstring[]nonew_event | baseline | occurrence_time_established | casualty_count_first_reported | casualty_count_raised | casualty_count_corrected | casualties_disputed | attribution_stated | attribution_changed | attribution_disputed | corroboration_increased | severity_escalated | location_resolved | observability_established | collection_ready | imagery_available | sar_pair_ready | observed | confirmed | reporting_disputed | retractedRestrict to these kinds of change. An unknown value is an error, never an empty result.
notable_onlybooleannoDefault true. False returns every recorded change, including minor ones.
limitnumberno1…200How many developments to return (default 50).

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
developmentsobject[]yes
get_event_threadFree

The full history of ONE event: its current state, and every change in the order it happened. Answers "is this a new event or an update to an old one" — the distinction a news feed cannot make. Returns the canonical event (where, when it HAPPENED as distinct from when it was reported, casualties, attribution and how that attribution is grounded), a timeline of developments, and every source article behind it. `occurred_at_basis` says whether the occurrence time was stated, absent, or never measured — those are three different things. `history_incomplete` marks an event that already existed when tracking began. Free of token charges: the discovery call that found the event was already metered.

ParameterTypeReq.ConstraintsDescription
event_idnumberyesAny signal id belonging to the event; the whole canonical event is returned.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
canonical_eventobjectyes
timelineobject[]yes
sourcesobject[]no
create_standing_orderFree

Put an area under CONTINUOUS watch: save a question plus a bounding box and Delta re-answers it on a schedule, notifying only when the answer actually changed. Creating one is FREE. Each time it fires it runs ask_analyst and is metered like any Analyst question, so the cost is per CHANGE, not per check: a deterministic pass over the corpus decides whether anything new crossed the reporting bar, and quiet periods never invoke the model or charge anything. Returns projected_monthly_tokens_typical (the observed median cost per run × this cadence) and projected_monthly_tokens_max (the true ceiling: every check fires AND every run reaches the per-question cap), so the cost is visible before committing. Cadence and how many orders you may hold are set by your plan; the error says which limit you hit. Use it when the question is "tell me when this changes" rather than "what is happening right now".

ParameterTypeReq.ConstraintsDescription
bboxnumber[]yes4 itemsArea to watch, [west, south, east, north] in WGS84. Required — a global standing order would fire on everything.
questionstringnoThe question to re-answer each time something changes. Omit for "what changed in this area, and what does it mean?".
namestringnoLabel for the order (default "Standing order").
cadencestringnodaily | weekly | monthlyHow often to CHECK (checking is free; only a fired check costs tokens). Default weekly. Faster cadences may require a higher plan.
categoriesstring[]noRestrict the watch to these Delta categories (kinetic, armed_conflict, maritime, natural_disaster, infrastructure, aviation, humanitarian, protest, diplomacy).
min_geoint_scorenumbernoReporting bar (0-10, default 6). Raise it to be told only about major developments.
min_new_eventsnumbernoHow many new qualifying events must appear before a run is triggered (default 1).
notify_emailbooleannoEmail the result when it fires (default true). Results are readable via list_standing_orders either way.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
orderobjectyes
projected_monthly_tokens_typicalnumberno
projected_monthly_tokens_maxnumberno
list_layer_setsFree

List the layer sets saved on this account — the named map configurations a user builds in the app, each with how many layers it holds, its tags, when it was last changed and when it was last opened. Use it to answer "what have I saved" and to tell an idle configuration from a working one. The layer tree itself is not returned: it is an internal format, and opening it is the map’s job. Free of token charges.

ParameterTypeReq.ConstraintsDescription
limitintegerno1…100Max layer sets to return (default 50).

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
layer_setsobject[]yes
totalintegerno
get_layer_setFree

Read one saved layer set by id: its name, description, layer count, size, tags and timestamps. The serialized layer tree is deliberately not exposed (contents:"not_exposed") — it is an internal representation, not a public contract. Free of token charges.

ParameterTypeReq.ConstraintsDescription
layer_set_idstringyesThe layer set id.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
layer_setobjectyes
list_uploaded_layersFree

List the data this account uploaded to the map — name, format, size and when it was added — plus the formats the uploader actually accepts. Uploading itself happens in the app (it is a file transfer, not a JSON call), so use this to see what is already there and to answer format questions correctly: GeoJSON and GeoTIFF are accepted, a shapefile or KML is not. Free of token charges.

ParameterTypeReq.ConstraintsDescription
limitintegerno1…100Max uploads to return (default 50).

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
uploadsobject[]yes
totalintegerno
accepted_formatsstring[]no
list_standing_ordersFree

List the standing orders on this key, with each one’s cadence, watched area, when it last checked, when it last actually fired, and how many consecutive checks found nothing (quiet_checks — a high number means the watch is not earning its place). Also returns how many orders the plan allows and how many remain. Free of token charges.

No arguments.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
ordersobject[]yes
limitsobjectno
delete_standing_orderFree

Delete a standing order by id, or pause/resume it instead by passing active=false/true. Pausing keeps the order and its history; deleting removes both. Neither costs tokens. A paused order still counts against the plan limit, so delete rather than pause when you want the slot back.

ParameterTypeReq.ConstraintsDescription
order_idstringyesThe id returned by create_standing_order or list_standing_orders.
activebooleannoOmit to DELETE. Pass false to pause and true to resume, keeping the order.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
deletedstringno
orderobjectno
list_monitored_areasFree

List the places under continuous satellite measurement on this key (Delta Monitor), with each area’s metric, most recent value, change since the previous measurement, whether that value was flagged anomalous, and coverage — how many acquisitions were measured versus how many exist. Coverage window_total is null when the catalog total is UNKNOWN; null never means zero. Also returns how many areas the plan allows and how many remain. Free of token charges.

No arguments.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
areasobject[]yes
limitsobjectno
meteringobjectno
get_monitored_areaFree

Fetch one monitored area with its full measurement history — every acquisition that was measured, its value, and whether it was flagged anomalous. This is the time series behind the number that list_monitored_areas reports, so use it to answer "is it going up", "when did it change", or "how unusual is today". Anomaly flags come from a median-absolute-deviation test on the series, not a fixed threshold. Free of token charges; returning the full history requires a plan that includes data export, so it can be refused with a forbidden error.

ParameterTypeReq.ConstraintsDescription
area_idstringyesThe area_id from list_monitored_areas. A metric’s polygon_id is also accepted and resolves to the same area.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
areaobjectyes
meteringobjectno
create_monitored_areaFree

Put a place under continuous satellite measurement: pick an area and what to count, and every new Sentinel-1 / Sentinel-2 / VIIRS acquisition over it is measured automatically from then on. Use this when the question is about a quantity at a fixed place over time ("how many ships are alongside", "how much has burned", "is the water receding") rather than about events, which is create_standing_order. Creating is free; each automatic check costs a small number of tokens only when it finds new imagery.

ParameterTypeReq.ConstraintsDescription
bboxnumber[]yes4 itemsThe area to measure, [west, south, east, north] in WGS84. Must be under 5,000 km² — measurement is per-pixel over the area, so a country-sized box is rejected rather than silently sampled.
metricstringyesWhat to count. Plain words work: ships, fires, vegetation, water, burn, snow, built_up, moisture, night_lights. Index names are also accepted: ship_detection, fire_count, ndvi, evi, savi, ndmi, ndwi, mndwi, ndbi, ndsi, nbr, dnb, vv, vh, rvi, rfdi, cr. The sensor is chosen from the metric.
namestringnoLabel for the area (default "Monitored area").
start_datestringnoYYYY-MM-DD to begin the history from. Defaults to 30 days ago — a longer backfill measures more scenes and therefore costs more on the first check.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
areaobjectyes
meteringobjectno
lookup_elevationFree

Measure terrain height from the Copernicus DEM GLO-30 — a point (lat + lon), an area (bbox), or a drawn polygon, for which the statistics are computed over the samples INSIDE the ring rather than its bounding box. Returns min, max, mean, median, p10, p90 and relief (max − min), the number that governs SAR layover and shadow severity. Free of token charges. Three things the result carries that any answer must respect: it is a SURFACE model (buildings and tree canopy included, so not bare ground); `downsampled: true` means a large area was read below the 30 m posting, so min/max are smoothed inward and the relief is a floor rather than an exact figure; and `covered: false` or `tiles_missing > 0` means open ocean where the model has no data — which is absence, not 0 m. Heights are orthometric on the EGM2008 geoid, not ellipsoidal. Cite the returned `attribution` wherever a height is shown.

ParameterTypeReq.ConstraintsDescription
latnumberno-90…90Latitude of a single point to measure (use with lon).
lonnumberno-180…180Longitude of a single point to measure (use with lat).
bboxnumber[]no4 itemsArea to measure as [lon_min, lat_min, lon_max, lat_max] (WGS84).
polygonarray[]no3–∞ itemsWGS84 ring [[lon, lat], …]. Statistics cover only the samples inside it.

Result (structuredContent)

FieldTypeAlwaysDescription
modestringnoWhich form was measured: 'point', 'bbox' or 'polygon'.
elevationobjectyes
attributionstringnoRequired Copernicus DEM credit (licence Article 6(b)).
analyze_terrainFree

Compute FROM the terrain rather than reading heights out of it (that is lookup_elevation). Free of token charges; both operations come from one Copernicus DEM GLO-30 read. `operation: 'sar_geometry'` over a bbox, with an incidence angle and a look azimuth, returns the share of the area lost to LAYOVER and to SHADOW, the share merely foreshortened, and the mean LOCAL incidence angle — the arithmetic behind whether radar can use that ground. It changes with the pass direction (measured on one volcanic flank: 2.6% layover looking west against 0.7% looking east at the same 35°), so the geometry is required rather than assumed. `operation: 'profile'` between two points returns the ground along the line and a LINE-OF-SIGHT verdict including Earth curvature: whether the ends can see each other, where the terrain first rises above the sight line, and the worst clearance. Both results state the sample spacing they were computed at — a coarser grid reads flatter, and therefore more observable, than the ground is. A SURFACE model, so canopy and buildings are included; over a surface model they block a sight line as they would in reality. Cite the returned `attribution`.

ParameterTypeReq.ConstraintsDescription
operationstringyessar_geometry | profile'sar_geometry' = layover/shadow over an area; 'profile' = ground along a line plus a line-of-sight verdict.
bboxnumber[]no4 itemsFor 'sar_geometry': area as [lon_min, lat_min, lon_max, lat_max] (WGS84).
incidence_degnumberno10…80For 'sar_geometry': sensor incidence angle. Sentinel-1 IW spans roughly 29-46 degrees; use the scene's own value when you have it.
look_azimuth_degnumberno0…360For 'sar_geometry': compass bearing the sensor looks along the ground range. A right-looking descending pass looks roughly west (270).
latnumberno-90…90For 'profile': latitude of the observer end.
lonnumberno-180…180For 'profile': longitude of the observer end.
to_latnumberno-90…90For 'profile': latitude of the far end.
to_lonnumberno-180…180For 'profile': longitude of the far end.
observer_height_mnumberno0…∞For 'profile': eye height above the ground, default 2 m. Use the real mast or tower height when that is the question.

Result (structuredContent)

FieldTypeAlwaysDescription
operationstringno
sar_geometryobjectno
profileobjectno
attributionstringnoRequired Copernicus DEM credit (licence Article 6(b)).
refine_locationMetered · 3–29 tok

Research one signal's location further and, if the sources genuinely narrow it, store and return the better coordinate. Most signals are geolocated once, for free, from a single article's place string: measured across production, about two thirds sit at ±5 km or have no bounded radius at all. This reads the source article and live search for a source that names something finer — a facility, bridge, district, port — resolves it, and verifies it before accepting it. **You are charged only if the precision actually improves**, between 3 and 29 tokens by what the run consumed; a signal that cannot be narrowed costs nothing, and a signal an earlier caller already refined is returned free. Read the result honestly: `improved: false` with a `reason` is the common and correct outcome when no source is more specific — it does NOT mean the event is unlocated, and it is not a failure to retry. When it does improve, `evidence` lists the sources that named the place; a location without evidence is never stored, so do not present a refined point without citing them. `footprint_kind` says whether the answer is a POINT or an AREA — if it is an area, describe an area, because an admin-level place has no finite radius and drawing it as a dot misstates where the event was. `uncertainty_m: null` means unbounded, not unknown.

ParameterTypeReq.ConstraintsDescription
signal_idintegeryesThe signal (global_event_id) whose location should be researched further.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
resultobjectno
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
measure_index_seriesMetered · 0.5 tok

Measure a spectral index over an area, scene by scene, back through the Sentinel-2 archive — the answer to "how has this changed since <year>". Give a polygon (or a bbox), an index (ndvi, evi, savi, ndmi, ndwi, mndwi, ndbi, ndsi, nbr, iron-oxide, clay, ferrous) and a date range; each scene is measured over the samples INSIDE the ring, and the result is the per-scene mean/median/min/max with a first-to-last change. Costs 0.5 tokens per scene actually measured; a scene that fails to read is reported in `skipped` and is not charged. **Call it once with `estimate_only: true` first** — that is free and returns how many scenes match, the real date span available, and what measuring them would cost, so the user can agree to the spend. Three things the result carries that any answer must respect: the Sentinel-2 archive begins 2015-06-27, so an earlier start is clamped and `clamped_to_archive` says so (those years are genuinely unavailable, not empty); at most 24 scenes are measured per call, so a longer period comes back as a SAMPLE and the rest appear in `skipped`; and `trend` compares the first and last measured scene only — it is not a fitted rate, so do not attach a slope or a confidence to it. `scenes_found` is what the catalog holds; `scenes_examined` is the newest page this call read, so `candidate_date_span` is the edge of that page and NOT how far the archive reaches — read `notes` before saying when coverage begins. For a SAR quantity, or to keep measuring as new imagery arrives, use create_monitored_area instead. Cite the returned `attribution`.

ParameterTypeReq.ConstraintsDescription
polygonarray[]noWGS84 ring [[lon, lat], …] with at least 3 vertices. Statistics cover the samples inside it.
bboxnumber[]no4 itemsAlternative to polygon: [lon_min, lat_min, lon_max, lat_max] (WGS84).
indexstringyesndvi | evi | savi | ndmi | ndwi | mndwi | ndbi | ndsi | nbr | iron-oxide | clay | ferrousWhich optical index to measure.
startstringyesStart date YYYY-MM-DD (UTC). Clamped forward to 2015-06-27 if earlier.
endstringyesEnd date YYYY-MM-DD (UTC).
max_scenesintegerno1…24Cap on scenes measured in this call. Server maximum 24.
max_cloud_covernumberno1…100Scene cloud-cover ceiling in percent. Default 30.
estimate_onlybooleannoTrue = free: return the scene count, date span and token cost WITHOUT measuring or charging.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
estimateobjectno
seriesobjectno
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.
attributionstringno
detect_shipsMetered · 5 tok

Count vessel-like targets in ONE SAR scene over an area, using CFAR detection on Sentinel-1. Costs 5 tokens per detection; a scene the worker refuses (an unsupported combination, an area with no usable sea) is not charged. The natural sequence is search_imagery over the area, pick a scene, then this with its `collection` and `item_id` — radar sees through cloud and at night, so the count works when optical would not. Read `caveats` before reporting the number: it states when the land mask was unavailable (shoreline structures may be counted as vessels), how far from the coast detections were excluded (the default excludes vessels alongside a quay), and when the scene covers only part of the requested area — a partial-coverage count must never be compared with a full one as though the difference were vessels. This measures one scene at one time. To track a berth or an anchorage over time, create_monitored_area with metric `ships` measures every new acquisition.

ParameterTypeReq.ConstraintsDescription
collectionstringyessentinel-1-grd | sentinel-1-rtcCatalog collection of the scene. NISAR detection is available in the app only (it needs a granule conversion first).
item_idstringyesSTAC item id of the scene, as returned by search_imagery.
bboxnumber[]no4 itemsArea to search within the scene, [lon_min, lat_min, lon_max, lat_max] (WGS84).
geometryobjectno
algorithm_versionstringnoauto | v2 | v3Detector version. 'auto' (default) picks the recommended version for the sensor.

Result (structuredContent)

FieldTypeAlwaysDescription
summarystringnoOne-line natural-language summary of the result, ready to relay to a user.
countintegernoVessel-like targets detected. Read `caveats` before quoting it.
shipsobjectno
caveatsstring[]no
sceneobjectno
processingobjectno
metaobjectnoQuery echo, token charge/balance (meta.tokens), and pagination where applicable.

REST ↔ MCP parameters

The MCP tools mirror the REST API — same filters, same token costs. The only difference is naming: REST uses snake_case query params, MCP uses camelCase arguments, and a bounding box is a comma-string in REST but a 4-number array in MCP.

REST (query param)MCP (argument)
areaIdarea_id
cloud_cover_maxcloudCoverMax
collection_ready_onlycollectionReadyOnly
created_sincecreatedSince
event_aoieventAoi
event_dateeventDate
event_pointeventPoint
event_timestampeventTimestamp
eventIdevent_id
idsignal_id
Idempotency-KeyidempotencyKey
jobIdjob_id
layerSetIdlayer_set_id
min_information_gainminInformationGain
min_severityminSeverity
observability_statusobservabilityStatus
open_dataopenData
orderIdorder_id
taskable_onlytaskableOnly
updated_sinceupdatedSince
bbox (comma string)bbox (number[4])

Example response

query_signals (concise projection). Full field definitions are in the signals://schema resource.

json
{
  "meta": {
    "start_date": "2026-07-08",
    "end_date": "2026-07-15",
    "count": 42,
    "next_cursor": "b2Zmc2V0OjEwMA",
    "has_more": true,
    "tokens": { "charged": 3, "remaining": 1997 }
  },
  "summary": "42 signals — armed conflict concentrated near the Black Sea, plus flooding in South Asia.",
  "signals": [
    {
      "id": 1313532800,
      "event_date": "2026-07-15",
      "category": "armed_conflict",
      "title": "Strike reported near the Odesa port",
      "location": "Odesa, Ukraine",
      "lat": 46.48, "lng": 30.72,
      "severity_score": 7.8,
      "geoint_score": 6.4,
      "escalation_trend": "escalating",
      "market": "shipping",
      "rs_level": "regional",
      "rs_sensor": "sentinel-1-sar",
      "satellite_observability": "observable",
      "expected_information_gain": 0.72,
      "geo_verified": true
    }
  ]
}

Resources

brief://latestThe most recent AI-synthesized Daily World Brief (JSON). Free.
signals://schemaJSON Schema of the public Signal shape returned by query_signals / /api/v1/signals.
usage://currentRemaining token balance and plan capabilities for the calling key. Free.
imagery://collectionsThe satellite catalog collections searchable via search_imagery — Sentinel-1 C-band SAR, Sentinel-2 optical, and NISAR L-band SAR (provisional calibration). Free.
status://currentHow current the data is (ingestion/enrichment frontier), the Daily World Brief status, and an Operational/Delayed/Degraded roll-up. Free.
brief://{date}The Daily World Brief for a specific UTC date (YYYY-MM-DD). Free.

Prompts

daily-situation-briefingSummarize the current world situation from the Daily World Brief.
assess-top-signalFind the highest-severity recent signal in an area/category and run an RS assessment.
aoi-watchScan an area of interest for recent escalations and recommend collection.
market-exposure-checkFind recent events that could plausibly move a given market (oil, grain, shipping, ...) and explain each transmission channel. Informational only — not investment advice.

Looking for the underlying REST endpoints, parameters, and token costs? See the API reference. For a conceptual overview and use cases, see the MCP overview.

From headline to satellite evidence

One connected intelligence workflow across four surfaces — free to start, no GIS software or remote-sensing background required.