Job Management

List jobs

Retrieve your most recent detection jobs, optionally filtered by status and endpoint.

GET /api/v1/jobs

List your most recent detection jobs. Filter by status and endpoint_id, adjust the page size with limit. Always sorted newest first.

The endpoint is designed for building "Recent jobs" panels in dashboards, CLI listings, and QGIS plugin history views without having to remember job_ids.

Request

curl "https://api.spcsft.com/api/v1/jobs?status=completed&limit=10" \
  -H "Authorization: Bearer sk_live_xxxxx"

Query parameters

ParameterTypeDefaultDescription
statusstring(all)Filter by status. Comma-separated for multiple values (pending,processing). Allowed: pending / processing / completed / failed.
endpoint_idstring(all)Filter by detection endpoint. Comma-separated for multiple (ship,oilslick). Allowed: ship / oilslick / newbuilding / disappearbuilding / timeseries.
limitinteger30Maximum number of jobs to return. Must be between 1 and 30.

Filter semantics

  • Values are strict lowercase. Pending returns 400.
  • Duplicate values are deduplicated (?status=pending,pending behaves as ?status=pending).
  • Empty segments are ignored (?status=,,pending,, behaves as ?status=pending).
  • Comma-separated only. Repeated keys (?status=pending&status=processing) will only apply the last value — always join with commas instead.
  • Unknown query parameters are silently ignored.

Response

{
  "jobs": [
    {
      "job_id": "351e635d-7c25-4ae8-a2a5-60c01a6f434c",
      "endpoint_id": "ship",
      "satellite_id": "sentinel-1",
      "status": "completed",
      "created_at": "2026-06-29T10:00:00Z",
      "completed_at": "2026-06-29T10:30:00Z",
      "credits_used": 120.0,
      "area_sqkm": 42.5,
      "lat": 35.68,
      "lon": 139.76,
      "request_params": {
        "scene_id": "S1A_IW_GRDH_1SDV_...",
        "polygon": "POLYGON((...))",
        "date": "2026-06-29",
        "date_direction": "nearest"
      },
      "result_path": "/api/v1/jobs/351e635d-7c25-4ae8-a2a5-60c01a6f434c/result.geojson",
      "error_code": null,
      "error_message": null
    }
  ]
}

Response headers

HeaderValueReason
Cache-Controlprivate, no-store, no-cache, must-revalidatePrevents intermediate proxies from caching per-user job lists.
VaryAuthorizationEnsures cache keys stay separated per API key.

Response fields

FieldTypeDescription
jobsarrayJob items, newest first. Empty array if you have no jobs.
jobs[].job_idstring (UUID)Job identifier.
jobs[].endpoint_idstringDetection endpoint (ship, newbuilding, ...).
jobs[].satellite_idstring | nullSatellite (sentinel-1). May be null for endpoints that don't tie to a single satellite.
jobs[].statusstringpending / processing / completed / failed.
jobs[].created_atstringISO 8601 UTC (always with Z suffix).
jobs[].completed_atstring | nullISO 8601 UTC. null while pending/processing.
jobs[].credits_usednumber | nullCredits charged for the job. null while pending.
jobs[].area_sqkmnumber | nullProcessed area. null while pending.
jobs[].latnumber | nullLatitude of the scene / AOI centroid. null while pending.
jobs[].lonnumber | nullLongitude of the scene / AOI centroid. null while pending.
jobs[].request_paramsobject | nullThe parameters you passed to POST /api/v1/analyze/{endpoint}. Shape depends on endpoint_id; useful for redrawing the polygon or re-running with tweaks. Treat every string value as untrusted — escape before inserting into HTML.
jobs[].result_pathstring | nullResult download path (.geojson). null unless status=completed.
jobs[].error_codestring | nullMachine-readable error code. See Errors.
jobs[].error_messagestring | nullHuman-readable error detail. 5xx errors return a fixed generic message — inspect error_code for the actual category.

Ordering and paging

  • Sort is fixed: created_at DESC, job_id DESC. The secondary sort by job_id guarantees a deterministic order when multiple jobs share the same created_at.
  • There is no cursor / offset in v1. Requesting ?limit=30 always returns the 30 newest jobs. If you need older history, request individual jobs via GET /api/v1/jobs/{job_id} — you must keep the job_id yourself.

Errors

StatusCodeWhen
400VALIDATION_ERRORInvalid status / endpoint_id value, non-integer / out-of-range limit, or a query parameter value longer than 128 characters.
401UNAUTHORIZEDMissing or invalid Authorization header.

See Errors for the full error contract.

Examples

Most recent 30 jobs

curl https://api.spcsft.com/api/v1/jobs \
  -H "Authorization: Bearer sk_live_xxxxx"

Only the latest completed job

curl "https://api.spcsft.com/api/v1/jobs?status=completed&limit=1" \
  -H "Authorization: Bearer sk_live_xxxxx"

In-flight ship / oilslick jobs

curl "https://api.spcsft.com/api/v1/jobs?status=pending,processing&endpoint_id=ship,oilslick" \
  -H "Authorization: Bearer sk_live_xxxxx"

Next steps

On this page