Get job status
Retrieve the status and metadata of a detection job.
GET /api/v1/jobs/{job_id}
Retrieve the current status of a detection job. Poll this endpoint until status becomes completed or failed.
Request
curl https://api.spcsft.com/api/v1/jobs/351e635d-7c25-4ae8-a2a5-60c01a6f434c \
-H "Authorization: Bearer sk_live_xxxxx"Path parameters
| Parameter | Type | Description |
|---|---|---|
job_id | string (UUID) | Returned from the detection endpoint. |
Response
Completed job
{
"job_id": "351e635d-7c25-4ae8-a2a5-60c01a6f434c",
"endpoint_id": "newbuilding",
"satellite_id": "sentinel-1",
"status": "completed",
"created_at": "2026-03-12T15:00:00Z",
"completed_at": "2026-03-12T15:32:10Z",
"result_path": "/api/v1/jobs/351e635d-7c25-4ae8-a2a5-60c01a6f434c/result.geojson",
"error_code": null,
"error_message": null,
"error": null,
"area_sqkm": 80.7,
"coverage": {
"method": "measured",
"requested_area_sqkm": 103.4,
"ratio": 0.78,
"polygon": "POLYGON((139.7 35.6, ...))"
},
"scene_selection": {
"first_month": "2024-01",
"last_month": "2026-02"
},
"warnings": [
{
"code": "LOW_AOI_COVERAGE",
"message": "Scenes cover only 78% of the requested area."
}
]
}Failed job
{
"job_id": "351e635d-7c25-4ae8-a2a5-60c01a6f434c",
"endpoint_id": "timeseries",
"satellite_id": "sentinel-1",
"status": "failed",
"created_at": "2026-03-12T15:00:00Z",
"completed_at": "2026-03-12T15:31:15Z",
"result_path": null,
"error_code": "VALIDATION_ERROR",
"error_message": "Polygon area (52.6 km²) exceeds 50 km² limit for endpoint 'timeseries'",
"error": "VALIDATION_ERROR",
"area_sqkm": null,
"coverage": null,
"scene_selection": null,
"warnings": []
}Response fields
| Field | Type | Description |
|---|---|---|
job_id | string | Job UUID. |
endpoint_id | string | null | Detection type (ship, oilslick, newbuilding, disappearbuilding, timeseries, idlefarm). null for jobs submitted before this field existed. |
satellite_id | string | null | Satellite used for the analysis. |
status | string | pending / processing / completed / failed |
created_at | string | ISO 8601 timestamp. |
completed_at | string | null | ISO 8601 timestamp. null while pending/processing. |
result_path | string | null | GeoJSON download path. null unless completed. |
error_code | string | null | Machine-readable error code. See Errors. |
error_message | string | null | Human-readable error detail. Fixed message for 5xx errors. |
error | string | null | Deprecated. Same as error_code. Use error_code instead. |
area_sqkm | number | null | Area in km² that credits were charged on. For newbuilding / disappearbuilding / timeseries it is the actually analysed area, with no-data excluded. |
coverage | object | null | How much of your requested polygon was actually analysed. See Coverage. |
scene_selection | object | null | When the imagery used was captured. null when you supplied scene_id, or for jobs submitted before this field existed. |
warnings | array | Non-fatal notices about the selected imagery. Empty when the request was satisfied as asked. |
Coverage
The polygon you request and the area actually analysed are rarely identical: the selected scene may not cover the whole AOI, and portions without usable data are excluded. coverage quantifies that difference, so you can tell "nothing detected" apart from "not analysed".
| Field | Type | Description |
|---|---|---|
coverage.method | "measured" | "estimated" | How the value was obtained — see below. |
coverage.requested_area_sqkm | number | Area of the polygon you submitted (km²). |
coverage.ratio | number | Fraction of the requested area that was analysed, 0.0–1.0, rounded down to two decimals. |
coverage.polygon | string | null | WKT of the analysed extent, in the same format as the request polygon. In job responses it is present only for measured coverage; a preview carries the predicted extent instead. |
method | Derived from | Endpoints |
|---|---|---|
measured | The actual data boundary after excluding no-data pixels | newbuilding, disappearbuilding, timeseries |
estimated | The intersection of your polygon with the selected scene footprint | ship, oilslick (polygon input) |
coverage is absent for inputs where the analysed fraction cannot be determined, such as scene_id input. Treat a missing coverage as unknown — do not display it as 100%.
coverage.polygon is simplified to fit within the request size limit, so you can resubmit it — or the missing remainder — directly as a new request's polygon. When no-data splits the analysed area it is a MULTIPOLYGON; split it into individual polygons before resubmitting.
Scene selection
When you submit a polygon, the API picks the Sentinel-1 imagery for you. scene_selection tells you when the imagery used was captured, so you can confirm it matches the period you asked for.
| Field | Type | Description |
|---|---|---|
scene_selection.first_month | string | null | Observation month of the earliest scene used (YYYY-MM). |
scene_selection.last_month | string | null | Observation month of the latest scene used (YYYY-MM). |
Compare first_month / last_month against the date_start / date_end you requested. A gap means suitable imagery was not available across the whole period — warnings explains why.
Observation dates are reported to month precision only. Scene identifiers and exact acquisition timestamps are not returned.
Warnings
A job with warnings still succeeds: status is completed and error_code is null. Warnings tell you whether to trust the result as-is.
{
"status": "completed",
"error_code": null,
"scene_selection": {
"first_month": "2021-01",
"last_month": "2021-12"
},
"warnings": [
{
"code": "PERIOD_PARTIALLY_COVERED",
"message": "Observations cover only 30% of the requested period (2021-01-01 to 2023-12-31)."
}
]
}Each entry has a machine-readable code and a human-readable message. See Warnings for the full list.
Status values
| Status | Description |
|---|---|
pending | Queued, not yet started. |
processing | Currently running. |
completed | Done. Result available for 30 days. |
failed | Failed. See error for details. No credits charged. |
Polling guidance
Poll about once per minute. See How it works for per-endpoint timing recommendations.