API Reference
SAR API gives you flood maps, dark vessel detections, and change analysis derived from
free Sentinel-1 radar data. All endpoints return JSON. Authentication via X-API-Key header.
Overview
The API is split into two parts:
- Public endpoints — no key required, rate-limited, sample data only
- Authenticated endpoints — require
X-API-Key, full access based on your plan tier
Authentication
Include your API key in every request as the X-API-Key header.
curl https://api.sarapi.io/v1/me \ -H "X-API-Key: sw_your_key_here"
Get a free key at sarapi.io/#signup. No credit card required.
Base URL
Rate limits & tiers
| Tier | Calls/day | History | Max bbox | Webhooks | Tiles |
|---|---|---|---|---|---|
| Free | 100 | 30 days | 1°×1° | ✗ | ✗ |
| Developer | 5,000 | 1 year | Unlimited | ✓ | ✗ |
| Pro | 50,000 | 3 years | Unlimited | ✓ | ✓ |
| Enterprise | Unlimited | Unlimited | Unlimited | ✓ | ✓ |
When you exceed your daily limit you can use burst credits — one credit per call. Credits roll over for 90 days and can be topped up via billing/credits.
Errors
| Status | Meaning |
|---|---|
| 400 | Bad request — invalid parameters |
| 401 | Missing or invalid X-API-Key |
| 403 | Your plan does not include this feature |
| 404 | Resource not found |
| 410 | Resource expired (e.g. COG tiles past 14-day window) |
| 429 | Daily rate limit exceeded, no credits remaining |
| 502 | Upstream error (tile server, payment provider) |
All errors return JSON: {"status":"error","code":"...","message":"..."}
GET /v1/analysis
Query analysis results (floods, vessels, oil spills, etc.) within a bounding box and date range. Results are paginated.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| bbox | required | Bounding box as west,south,east,north in decimal degrees. Free tier limited to 1°×1°. |
| type | optional | Filter by analysis type: flood, vessel, oil_spill, burn_scar, sea_ice, deforestation, construction. Omit or pass all for all types. |
| date_from | optional | ISO 8601 date string (e.g. 2024-01-01). Clamped to your tier's history limit. |
| date_to | optional | ISO 8601 date string. |
| limit | optional | Results per page. Default: 100. |
| page | optional | Page number. Default: 1. |
{
"data": [
{
"id": "uuid",
"type": "flood",
"geometry": { "type": "Polygon", "coordinates": [...] },
"confidence": 0.87,
"acquired_at": "2024-06-15T10:32:00Z",
"scene_id": "S1A_IW_GRDH_...",
"properties": { "area_km2": 142.3 }
}
],
"meta": { "total": 48, "page": 1, "limit": 100, "pages": 1 }
}
GET /v1/latest
Returns the single most recent detection of a given type within a bounding box.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| bbox | required | west,south,east,north |
| type | required | Analysis type (see above) |
{ "data": [ /* 0 or 1 result */ ] }
GET /v1/summary
Aggregate counts, total area, and last detection time per analysis type for a bbox and date range.
{
"flood": { "events": 12, "total_area_km2": 843.2, "last_detected": "2024-06-15T10:32:00Z" },
"vessel": { "events": 234, "total_area_km2": 0, "last_detected": "2024-06-15T10:32:00Z" },
"oil_spill": { "events": 3, "total_area_km2": 21.5, "last_detected": "2024-05-20T08:11:00Z" }
}
GET /v1/timeseries
Time-bucketed counts or total area for a given analysis type. Useful for charting trends.
Query parameters
| Parameter | Type | Description |
|---|---|---|
| bbox | required | west,south,east,north |
| type | required | Analysis type |
| metric | optional | count (default) or area_km2 |
| interval | optional | day, week (default), or month |
{ "data": [ { "date": "2024-06-10T00:00:00.000Z", "value": 7 }, ... ] }
GET /v1/scenes
List SAR scenes that intersect a bounding box. Each scene includes a tile URL for map rendering.
{
"data": [
{
"scene_id": "S1A_IW_GRDH_...",
"acquired_at": "2024-06-15T10:32:00Z",
"pass_direction": "ascending",
"coverage": { "type": "Polygon", ... },
"analysis_types": ["flood", "vessel"],
"tile_url": "https://api.sarapi.io/v1/tiles/{scene_id}/{z}/{x}/{y}.png"
}
]
}
GET /v1/coverage
Check whether a location has been imaged by Sentinel-1 and when the last acquisition was.
{
"covered": true,
"last_acquired": "2024-06-15T10:32:00Z",
"next_expected": null,
"pass_frequency_days": 6,
"total_scenes": 84
}
Map tiles
Pro Enterprise Render SAR imagery as XYZ map tiles.
Returns a PNG tile. The band parameter accepts vv (default) or vh. Tiles are cached for 1 hour and expire 14 days after scene acquisition.
tile_url from /v1/scenes as a template — replace {z}, {x}, {y} with tile coordinates in your map library (Leaflet, Mapbox GL JS, etc).
POST /v1/subscriptions
Developer Pro Enterprise Subscribe to real-time webhook alerts for new detections in an area.
Request body
| Field | Type | Description |
|---|---|---|
| analysis_type | required | flood, vessel, oil_spill, burn_scar, sea_ice, deforestation, construction, or all |
| bbox | required | Array of 4 numbers: [west, south, east, north] |
| webhook_url | required | HTTPS URL that will receive POST events |
| secret | optional | Signing secret — included in X-SAR-Signature header of webhook events |
curl -X POST https://api.sarapi.io/v1/subscriptions \ -H "X-API-Key: sw_your_key" \ -H "Content-Type: application/json" \ -d '{ "analysis_type": "flood", "bbox": [-0.5, 51.3, 0.3, 51.7], "webhook_url": "https://yourapp.com/hooks/sar", "secret": "whsec_..." }'
{ "id": "uuid", "analysis_type": "flood", "webhook_url": "...", "active": true, "created_at": "..." }
GET /v1/subscriptions
List all webhook subscriptions for your API key.
DELETE /v1/subscriptions/:id
Permanently delete a webhook subscription.
Returns 204 No Content on success.
Webhook payload format
When a new detection intersects your subscribed bbox, we send a signed POST to your webhook_url.
{
"event": "detection.new",
"subscription_id": "uuid",
"analysis_type": "flood",
"result": {
"id": "uuid",
"type": "flood",
"geometry": { /* GeoJSON */ },
"confidence": 0.91,
"acquired_at": "2024-06-15T10:32:00Z",
"properties": { "area_km2": 58.4 }
},
"sent_at": "2024-06-15T11:00:00Z"
}
If you provided a secret, verify the X-SAR-Signature: sha256=... header using HMAC-SHA256.
GET /v1/me
Returns your current plan, daily usage, credits, and limits.
{
"tier": "free",
"calls_today": 42,
"calls_month": 312,
"credits": 0,
"limits": {
"calls_per_day": 100,
"history_days": 30,
"bbox_max_degrees": 1
}
}
POST /v1/billing/checkout
Create a Stripe Checkout session to upgrade your plan. Returns a redirect URL.
Request body
| Field | Type | Description |
|---|---|---|
| plan | required | developer or pro |
{ "url": "https://checkout.stripe.com/..." }
POST /v1/billing/credits
Purchase burst credits. Credits let you exceed your daily limit — one credit per extra call.
Request body
| Field | Type | Description |
|---|---|---|
| pack | required | starter (1,000 credits), growth (3,000 credits), pro (7,000 credits) |
{ "url": "https://checkout.stripe.com/..." }
GET /public/analysis
Sample of recent detections — no authentication required. Returns up to 500 results globally.
GET /public/stats
Aggregate counts by detection type across the full dataset. No authentication required.
{
"flood": 1842, "vessel": 94210, "oil_spill": 312,
"burn_scar": 58, "deforestation": 127, "sea_ice": 44,
"construction": 91, "scenes": 2104
}