ENVI Server runs ENVI tasks in the background, in parallel, and across multiple machines. It lets you offload heavy processing from your workstation and speed up imagery analysis by distributing jobs. It uses a queue and a configurable number of workers to control how many jobs run concurrently. Clients submit jobs over HTTP, and the server queues and executes them using the ENVI task engine, streaming progress back in real time.

This document is the complete reference for the ENVI Server REST API. Use it when building clients, writing automation scripts, or integrating ENVI Server into a larger workflow. It covers every endpoint, all request and response fields, job lifecycle states, and the event polling protocol used by the dashboard.

Base URL: http[s]://<host>:<port> (default port: 9191)

All request and response bodies are JSON (Content-Type: application/json). Dates and times are ISO 8601 UTC strings: 2024-06-15T14:32:01.123Z.

Jobs


List Jobs

GET /jobs

Returns all known jobs, newest first.

Query parameters

Parameter Type Default Description
limit int 100 Max jobs to return. -1 returns all.
offset int 0 Number of jobs to skip (for pagination).

Response headers

Header Description
X-Total-Count Total number of jobs across all pages.

Response 200 OK - array of Job Status objects.

[
  {
    "jobId": "0042",
    "taskName": "SpectralIndex",
    "serviceName": "ENVI",
    "jobStatus": "Succeeded",
    "jobProgress": 100,
    "jobSubmitted": "2024-06-15T14:32:01.123Z",
    "jobStart": "2024-06-15T14:32:01.123Z",
    "jobEnd": "2024-06-15T14:32:09.456Z",
    "jobError": null,
    "jobResults": { "EXECUTION_TIME": { "best": 8.333 } }
  }
]

Get Job

GET /jobs/<jobId>

Response 200 OK - single Job Status object.

Response 404 Not Found - job does not exist.

Submit Job

POST /jobs

Request body

Field Type Required Description
taskName string Yes ENVI task name (e.g. "SpectralIndex").
serviceName string No Always "ENVI".
inputParameters object No Task input parameters.
jobOptions object No { "route": "default" }
{
  "taskName": "SpectralIndex",
  "serviceName": "ENVI",
  "inputParameters": {
    "INDEX": "Normalized Difference Vegetation Index",
    "INPUT_RASTER": { "url": "/data/image.dat" }
  },
  "jobOptions": { "route": "default" }
}

Response 201 Created

{ "jobId": "0043" }

Response headers

Header Value
Location /jobs/0043

Cancel Job

PUT /jobs/<jobId>

Request body

{ "jobStatus": "CancelRequested" }

Only CancelRequested is accepted; any other value returns 400.

Response 200 OK - job was running or queued and has been canceled.

{ "jobId": "0042", "message": "Job was Canceled" }

Response 409 Conflict - job already finished (cannot cancel).

{ "jobId": "0042", "message": "Job already finished" }

Response 404 Not Found - job does not exist.

Delete Job

DELETE /jobs/<jobId>

Permanently removes the job record from disk. Only allowed for finished jobs (Succeeded, Failed, Canceled). Follows the GSF DELETE /jobs/:id convention.

Response 200 OK

{ "code": 204 }

Response 409 Conflict - job is active (cancel it first).

{ "error": "Cannot delete an active job. Cancel it first." }

Response404 Not Found - job does not exist.

Clear Completed Jobs

DELETE /jobs

Permanently removes all finished jobs (Succeeded, Failed, Canceled). Active jobs (Started, Accepted) are not affected.

Response 200 OK

{ "deleted": 37, "skipped": 2 }

deleted - number of jobs removed.
skipped - number of active jobs left in place.

Job Status Object


{
  "jobId": "0042",
  "taskName": "SpectralIndex",
  "serviceName": "ENVI",
  "inputParameters": { "INDEX": "NDVI" },
  "jobUser": null,
  "jobOptions": { "route": "default" },
  "jobSubmitted": "2024-06-15T14:32:01.123Z",
  "jobStart":     "2024-06-15T14:32:01.123Z",
  "jobEnd":       "2024-06-15T14:32:09.456Z",
  "jobStatus": "Succeeded",
  "jobProgress": 100,
  "jobMessage": "",
  "jobError": null,
  "jobResults": {
    "EXECUTED_TASK": { "best": { } },
    "EXECUTION_TIME": { "best": 8.333 }
  }
}

jobStatus values

