A job is one execution of an operation type over a target set of entities. Creating a job is the normal way to run an operation: you POST a job request, and OpenGate turns it into one operation per target entity.

POST /v80/operation/jobs

Anatomy of a job request

Section Purpose
name The operation type to execute, for example REBOOT_EQUIPMENT.
parameters The parameters of the operation itself. See Operation parameters.
target Which entities the operation runs on.
active Whether the job starts. false creates the job without launching it.
schedule When the job runs and when it gives up.
operationParameters Timeouts and retry policy applied to each individual operation.
notify Whether to notify the operation result by email or trap. Defaults to false.
callback URI to be notified on job progress instead of polling. See Callbacks.
userNotes Free-text notes attached to the job instance.

Selecting the target

There are three ways to reference the entities a job acts on, and they are mutually exclusive — a single job cannot mix entity lists, tags and filters.

An explicit list of entities

"target": { "append": { "entities": ["device_1", "device_2"] } }

The same parametrization is applied to every entity in the list. Two limits apply:

  • Entities per array: 100 by default.
  • Request body size: 300 KBytes by default.

Both are configurable per platform, so check the values with your administrator. To launch an operation over a larger list, create the job with active set to false and use PUT requests to append entities in batches, activating the job in the last call.

A tag

"target": { "append": { "tags": ["fleet_north"] } }

Only one tag name can be passed. OpenGate resolves the tag into the target set and builds the internal structure of the job; when that work finishes the job waits in IDLE if it is not active, or in SCHEDULED if it is.

A filter

"target": { "append": { "filter": { "eq": { "device.model": "MDL-1" } } } }

The filter is evaluated by the platform to resolve the target set. Previously created filters cannot be reused here — the filter must be inlined in the request.

The optional resourceType query string parameter restricts the filter to one entity type:

Value Entities considered
entity.device Devices
entity.asset Assets
entity.commsModule Communication modules
entity.subscription Subscriptions
entity.subscriber Subscribers
Filter targets cannot be updated

The target section of a filter-based job cannot be modified afterwards. To change the target set, deactivate the job and create a new one with the new filter.

Scheduling

The schedule block controls when the job runs. start accepts either an exact date or a delayed value in milliseconds; stop sets the deadline after which pending operations are cancelled.

Two optional modes refine how the operations are distributed inside that window.

Window

window restricts execution to given weekdays and a daily time range — useful when field interventions are only acceptable during a maintenance window.

Periods must be whole hours; intermediate periods are rejected:

Window Allowed
"start": "09:00:00Z""stop": "15:00:00Z" Yes
"start": "09:30:00Z""stop": "15:30:00Z" Yes
"start": "09:00:00Z""stop": "15:30:00Z" No

Scattering

scattering spreads the individual operations across the available time instead of firing them all at once. It exists to protect shared infrastructure — typically a mobile operator cell that would collapse if thousands of devices woke up simultaneously.

Field Meaning
maxSpread Percentage (0–100) of the job’s effective time used to spread operations. 0 runs as fast as possible, 100 spreads over the whole window. Default 0.
strategy.field Entity field used to group operations. Currently only subscription.collected.cellInfo.
strategy.factor Dispersion level (0–100) applied within each group. 0 clusters maximally, 100 scatters maximally. Default 0.
strategy.warningMaxRate Speed control in operations per second, to verify the resulting rate stays within maxSpread.

Per-operation timeouts and retries

operationParameters applies to each individual operation, not to the job as a whole:

Field Meaning
ackTimeout Milliseconds to wait for the device to accept the operation. On expiry the operation is cancelled.
timeout Milliseconds to wait for the operation to finish. Default 60000.
retries Number of retries when the operation gets no acknowledgement or times out. Default 0.
retriesDelay Milliseconds between retries.
retryResultList Results that trigger a retry. ERROR_TIMEOUT is always included.
Minimum internal timeout

OpenGate enforces a minimum internal timeout of 40 seconds, so timeout plus ackTimeout must be greater than that. The default of 60 seconds is a good starting point.

Job life cycle

A job’s status reflects the aggregate progress of all its operations:

