Polling a job to know whether it has finished works, but it does not scale and it wastes time. A callback inverts the flow: OpenGate notifies your application over HTTP as the job progresses.

Enabling callbacks

Set the callback field of the job request to the URI you want to be notified on:

{
  "job": {
    "request": {
      "name": "REBOOT_EQUIPMENT",
      "callback": "http://[your_application_address]/[your_URI]",
      "target": { "append": { "entities": ["device_1"] } }
    }
  }
}
  • The URI follows the RFC 3986 format, and only HTTP transport is supported.
  • OpenGate appends the name of the specific callback to this URI when notifying, so a single base URI serves both notifications.
  • The HTTP method is always POST, with the payload as the request body.
  • An empty value disables callback notification.

Callbacks work for tasks too: configure callback inside task.job.request, and every job the task creates will notify.

The two notifications

sequenceDiagram
    participant App as Your application
    participant OG as OpenGate
    participant Dev as Devices

    App->>OG: POST /v80/operation/jobs
    OG-->>App: 201 Created + location
    Note over OG: target set resolved,<br>operations created,<br>schedule reached
    OG->>App: POST callback — job started
    OG->>Dev: operations dispatched
    Dev-->>OG: results per entity
    Note over OG: all operations finished,<br>cancelled or timed out
    OG->>App: POST callback — job finished
Callback Fired when Payload carries
Started The job begins executing — immediately, or when its schedule says so. id, request, report.execution
Finished The job is over: schedule terminated, job cancelled, or all operations completed. id, request, report.execution, report.summary, result with the first page of per-entity operations

Creating a job is not itself notified: the 201 Created response to your POST already tells you the job exists, and report.summary is available from GET /v80/operation/jobs/{jobId} from that moment on.

Job started callback

Fired when execution actually begins. For a scheduled job this happens when the scheduling parameters say so, which may be long after creation:

{
  "job": {
    "id": "33eb9dfa-7a87-41f7-9bad-7b5a26712fec",
    "request": {
      "name": "REBOOT_EQUIPMENT",
      "parameters": {
        "TYPE": "HARDWARE"
      },
      "notify": true,
      "user": "user@mail.com"
    },
    "report": {
      "execution": {
        "activatedDate": "2010-12-20T10:10:00.00Z",
        "startedDate": "2010-12-20T10:10:00.00Z",
        "finishedDate": ""
      }
    }
  }
}

Job finished callback

The most complete of the three. Besides the summary counters it includes the first page of per-entity results, so a small job needs no follow-up request at all. For larger jobs, page through the remaining results with GET /v80/operation/jobs/{jobId}/operations.

{
  "job": {
    "id": "33eb9dfa-7a87-41f7-9bad-7b5a26712fec",
    "request": {
      "name": "REBOOT_EQUIPMENT",
      "parameters": {
        "TYPE": "HARDWARE"
      },
      "notify": true,
      "user": "user@mail.com"
    },
    "report": {
      "execution": {
        "activatedDate": "2014-03-12T11:43:35Z",
        "startedDate": "2014-03-12T11:43:35Z",
        "finishedDate": "2014-03-12T11:44:52Z"
      },
      "summary": {
        "status": "FINISHED",
        "total": 3,
        "inProgress": {
          "total": 0,
          "scheduled": 0,
          "pendingExecution": 0,
          "waitingForConnection": 0,
          "started": 0
        },
        "finished": {
          "total": 2,
          "successful": 1,
          "error": 0,
          "cancelled": {
            "total": 1,
            "byEngine": 0,
            "byUser": 0,
            "byTimeout": 1,
            "byExternalTimeout": 0,
            "byExternal": 0
          }
        },
        "finishedOutOfTime": {
          "total": 1,
          "successful": 1,
          "error": 0
        }
      }
    },
    "result": {
      "page": {
        "number": 1,
        "of": 50
      },
      "operations": [
        {
          "operationId": "86dd3409-6fcd-49d4-be6b-b2fa497207ec",
          "entityId": "device_1",
          "resourceType": "entity.device",
          "name": "REBOOT_EQUIPMENT",
          "parameters": {
            "TYPE": "HARDWARE"
          },
          "notify": true,
          "execution": {
            "activatedDate": "2014-10-01T09:03:42Z",
            "startedDate": "2014-10-01T09:03:45Z",
            "finishedDate": "2014-10-01T09:04:45Z"
          },
          "user": "user@mail.com",
          "status": "FINISHED",
          "result": "SUCCESSFUL",
          "description": "successful operation",
          "steps": [
            {
              "name": "RESET",
              "result": "SUCCESSFUL",
              "description": "Reset ok",
              "timestamp": "2012-09-27T16:46:02.10Z"
            }
          ]
        },
        {
          "operationId": "29891afd-5f4f-4b23-800e-586bd4ecb0eb",
          "entityId": "device_2",
          "resourceType": "entity.device",
          "name": "REBOOT_EQUIPMENT",
          "parameters": {
            "TYPE": "HARDWARE"
          },
          "notify": true,
          "execution": {
            "activatedDate": "2014-10-01T09:03:42Z",
            "startedDate": "2014-10-01T09:03:45Z",
            "finishedDate": "2014-10-01T09:04:45Z"
          },
          "user": "user@mail.com",
          "status": "FINISHED",
          "result": "SUCCESSFUL",
          "description": "successful operation",
          "steps": [
            {
              "name": "RESET",
              "result": "SUCCESSFUL",
              "description": "Reset ok",
              "timestamp": "2012-09-27T16:46:02.10Z"
            }
          ]
        }
      ]
    }
  }
}

Note that a job reaching the finished callback is not necessarily a job that succeeded: in this example status is FINISHED, but of the three operations one was cancelled by timeout and one finished out of time. Always read the counters, not just the status. See the status reference for what each value means.

Notifications versus callbacks

callback and notify are different mechanisms and can be used together:

Field Recipient Purpose
callback Your application, over HTTP Machine-to-machine job progress notification
notify The platform’s notification channels (email, trap) Human notification of the operation result