Value Meaning
Accepted Job is queued, waiting for a worker slot.
Started Engine process is running.
Succeeded Engine exited with valid JSON output.
Failed Engine error, bad output, or non-zero exit code. jobError contains the message.
Canceled Job was canceled before or during execution.

jobResults - each key maps to { "best": <value> }. Present only on Succeeded. Standard keys:

Key Type Description
EXECUTION_TIME float Wall-clock seconds the task ran.
EXECUTED_TASK object The task's primary output parameter object.

Events


Poll for Events

GET /events/poll?since=<seq>

Returns all server-side events recorded after sequence number since. The dashboard calls this repeatedly to receive live updates without SSE.

Query parameters

Parameter Type Default Description
since int 0 Return events with seq > since.

Response 200 OK

{
  "seq": 17,
  "events": [
    { "seq": 15, "type": "job_submitted", "data": { } },
    { "seq": 16, "type": "job_progress",  "data": { } },
    { "seq": 17, "type": "job_completed", "data": { } }
  ]
}

Event types

Type Description
job_submitted A new job was accepted. data is the initial Job Status object.
job_progress Progress update for a running job. data contains jobId, jobStatus, jobProgress, jobMessage.
job_completed A job finished (succeeded, failed, or canceled). data is the final Job Status object.
job_deleted A single job was deleted. data: { "jobId": "0042" }.
jobs_cleared All completed jobs were cleared. data: { "deleted": 37 }.

The server keeps the last 1 000 events in memory. On first connect, poll with since=0 to get the current sequence number, then begin polling from that position.

Services


List Services

GET /services

Response 200 OK

{ "services": [{ "name": "ENVI" }] }

Get Service

GET /services/<serviceName>

serviceName must be ENVI (case-insensitive). Returns 404 otherwise.

Response 200 OK

{ "name": "ENVI" }

Refresh Task Catalog

PUT /services

Invalidates the in-memory task catalog so it is rebuilt on the next request.

Request body

{ "taskRefresh": true }

Response200 OK

{ "message": "Task catalog refreshed" }

Tasks


List Tasks

GET /services/<serviceName>/tasks

Returns all tasks available from the ENVI task engine. The catalog is built once and cached; use PUT /services to refresh it.

Response 200 OK

{
  "tasks": [
    {
      "taskName": "SpectralIndex",
      "serviceName": "ENVI",
      "displayName": "Spectral Index",
      "description": "Computes a spectral index from a raster.",
      "revision": "1",
      "inputParameters": [
        {
          "name": "INPUT_RASTER",
          "type": "ENVIRASTER",
          "required": true,
          "displayName": "Input Raster",
          "description": "The input raster."
        }
      ],
      "outputParameters":[
        {
          "name": "OUTPUT_RASTER",
          "type": "ENVIRASTER",
          "required": false,
          "displayName": "Output Raster"
        }
      ]
    }
  ]
}

Get Task Info

GET /services/<serviceName>/tasks/<taskName>

Returns metadata for a single task.

Response 200 OK - same shape as one entry in the tasks array above.

Response 404 Not Found - task not found.

Get Task JSON Schema

GET /services/<serviceName>/tasks/<taskName>/schema

Returns the JSON Schema for the task's input parameters, if the engine supports it.

Response 200 OK - a JSON Schema object.

Response 404 Not Found - schema not available or task not found.

Reports


Server Info

GET /reports/server-info

Response 200 OK

{
  "description": "ENVI Server runs ENVI tasks in the background...",
  "version": "6.3",
  "hostname": "workstation01",
  "port": 9191,
  "configuration": { },
  "config_path": "C:\\envi\\configuration.json"
}

Debug


Server state

GET /debug/state

Snapshot of internal runtime state - for troubleshooting only, not a stable API.

Response 200 OK

{
  "active_procs": [{ "jobId": "0043", "pid": 12345 }],
  "queued": [],
  "live_progress": { "0043": { "percent": 42, "message": "Processing band 3" } },
  "event_seq": 17,
  "recent_events": [ ],
  "job_index_size": 43
}

Dashboard


GET /dashboard

Returns the HTML dashboard page (served from dashboard.html alongside server.py).

Error Responses


All error responses use this shape:

{ "error": "Human-readable error message" }
HTTP status When
400 Bad Request Invalid request body or unsupported operation.
404 Not Found Job, service, or task does not exist.
409 Conflict Operation not valid for the job's current state (e.g. canceling a finished job, deleting an active job).
500 Internal Server Error Unexpected server error.
502 Bad Gateway Task engine returned an error.
503 Service Unavailable Task engine query timed out.