Skip to main content

ICP Runtime API

The Integration Control Plane (ICP) exposes a dedicated REST service for runtime agents (Micro Integrator and Ballerina Integrator) to register themselves and continuously report their state. The ICP uses the data from this service to drive reconciliation — pushing control commands back to runtimes to align their state with the desired configuration.

This API is consumed by runtime agents, not by end users. It is separate from the Management API (GraphQL) and the Authentication API (user-facing REST).

Base URL

https://<icp-host>:9445/icp

The default runtime listener port is 9445.


Authentication

All requests must include a signed JWT in the Authorization header:

Authorization: Bearer <runtime-jwt>

The token is validated using kid-based lookup:

  1. The JWT header must contain a kid claim identifying the org secret key.
  2. The ICP looks up the HMAC secret associated with that kid.
  3. The JWT is validated against that secret with:
    • Issuer: icp-runtime-jwt-issuer
    • Audience: icp-server
    • Required scope claim: runtime_agent
    • Clock skew tolerance: 10 seconds

Tokens are provisioned when a runtime key is created in the ICP (via the Management API). A key can be unbound (not yet associated with a project/component) or bound.


Endpoints

POST /icp/heartbeat

Submits a full heartbeat from a runtime. This is the primary registration and state-reporting mechanism. On the first heartbeat from an unbound key, the ICP auto-provisions the project and component and binds the key to them.

After processing the heartbeat, the ICP runs reconciliation and returns any pending control commands for the runtime to execute.

Request body:

{
"heartbeatVersion": "v1.0",
"runtimeId": "runtime-abc123",
"runtimeType": "wso2-mi",
"status": "RUNNING",
"environment": "dev-env",
"project": "MyProject",
"component": "OrderService",
"version": "1.0.0",
"runtimeHostname": "mi-host.example.com",
"runtimePort": "9164",
"nodeInfo": {
"platformName": "wso2-mi",
"platformVersion": "4.3.0",
"osName": "Linux",
"osVersion": "5.15.0",
"osArch": "amd64",
"javaVersion": "17.0.9",
"javaVendor": "Eclipse Adoptium",
"totalMemory": 2147483648,
"freeMemory": 1073741824,
"maxMemory": 2147483648,
"usedMemory": 1073741824
},
"artifacts": {
"listeners": [],
"services": [],
"apis": [{ "name": "OrderAPI", "state": "enabled" }],
"proxyServices": [],
"sequences": [],
"tasks": [],
"templates": [],
"messageStores": [],
"messageProcessors": [],
"localEntries": [],
"dataServices": [],
"carbonApps": [],
"dataSources": [],
"connectors": [],
"registryResources": [],
"endpoints": [],
"inboundEndpoints": []
},
"runtimeHash": "sha256-abc123...",
"timestamp": "2025-05-01T10:00:00Z"
}

Request fields:

FieldTypeRequiredDescription
heartbeatVersionstringNoHeartbeat format version. Default: "v1.0"
runtimeIdstringYesUnique identifier for this runtime instance
runtimeTypestringYesRuntime type identifier (e.g., "wso2-mi")
statusstringYesCurrent runtime status ("RUNNING", "STOPPED", etc.)
environmentstringYesEnvironment handler or UUID the runtime belongs to
projectstringYesProject name or UUID
componentstringYesComponent/integration name or UUID
versionstringNoRuntime version
runtimeHostnamestringNoHostname of the MI management API
runtimePortstringNoPort of the MI management API
nodeInfoobjectYesHost system information (see below)
artifactsobjectYesAll deployed artifacts grouped by type (see below)
runtimeHashstringYesHash of the full runtime state, used for delta comparison
timestampstringYesISO 8601 UTC timestamp of the heartbeat
logLevelsobjectNoCurrent log levels as a { "loggerName": "LEVEL" } map (Ballerina runtimes)

nodeInfo fields:

