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. |