stateDiagram-v2
    direction TB
    [*] --> IDLE: active=false
    [*] --> SCHEDULED: active=true<br>start delayed
    [*] --> IN_PROGRESS: active=true<br>start now

    IDLE --> SCHEDULED: active=true<br>start delayed
    IDLE --> IN_PROGRESS: active=true<br>start now
    SCHEDULED --> IDLE: active=false
    SCHEDULED --> IN_PROGRESS: start time<br>reached

    IN_PROGRESS --> PAUSED: active=false
    PAUSED --> IN_PROGRESS: active=true

    IN_PROGRESS --> FINISHED: all ok
    IN_PROGRESS --> FINISHED_WITH_ERRORS: with errors
    IN_PROGRESS --> CANCELLING_BY_USER: cancelled<br>by a user
    IN_PROGRESS --> CANCELLING_BY_ENGINE: timeout<br>reached
    SCHEDULED --> CANCELLING_BY_USER: cancelled<br>by a user
    CANCELLING_BY_USER --> CANCELLED: all operations<br>cancelled
    CANCELLING_BY_ENGINE --> TIMEOUT_CANCELLED: all operations<br>cancelled

    FINISHED --> [*]
    FINISHED_WITH_ERRORS --> [*]
    TIMEOUT_CANCELLED --> [*]
    CANCELLED --> [*]
Transition Trigger
Into IDLE The job is created or updated with active set to false.
Into SCHEDULED The job is active and its schedule.start is a date or a delay.
Into IN_PROGRESS The job is active with an immediate start, or the scheduled start time is reached.
IN_PROGRESSPAUSED active set to false on a running job.
PAUSEDIN_PROGRESS active set to true on a paused job.
Into FINISHED Every operation reached a final state successfully.
Into FINISHED_WITH_ERRORS Operations failed or were cancelled.
Into CANCELLING_BY_USER A user cancels the job, through the console or the API.
Into CANCELLING_BY_ENGINE The job’s timeout is reached, so the platform cancels it.
Into CANCELLED Every entity operation of a user-cancelled job finished cancelling.
Into TIMEOUT_CANCELLED The same, for a job the timeout cancelled.

Both cancelling states are transient: the job stays there until every one of its operations has finished cancelling, which on a job targeting thousands of entities is not instant.

One detail still unconfirmed

The specification defines what each state means but not which terminal state the engine path ends in. The pairing above — a user cancellation ending in CANCELLED, a timeout ending in TIMEOUT_CANCELLED — follows from their descriptions and is pending confirmation.

See the status reference for the complete list of job, operation and step values.

Reading the result

An execution involves as many entities as the target references, so one job explodes into many results. The API exposes both levels:

flowchart LR
    JOB["Job"] --> SUM["report.summary<br>one aggregated view<br>counters per state"]
    JOB --> RES["operations<br>one result per entity<br>status, result, steps"]
Endpoint Returns
GET /v80/operation/jobs/{jobId} The job request plus report.summary
GET /v80/operation/jobs/{jobId}/operations Paginated per-entity results
GET /v80/operation/jobs/{jobId}/operations/{id} A single entity’s result

The per-entity list is paginated with start and size parameters — necessary when a job targets thousands of entities. Each operation object carries its own status, result, description and steps array.

To be notified when the job starts and when it finishes instead of polling these endpoints, configure a callback.

Updating a job

PUT /v80/operation/jobs/{jobId}

A job can only be modified while active is false and it has not started. What you can change:

  • Request fields: active, notify, callback, userNotes, schedule.start, schedule.stop.
  • The target entity list, by appending or removing entities.

The same JSON size limit as in creation applies. In the last PUT, set active to true to start the execution.

Pause and resume

The same endpoint controls a running job through the active field:

  • Pause: set active to false on a job in IN_PROGRESS. The job moves to PAUSED. While paused, the job’s features cannot be modified.
  • Resume: set active to true on a paused job. The job returns to IN_PROGRESS.

Cancelling a job

DELETE /v80/operation/jobs/{jobId}

The job moves to CANCELLING_BY_USER first — or to CANCELLING_BY_ENGINE when the platform itself cancels it — and to CANCELLED once all of its operations are cancelled.

Cancellation does not roll back

Cancelling a job does not undo steps that already executed on the devices. A firmware update cancelled halfway leaves the device halfway. Be deliberate.

Searching jobs and operations

Job and operation searches follow the platform’s standard search pattern, with support for filtering, sorting, field selection and summaries:

POST /v80/search/jobs
POST /v80/search/jobs/summary
POST /v80/search/entities/devices/operations
POST /v80/search/entities/operations/history

Equivalent endpoints exist for subscribers and subscriptions. Results are returned as JSON by default, or as CSV through HTTP header options. The full parameter list is in the API reference.