FieldTypeDescription
platformNamestringPlatform identifier (default: "wso2-mi")
platformVersionstringPlatform/product version
platformHomestringInstallation directory
ballerinaHomestringBallerina home directory (default profile runtimes)
osNamestringOperating system name
osVersionstringOS version
osArchstringCPU architecture
javaVersionstringJVM version
javaVendorstringJVM vendor
carbonHomestringCarbon home directory (MI runtimes)
totalMemoryintegerTotal JVM heap memory in bytes
freeMemoryintegerFree JVM heap memory in bytes
maxMemoryintegerMaximum JVM heap memory in bytes
usedMemoryintegerUsed JVM heap memory in bytes

artifacts fields:

FieldTypeDescription
listenersarrayActive HTTP/HTTPS listeners (default profile)
servicesarrayDeployed Ballerina services (default profile)
mainobjectMain Ballerina package info: packageOrg, packageName, packageVersion (default profile)
apisarrayREST APIs (MI)
proxyServicesarrayProxy services (MI)
sequencesarraySequences (MI)
tasksarrayScheduled tasks (MI)
templatesarrayTemplates (MI)
messageStoresarrayMessage stores (MI)
messageProcessorsarrayMessage processors (MI)
localEntriesarrayLocal entries (MI)
dataServicesarrayData services (MI)
carbonAppsarrayCarbon applications (MI)
dataSourcesarrayData sources (MI)
connectorsarrayConnectors (MI)
registryResourcesarrayRegistry resources (MI)
endpointsarrayNamed endpoints (MI)
inboundEndpointsarrayInbound endpoints (MI)

Each artifact entry includes at minimum a name field and a state field ("enabled" or "disabled").

Response 200 OK:

{
"acknowledged": true,
"fullHeartbeatRequired": false,
"commands": [
{
"commandId": "cmd-001",
"runtimeId": "runtime-abc123",
"targetArtifact": { "name": "OrderAPI" },
"action": "STOP",
"issuedAt": "2025-05-01T10:01:00Z",
"status": "PENDING"
}
],
"errors": []
}
FieldTypeDescription
acknowledgedbooleantrue if the heartbeat was accepted and processed
fullHeartbeatRequiredbooleanIf true, the runtime must send a full heartbeat on the next cycle
commandsarrayControl commands to execute (may be empty)
errorsarrayError messages if processing partially failed

commands entry fields:

FieldTypeDescription
commandIdstringUnique command identifier
runtimeIdstringTarget runtime
targetArtifact.namestringName of the artifact to act on
actionstringSTART, STOP, or SET_LOGGER_LEVEL
issuedAtstringISO 8601 UTC timestamp
statusstringPENDING, SENT, ACKNOWLEDGED, FAILED, or COMPLETED
payloadstringJSON-encoded additional data for the action (e.g., log level settings)

Error responses:

StatusReason
400 Bad RequestInvalid heartbeat payload, unknown kid, or invalid project/component name
401 UnauthorizedMissing or invalid JWT, or insufficient scope (requires runtime_agent)
409 ConflictEnvironment or runtime type mismatch between the JWT key binding and the heartbeat

POST /icp/deltaHeartbeat

Submits a lightweight delta heartbeat containing only the runtime ID and a hash of its current state. If the hash matches the ICP's last known state, no full resync is needed, reducing overhead for stable runtimes.

If the key is unbound (not yet associated with a project/component), the ICP cannot resolve the context from a delta heartbeat alone and instructs the runtime to send a full heartbeat.

Request body:

{
"heartbeatVersion": "v1.0",
"runtimeId": "runtime-abc123",
"runtimeHash": "sha256-abc123...",
"timestamp": "2025-05-01T10:05:00Z"
}
FieldTypeRequiredDescription
heartbeatVersionstringNoHeartbeat format version. Default: "v1.0"
runtimeIdstringYesUnique identifier for this runtime instance
runtimeHashstringYesHash of the full runtime state
timestampstringYesISO 8601 UTC timestamp

Response 200 OK:

Same structure as the full heartbeat response. If fullHeartbeatRequired is true, the runtime must send a POST /icp/heartbeat on the next cycle.

{
"acknowledged": true,
"fullHeartbeatRequired": false,
"commands": [],
"errors": []
}

Error responses:

StatusReason
400 Bad RequestUnknown kid
401 UnauthorizedMissing or invalid JWT
409 ConflictRuntime type mismatch