REST API
Since version 3.5.x+, IoP exposes a REST API that lets you manage productions, inspect logs, and test components remotely.
The API is served by the IOP.Service.Remote.Rest.v1 CSP class and is mounted at /api/iop by default.
All endpoints return application/json. Errors are returned as:
{"error": "<description>"}
Namespace resolution
Every endpoint accepts an optional namespace parameter that selects the IRIS namespace to operate in (defaults to USER).
It can be supplied in two ways, which work on all routes:
| Method | Where to pass it | Example |
|---|---|---|
| Query string | ?namespace=IRISAPP |
GET /api/iop/status?namespace=IRISAPP |
| JSON body | {"namespace": "IRISAPP", ...} |
POST /api/iop/start with body |
When both are present (POST/PUT routes), the JSON body value takes priority over the query string.
GET /api/iop/version
Returns the API version and description.
Response
{
"version": "1.0.0",
"description": "Interoperability Embedded Python Service API"
}
GET /api/iop/status
Returns the currently running production name and its state.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
string | USER |
Target IRIS namespace |
Response
{
"production": "MyApp.Production",
"status": "running"
}
Possible status values: running, stopped, suspended, troubled, unknown.
POST /api/iop/start
Starts a production.
Namespace — query string (?namespace=) or JSON body field (body wins).
Request body (all fields optional)
{
"production": "MyApp.Production"
}
| Field | Required | Description |
|---|---|---|
production |
No | Production class name. Defaults to the last-used production. |
Response
{
"status": "started",
"production": "MyApp.Production"
}
POST /api/iop/stop
Stops the currently running production.
Namespace — query string (?namespace=) or optional JSON body field (body wins).
The request body may be omitted entirely.
Response
{"status": "stopped"}
POST /api/iop/kill
Forcefully stops the production (equivalent to iop --kill).
Namespace — query string (?namespace=) or optional JSON body field (body wins).
The request body may be omitted entirely.
Response
{"status": "killed"}
POST /api/iop/restart
Restarts the currently running production.
Namespace — query string (?namespace=) or optional JSON body field (body wins).
The request body may be omitted entirely.
Response
{"status": "restarted"}
POST /api/iop/update
Updates (hot-reloads) the currently running production.
Namespace — query string (?namespace=) or optional JSON body field (body wins).
The request body may be omitted entirely.
Response
{"status": "updated"}
GET /api/iop/list
Lists all productions in the namespace with their status metadata.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
string | USER |
Target IRIS namespace |
Response
{
"MyApp.Production": {
"Status": "Running",
"LastStartTime": "2024-01-15 10:30:00",
"LastStopTime": "2024-01-14 18:00:00",
"AutoStart": true
}
}
GET /api/iop/default
Returns the default (last-used) production for the namespace.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
string | USER |
Target IRIS namespace |
Response
{"production": "MyApp.Production"}
PUT /api/iop/default
Sets the default production for the namespace.
Namespace — query string (?namespace=) or JSON body field (body wins).
Request body
{
"production": "MyApp.Production"
}
Response
{"production": "MyApp.Production"}
GET /api/iop/log
Returns production log entries from Ens_Util.Log.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
string | USER |
Target IRIS namespace |
top |
integer | 10 |
Number of most-recent entries to return (ignored when since_id is set) |
since_id |
integer | — | Return only entries with ID > since_id, ordered ascending (useful for polling) |
Response
[
{
"id": 42,
"config_name": "MyService",
"job": "12345",
"message_id": "1",
"session_id": "7",
"source_class": "MyApp.Service",
"source_method": "OnProcessInput",
"text": "Processing request",
"time_logged": "2024-01-15 10:30:01",
"type": "Info"
}
]
Possible type values: Assert, Error, Warning, Info, Trace, Alert, Unknown.
Polling example
import requests
last_id = 0
while True:
resp = requests.get(
"http://localhost:52773/api/iop/log",
params={"since_id": last_id, "namespace": "USER"},
auth=("_SYSTEM", "SYS")
)
entries = resp.json()
for entry in entries:
print(f"[{entry['type']}] {entry['config_name']}: {entry['text']}")
last_id = entry["id"]
GET /api/iop/export
Exports a production definition as JSON.
Query parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
namespace |
string | USER |
Target IRIS namespace |
production |
string | last-used production | Production class name to export |
Response
{
"name": "MyApp.Production",
"description": "",
"test_enabled": true,
"log_trace_events": false,
"actor_pool_size": 2,
"items": [
{
"name": "Python.MyOperation",
"classname": "Python.MyOperation",
"pool_size": 1,
"enabled": true,
"foreground": false,
"comment": "",
"log_trace_events": false,
"schedule": "",
"settings": [
{"target": "Host", "name": "PythonClass", "value": "mymodule.MyOperation"}
]
}
]
}
POST /api/iop/test
Sends a test message to a target component and returns the response synchronously.
Namespace — query string (?namespace=) or JSON body field (body wins).
Request body
{
"target": "Python.MyOperation",
"classname": "Python.MyMsg",
"body": {"key": "value"},
"restart": true
}
| Field | Required | Description |
|---|---|---|
target |
Yes | Config name of the component to invoke |
classname |
No | Python message class name. If omitted an empty Ens.Request is used. |
body |
No | Message body — either a JSON object or a JSON string. Defaults to {}. |
restart |
No | If true, the target component is stopped and restarted before the message is dispatched. Useful to pick up code changes without restarting the whole production. |
Response
{
"classname": "Python.MyMsg",
"body": "{\"result\": \"ok\"}",
"truncated": false
}
truncated is true when the response body was too large to return in full.
PUT /api/iop/migrate
Uploads a Python package to the server and runs its settings.py migration.
Namespace — query string (?namespace=) or JSON body field (body wins).
Request body
{
"namespace": "USER",
"remote_folder": "/opt/iris/packages",
"package": "my_package",
"body": [
{"name": "__init__.py", "data": ""},
{"name": "settings.py", "data": "..."}
]
}
| Field | Required | Description |
|---|---|---|
remote_folder |
No | Absolute server path to place the package. Defaults to the namespace's routine DB directory. |
package |
Yes | Package directory name |
body |
Yes | Array of {name, data} objects representing the files to write |
Response
200 OK with an empty body on success.
Authentication
The API uses standard IRIS CSP authentication. Pass credentials via HTTP Basic Auth:
curl -u <__USERNAME__>:<__PASSWORD__> http://localhost:52773/api/iop/status?namespace=USER
Error responses
All endpoints return HTTP 500 Error with a JSON body on failure:
{"error": "<IRIS error string>"}