Signals and imagery, concurrently
An event feed and a scene catalog answer different questions; production code usually needs both, and they do not need to wait for each other.
Steps
- Fire the signals query and the imagery search for the same AOI concurrently (async client).
- Join them: which recent events have a recent low-cloud scene over them.
In the web app
REST
Authenticate with Authorization: Bearer ond_… (create a key at /account/api). Try any of these live in the Playground.
Signals over the AOI
bash
curl "https://offnadir-delta.com/api/v1/signals?bbox=22%2C44%2C40%2C53&recency=24h&limit=10" \
-H "Authorization: Bearer ond_YOUR_API_KEY"Scenes over the AOI
bash
curl "https://offnadir-delta.com/api/v1/imagery?bbox=22%2C44%2C40%2C53&collection=sentinel-2-l2a&cloud_cover_max=20" \
-H "Authorization: Bearer ond_YOUR_API_KEY"Python
This is the runnable example shipped with the SDK (pip install offnadir-delta, then set OFFNADIR_DELTA_API_KEY).
python
"""Async client: concurrently search imagery and stream signals over an AOI."""
import asyncio
from datetime import date, timedelta
from offnadir_delta import AsyncClient
AOI = [22.0, 44.0, 40.0, 53.0]
TODAY = date.today()
async def main() -> None:
async with AsyncClient() as client:
# Run two independent requests concurrently.
signals_task = client.signals.list(bbox=AOI, recency="24h", limit=10)
imagery_task = client.imagery.search(
bbox=AOI,
collection="sentinel-2-l2a",
cloud_cover_max=20,
start_date=(TODAY - timedelta(days=13)).isoformat(),
end_date=TODAY.isoformat(),
)
page, scenes = await asyncio.gather(signals_task, imagery_task)
print(f"{page.meta.count} signals, {scenes.meta.count} scenes")
for scene in scenes.scenes[:5]:
print(f" {scene.id} {scene.datetime} cloud={scene.cloud_cover}")
# Async iteration over every signal in a date range, Severity 6+ (a plan with event
# filters applies the severity filter; meta.filter_clamp says when it was not applied).
async for signal in client.signals.iterate(
bbox=AOI,
start_date=(TODAY - timedelta(days=2)).isoformat(),
end_date=TODAY.isoformat(),
min_severity_band=6,
):
print(" !", signal.title)
if __name__ == "__main__":
asyncio.run(main())
MCP
Connect once, from any MCP client:
bash
claude mcp add --transport http off-nadir-delta \
https://offnadir-delta.com/api/v1/mcp \
--header "Authorization: Bearer ond_..."The tools this workflow uses: query_signals, search_imagery. See the full roster at /docs/mcp.
From headline to satellite evidence
One connected intelligence workflow across four surfaces — free to start, no GIS software or remote-sensing background required.