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.
https://offnadir-delta.com/api/v1/mcpAuthentication
Two ways to authenticate, in order of preference:
- 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.
- 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:
https://offnadir-delta.com/api/v1/mcpClaude.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
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:
{
"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)
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:
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_signals | Metered | 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). |
| query_stats | Metered | Aggregate statistics over the signal corpus — total event count plus per-category and per-day breakdown (trend) for a bounding box and date window. |
| query_hotspots | Metered | 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). |
| get_world_brief | Free | 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). |
| get_usage | Free | 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). |
| search_imagery | Metered | 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). |
| plan_event_imagery | Metered | Plan the imagery evidence for ONE event in a single call, instead of guessing collections one at a time. |
| rank_imaging_priority | Metered | WHERE — and with what class (and therefore cost) of satellite — is observation most worthwhile right now? |
| survey_observable_events | Metered | Which events in a window can a given in-app sensor actually RESOLVE? |
| predict_satellite_passes | Metered | WHEN can this place next be imaged, and by WHAT — the timing half of collection planning. |
| assess_signal | Metered | Run an AI RS (remote-sensing) deep-dive assessment for a specific signal: what to observe, recommended sensors, and a collection window. |
| ask_analyst | Metered | Ask the Delta Analyst an OSINT/GEOINT question. |
| get_analyst_job | Free | Fetch the status and result of an ask_analyst run by job_id. |
| query_claims | Free | 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. |
| create_standing_order | Free | 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. |
| list_standing_orders | Free | 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). |
| delete_standing_order | Free | Delete a standing order by id, or pause/resume it instead by passing active=false/true. |
| list_monitored_areas | Free | 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. |
| get_monitored_area | Free | Fetch one monitored area with its full measurement history — every acquisition that was measured, its value, and whether it was flagged anomalous. |
| create_monitored_area | Free | 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. |
| lookup_elevation | Free | 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. |
| analyze_terrain | Free | Compute FROM the terrain rather than reading heights out of it (that is lookup_elevation). |
| measure_index_series | Metered | 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>". |
| detect_ships | Metered | Count 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 tokQuery 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | no | 4 items | Bounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide. |
| date | string | no | — | Window end date, YYYY-MM-DD (UTC). Defaults to today. |
| days | integer | no | 1…30 | Window length in days ending on `date`. Defaults to 1. |
| categories | string[] | no | kinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | other | Restrict to these categories. Omit for all. |
| markets | string[] | no | oil | natural_gas | grain | shipping | defense | metals | semiconductors | fx | equities | Restrict to signals AI-tagged as exposing these financial markets via a direct physical/supply channel (informational only, not investment advice). Omit for all. |
| limit | integer | no | 1…500 | Maximum rows per page. Defaults to 100. |
| cursor | string | no | — | Opaque pagination cursor from a previous response's meta.next_cursor. |
| minSeverity | number | no | 0…10 | Keep only signals with severity_score >= this (0-10). |
| escalating | boolean | no | — | Keep only signals whose escalation_trend is "escalating". |
| sort | string | no | severity | recent | sources | geoint | Result 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. |
| updatedSince | string | no | — | Differential fetch: only signals (re)enriched at/after this ISO 8601 timestamp. Ignores the date window. Response signals carry last_updated_at. |
| createdSince | string | no | — | Differential fetch: only signals first enriched at/after this ISO 8601 timestamp. |
| observability | string | no | observable | not-observable | Keep only signals with this satellite observability — whether a physical mark is imageable at all (intelligence.satellite_observability). |
| observabilityStatus | string | no | observable | not_observable | insufficient_detail | 3-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. |
| openData | string | no | sufficient | commercial-recommended | not-applicable | Keep only signals with this open-data sufficiency — free imagery is enough vs commercial tasking recommended (intelligence.open_data_sufficiency). |
| minInformationGain | number | no | 0…1 | Keep only signals whose intelligence.expected_information_gain >= this (0-1). |
| taskableOnly | boolean | no | — | Keep 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"). |
| collectionReadyOnly | boolean | no | — | STRICT 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. |
| responseFormat | string | no | concise | detailed | Per-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)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| signals | object[] | yes |
query_statsMetered · 1 tokAggregate 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | no | 4 items | Bounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide. |
| date | string | no | — | Window end date, YYYY-MM-DD (UTC). Defaults to today. |
| days | integer | no | 1…30 | Window length in days. Defaults to 1. |
| categories | string[] | no | kinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | other | Restrict to these categories. Omit for all. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| stats | object | yes |
query_hotspotsMetered · 1 tokGeographic 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | no | 4 items | Bounding box [minLon, minLat, maxLon, maxLat] (WGS84). Omit for worldwide. |
| date | string | no | — | Window end date, YYYY-MM-DD (UTC). Defaults to today. |
| days | integer | no | 1…30 | Window length in days. Defaults to 1. |
| categories | string[] | no | kinetic | armed_conflict | maritime | natural_disaster | infrastructure | aviation | humanitarian | protest | diplomacy | other | Restrict to these categories. Omit for all. |
| precision | number | no | 0.1…5 | Grid cell size in decimal degrees. Defaults to 1. |
| minSeverity | number | no | 0…10 | Keep only points with severity_score >= this. |
| limit | integer | no | 1…500 | Max 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)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| hotspots | object[] | yes |
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). 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| date | string | no | — | Brief date, YYYY-MM-DD (UTC). Defaults to the latest available. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| brief | object | yes | |
| freshness | object | no | Freshness of the returned brief: brief_date, generated_at, age_hours, freshness (operational|delayed|degraded), is_stale, note. |
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). Use this to pre-flight a metered call: decide whether enough balance is left before spending. Free of token charges.
No arguments.
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| tokens | object | yes | |
| plan | object | yes |
search_imageryMetered · 2 tokSearch 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | yes | 4 items | Bounding box [minLon, minLat, maxLon, maxLat] (WGS84). Required. |
| collection | string | no | sentinel-1-grd | sentinel-1-rtc | sentinel-2-l2a | NISAR_L2_GCOV_PROVISIONAL_V1 | Catalog collection. Defaults to sentinel-2-l2a. |
| date | string | no | — | Window end date, YYYY-MM-DD (UTC). Defaults to today. |
| days | integer | no | 1…30 | Window length in days. Defaults to 7. |
| eventDate | string | no | — | Event 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. |
| eventPoint | number[] | no | 2 items | Event 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. |
| eventAoi | number[] | no | 4 items | Event AOI bbox [minLon, minLat, maxLon, maxLat] (WGS84). Drives target_relation.intersects_event_aoi / event_aoi_coverage_ratio. |
| eventTimestamp | string | no | — | Full event timestamp (ISO 8601) when known — promotes same-day scenes from same_day_unknown to pre/post by time. |
| cloudCoverMax | number | no | 0…100 | Sentinel-2 only: max cloud cover %. |
| limit | integer | no | 1…100 | Max scenes to return. Defaults to 25. |
| responseFormat | string | no | concise | detailed | Per-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)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| scenes | object[] | yes |
plan_event_imageryMetered · 4 tokPlan 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).
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| event_id | integer | yes | — | The `id` from query_signals. The server resolves its authoritative point + AOI. |
| analysis_goal | string | yes | damage_assessment | flood_mapping | wildfire_assessment | What the imagery must establish — decides which collection leads and how cloud is gated. |
| event_date | string | no | — | Event date YYYY-MM-DD. Optional — the event row supplies it when known. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| plan | object | yes |
rank_imaging_priorityMetered · 1 tokWHERE — 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | no | 4 items | Area [west, south, east, north] in WGS84. Omit for a global survey. |
| start_date | string | no | — | Inclusive start date YYYY-MM-DD. Defaults to today; clamped to your plan history floor. |
| end_date | string | no | — | Inclusive end date YYYY-MM-DD. Defaults to today. The window is capped at 30 days. |
| categories | string[] | no | — | Restrict to these Delta categories (kinetic, armed_conflict, maritime, natural_disaster, infrastructure, aviation, humanitarian, protest, diplomacy). |
| min_geoint_score | number | no | — | Drop events below this GEOINT score before ranking. |
| top_n | number | no | 1…50 | How many top targets to return (default 12). |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| priority | object | yes |
survey_observable_eventsMetered · 1 tokWhich 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| sensor | string | no | sentinel-2 | sentinel-1 | Which in-app sensor to evaluate against. sentinel-2 = ~10 m optical (daylight, clear sky); sentinel-1 = SAR (all-weather, day/night). Default sentinel-2. |
| bbox | number[] | no | 4 items | Area [west, south, east, north] in WGS84. Omit for a global survey. |
| start_date | string | no | — | Inclusive start date YYYY-MM-DD. Defaults to today; clamped to your plan history floor. |
| end_date | string | no | — | Inclusive end date YYYY-MM-DD. Defaults to today. The window is capped at 30 days. |
| categories | string[] | no | — | Restrict to these Delta categories. |
| min_geoint_score | number | no | — | Drop events below this GEOINT score before surveying. |
| top_n | number | no | 1…50 | How many observable events to return (default 20). |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| survey | object | yes |
predict_satellite_passesMetered · 2 tokWHEN 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| lat | number | no | -90…90 | Target latitude (-90..90; positive = North). Required unless bbox is given. |
| lon | number | no | -180…180 | Target longitude (-180..180; positive = East). Required unless bbox is given. |
| bbox | number[] | no | 4 items | Area [west, south, east, north] in WGS84. The CENTRE is used as the target when lat/lon are omitted. |
| start_date | string | no | — | Inclusive start date YYYY-MM-DD (UTC). Defaults to today. |
| end_date | string | no | — | Inclusive end date YYYY-MM-DD (UTC). Defaults to start+2 days; the window is capped to a 7-day horizon. |
| satellites | string[] | no | sentinel-1 | sentinel-2 | landsat | worldview | iceye | capella | skysat | Families to consider. Omit for all seven. Use this to compare "free systematic only" against "what could I task". |
| max_passes | number | no | 1…100 | Maximum passes to return, soonest first (default 40). |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| passes | object[] | yes | |
| freshness | object | no |
assess_signalMetered · 5/15 tokRun 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| eventId | integer | yes | — | Signal id (global_event_id) from query_signals. |
| kind | string | no | quick | deep | Assessment depth. Defaults to quick. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| kind | string | yes | |
| cached | boolean | no | |
| model | string | no | |
| content | object | yes | |
| meta | object | yes | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
ask_analystMetered · 5–123 tokAsk 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).
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| question | string | yes | — | The analytic question (≤ 500 chars). |
| bbox | number[] | no | 4 items | Optional focus bounding box [minLon, minLat, maxLon, maxLat] (WGS84). |
| mode | string | no | fast | deep | fast (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. |
| idempotencyKey | string | no | — | Optional 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_format | string | no | full | 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)
| Field | Type | Always | Description |
|---|---|---|---|
| brief | object | no | |
| meta | object | no | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| status | string | no | "processing" when the run is still going (poll get_analyst_job or re-send the same idempotencyKey). |
| job_id | string | no | Id of the analyst run — pass to get_analyst_job (also at GET /api/v1/analyst/{job_id}). |
| progress | object | no | Pipeline progress while the job is processing. completed_steps reaches total_steps ONLY when status is "done". |
| estimated_charge | object | no | The 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. |
| message | string | no |
get_analyst_jobFreeFetch 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| job_id | string | yes | — | The job_id returned by ask_analyst. |
| response_format | string | no | full | 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)
| Field | Type | Always | Description |
|---|---|---|---|
| job_id | string | no | |
| status | string | no | "processing" | "done" | "error". |
| progress | object | no | Pipeline progress while the job is processing. completed_steps reaches total_steps ONLY when status is "done". |
| brief | object | no | |
| meta | object | no | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| error | string | no | Failure reason when status is "error". |
| message | string | no | |
| created_at | string | no | |
| updated_at | string | no |
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. 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| since | string | no | — | Only claims asserted on or after this date (YYYY-MM-DD or ISO 8601). |
| evidence_class | string | no | CONFIRMED | REPORTED | PARTY_CLAIM | DISPUTED | ASSESSMENT | UNKNOWN | Restrict to one evidence class. |
| restated_only | boolean | no | — | Only claims that sit in a restatement chain. |
| downgraded_only | boolean | no | — | Only claims a later answer restated with WEAKER evidence — read these first. |
| limit | number | no | 1…200 | How many claims to return (default 50). |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| claims | object[] | yes | |
| counts | object | no |
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. 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".
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | yes | 4 items | Area to watch, [west, south, east, north] in WGS84. Required — a global standing order would fire on everything. |
| question | string | no | — | The question to re-answer each time something changes. Omit for "what changed in this area, and what does it mean?". |
| name | string | no | — | Label for the order (default "Standing order"). |
| cadence | string | no | daily | weekly | monthly | How often to CHECK (checking is free; only a fired check costs tokens). Default weekly. Faster cadences may require a higher plan. |
| categories | string[] | no | — | Restrict the watch to these Delta categories (kinetic, armed_conflict, maritime, natural_disaster, infrastructure, aviation, humanitarian, protest, diplomacy). |
| min_geoint_score | number | no | — | Reporting bar (0-10, default 6). Raise it to be told only about major developments. |
| min_new_events | number | no | — | How many new qualifying events must appear before a run is triggered (default 1). |
| notify_email | boolean | no | — | Email the result when it fires (default true). Results are readable via list_standing_orders either way. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| order | object | yes | |
| projected_monthly_tokens_typical | number | no | |
| projected_monthly_tokens_max | number | no |
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). Also returns how many orders the plan allows and how many remain. Free of token charges.
No arguments.
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| orders | object[] | yes | |
| limits | object | no |
delete_standing_orderFreeDelete 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| order_id | string | yes | — | The id returned by create_standing_order or list_standing_orders. |
| active | boolean | no | — | Omit to DELETE. Pass false to pause and true to resume, keeping the order. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| deleted | string | no | |
| order | object | no |
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. 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)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| areas | object[] | yes | |
| limits | object | no | |
| metering | object | no |
get_monitored_areaFreeFetch 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| area_id | string | yes | — | The area_id from list_monitored_areas. A metric’s polygon_id is also accepted and resolves to the same area. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| area | object | yes | |
| metering | object | no |
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. 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| bbox | number[] | yes | 4 items | The 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. |
| metric | string | yes | — | What 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. |
| name | string | no | — | Label for the area (default "Monitored area"). |
| start_date | string | no | — | YYYY-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)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| area | object | yes | |
| metering | object | no |
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. 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| lat | number | no | -90…90 | Latitude of a single point to measure (use with lon). |
| lon | number | no | -180…180 | Longitude of a single point to measure (use with lat). |
| bbox | number[] | no | 4 items | Area to measure as [lon_min, lat_min, lon_max, lat_max] (WGS84). |
| polygon | array[] | no | 3–∞ items | WGS84 ring [[lon, lat], …]. Statistics cover only the samples inside it. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| mode | string | no | Which form was measured: 'point', 'bbox' or 'polygon'. |
| elevation | object | yes | |
| attribution | string | no | Required Copernicus DEM credit (licence Article 6(b)). |
analyze_terrainFreeCompute 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`.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| operation | string | yes | sar_geometry | profile | 'sar_geometry' = layover/shadow over an area; 'profile' = ground along a line plus a line-of-sight verdict. |
| bbox | number[] | no | 4 items | For 'sar_geometry': area as [lon_min, lat_min, lon_max, lat_max] (WGS84). |
| incidence_deg | number | no | 10…80 | For '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_deg | number | no | 0…360 | For 'sar_geometry': compass bearing the sensor looks along the ground range. A right-looking descending pass looks roughly west (270). |
| lat | number | no | -90…90 | For 'profile': latitude of the observer end. |
| lon | number | no | -180…180 | For 'profile': longitude of the observer end. |
| to_lat | number | no | -90…90 | For 'profile': latitude of the far end. |
| to_lon | number | no | -180…180 | For 'profile': longitude of the far end. |
| observer_height_m | number | no | 0…∞ | For 'profile': eye height above the ground, default 2 m. Use the real mast or tower height when that is the question. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| operation | string | no | |
| sar_geometry | object | no | |
| profile | object | no | |
| attribution | string | no | Required Copernicus DEM credit (licence Article 6(b)). |
measure_index_seriesMetered · 0.5 tokMeasure 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`.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| polygon | array[] | no | — | WGS84 ring [[lon, lat], …] with at least 3 vertices. Statistics cover the samples inside it. |
| bbox | number[] | no | 4 items | Alternative to polygon: [lon_min, lat_min, lon_max, lat_max] (WGS84). |
| index | string | yes | ndvi | evi | savi | ndmi | ndwi | mndwi | ndbi | ndsi | nbr | iron-oxide | clay | ferrous | Which optical index to measure. |
| start | string | yes | — | Start date YYYY-MM-DD (UTC). Clamped forward to 2015-06-27 if earlier. |
| end | string | yes | — | End date YYYY-MM-DD (UTC). |
| max_scenes | integer | no | 1…24 | Cap on scenes measured in this call. Server maximum 24. |
| max_cloud_cover | number | no | 1…100 | Scene cloud-cover ceiling in percent. Default 30. |
| estimate_only | boolean | no | — | True = free: return the scene count, date span and token cost WITHOUT measuring or charging. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| estimate | object | no | |
| series | object | no | |
| meta | object | no | Query echo, token charge/balance (meta.tokens), and pagination where applicable. |
| attribution | string | no |
detect_shipsMetered · 5 tokCount 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.
| Parameter | Type | Req. | Constraints | Description |
|---|---|---|---|---|
| collection | string | yes | sentinel-1-grd | sentinel-1-rtc | Catalog collection of the scene. NISAR detection is available in the app only (it needs a granule conversion first). |
| item_id | string | yes | — | STAC item id of the scene, as returned by search_imagery. |
| bbox | number[] | no | 4 items | Area to search within the scene, [lon_min, lat_min, lon_max, lat_max] (WGS84). |
| geometry | object | no | — | |
| algorithm_version | string | no | auto | v2 | v3 | Detector version. 'auto' (default) picks the recommended version for the sensor. |
Result (structuredContent)
| Field | Type | Always | Description |
|---|---|---|---|
| summary | string | no | One-line natural-language summary of the result, ready to relay to a user. |
| count | integer | no | Vessel-like targets detected. Read `caveats` before quoting it. |
| ships | object | no | |
| caveats | string[] | no | |
| scene | object | no | |
| processing | object | no | |
| meta | object | no | Query 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) |
|---|---|
| areaId | area_id |
| cloud_cover_max | cloudCoverMax |
| collection_ready_only | collectionReadyOnly |
| created_since | createdSince |
| event_aoi | eventAoi |
| event_date | eventDate |
| event_point | eventPoint |
| event_timestamp | eventTimestamp |
| Idempotency-Key | idempotencyKey |
| jobId | job_id |
| min_information_gain | minInformationGain |
| min_severity | minSeverity |
| observability_status | observabilityStatus |
| open_data | openData |
| orderId | order_id |
| taskable_only | taskableOnly |
| updated_since | updatedSince |
| bbox (comma string) | bbox (number[4]) |
Example response
query_signals (concise projection). Full field definitions are in the signals://schema resource.
{
"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://latest | The most recent AI-synthesized Daily World Brief (JSON). Free. |
| signals://schema | JSON Schema of the public Signal shape returned by query_signals / /api/v1/signals. |
| usage://current | Remaining token balance and plan capabilities for the calling key. Free. |
| imagery://collections | The satellite catalog collections searchable via search_imagery — Sentinel-1 C-band SAR, Sentinel-2 optical, and NISAR L-band SAR (provisional calibration). Free. |
| status://current | How 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-briefing | Summarize the current world situation from the Daily World Brief. |
| assess-top-signal | Find the highest-severity recent signal in an area/category and run an RS assessment. |
| aoi-watch | Scan an area of interest for recent escalations and recommend collection. |
| market-exposure-check | Find 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.