i3X API
A standards-based read interface to your Unified Namespace (UNS) that implements the CESMII i3X (Industrial Information Interoperability eXchange) 1.0 specification. Where the UNS Read API is Capture's native, ergonomic UNS interface, the i3X API exposes the same data through the vendor-neutral i3X contract — so an integrator that already speaks i3X can browse and query Capture without bespoke code.
i3X is a thin, read-only façade over the UNS: the same hierarchy, the same identifiers, re-projected as i3X objects, object types and relationships.
The i3X API is disabled by default. If every i3X endpoint returns 404, it has not been enabled for your environment — contact Capture to switch it on. (UNS itself must also be enabled for your company.)
Base URL & versioning
https://portal.captureplatform.com/v2/i3x/v1
i3X carries its own /v1 version, independent of the Capture API version. The leading /v2 is the Capture gateway prefix; the trailing /v1 is the i3X spec version. An i3X client's base URL is therefore https://portal.captureplatform.com/v2/i3x, to which it appends /v1/{resource}.
Headers & authentication
| Header | Value |
|---|---|
| AuthVersion | V0.0.1 (only value accepted; others return 401) |
| Authorization | [Bearer / ApiToken] <Received auth token> |
| companyView | (Optional) restricts the call to a specific company view |
GET /infois unauthenticated (per the i3X spec) — no headers required.- Every other endpoint requires a valid token and the Data Explorer → View right on a UNS-enabled company. The token's company determines which slice of the UNS you can see.
See Authentication for how to obtain a token.
Response envelope
Every i3X endpoint wraps its payload in the i3X envelope. Field names are camelCase (the i3X spec), unlike the rest of the Capture API.
Single / collection responses:
{ "success": true, "result": <payload> }
Batch (per-element) responses — used by the POST endpoints that take elementIds:
{
"success": true,
"results": [
{ "success": true, "elementId": "c91a…", "result": { } },
{
"success": false,
"elementId": "not-a-guid",
"responseDetail": { "title": "Bad Request", "status": 400, "detail": "Invalid elementId (not a GUID): not-a-guid" }
}
]
}
In a batch call, the HTTP status is 200 even when individual elements fail. Inspect each element's success and responseDetail (an RFC 7807-style problem detail). An element is reported failed when its id is not a GUID (400) or is unknown / outside your company subtree (404, "Object not found or not in scope").
elementId
An i3X elementId is the UNS node's identifier (a GUID), as a string — the same identifier used by the UNS Read API. So you can discover ids there (or via i3X browsing below) and use them interchangeably.
- An asset node (
enterprise,site,area,line,workCell, …) is a composition (isComposition: true). - A variable node is a leaf (
isComposition: false) and carries a value.
maxDepth controls how deep a composition is expanded: 1 (default) means "this object only"; > 1 expands descendant variable values under a components map keyed by child elementId.
All timestamps are RFC 3339 UTC with sub-second precision, e.g. 2026-06-29T14:32:15.1234567Z.
Capabilities — GET /info
Unauthenticated server capabilities document. Use it to discover what this server supports.
{
"success": true,
"result": {
"specVersion": "1.0",
"serverName": "Capture Platform",
"serverVersion": null,
"capabilities": {
"query": { "history": true },
"update": { "current": false, "history": false },
"subscribe": { "stream": false }
}
}
}
Capture's façade supports history queries and poll-based subscriptions; it does not support value writes (update) or SSE streaming (subscribe.stream).
Browsing the address space
List Namespaces — GET /namespaces
The i3X type namespaces this server exposes.
{ "success": true, "result": [ { "uri": "urn:capture:uns", "displayName": "Capture UNS" } ] }
List Root Objects — GET /objects
Returns the root object(s) of your address space (your company UNS root). Walk down from here with /objects/related.
{
"success": true,
"result": [
{
"elementId": "1a0d…",
"displayName": "Vintecc",
"typeElementId": "enterprise",
"isComposition": true,
"isExtended": false
}
]
}
| Field | Type | Notes |
|---|---|---|
elementId | string | UNS node GUID. |
displayName | string | Node name. |
typeElementId | string | The object's type (a UNS node-type string, e.g. line, variable). |
parentId | string | — | Parent elementId; omitted at the company root. |
isComposition | bool | true for assets, false for leaf variables. |
isExtended | bool | Always false in v1. |
metadata | object | — | Key/value metadata (not populated in v1). |
Fetch Objects by Id — POST /objects/list
Resolve specific elementIds to objects. Per-element batch result.
// request
{ "elementIds": ["1a0d…", "c91a…"], "includeMetadata": false }
// response
{
"success": true,
"results": [
{ "success": true, "elementId": "1a0d…", "result": { "elementId": "1a0d…", "displayName": "Vintecc", "typeElementId": "enterprise", "isComposition": true, "isExtended": false } }
]
}
Related Objects — POST /objects/related
Navigate the hierarchy from one or more objects. This is how you browse the tree in i3X.
// request
{ "elementIds": ["8b2e…"], "relationshipType": "HasChildren", "includeMetadata": false }
| Field | Type | Notes |
|---|---|---|
elementIds | string[] | Objects to navigate from. |
relationshipType | string | null | Direction to follow. Omit/null to return both children and parent. See below. |
includeMetadata | bool | Accepted; metadata is not populated in v1. |
Accepted relationshipType values: HasChildren / HasComponent (descend to direct children, capped at 1000) and HasParent / ComponentOf (ascend to the parent).
// response — each related object plus the relationship by which it was reached
{
"success": true,
"results": [
{
"success": true,
"elementId": "8b2e…",
"result": [
{ "sourceRelationship": "HasChildren", "object": { "elementId": "c91a…", "displayName": "Temperature", "typeElementId": "variable", "isComposition": false, "isExtended": false } }
]
}
]
}
Object Types
GET /objecttypes lists the implicit object types — one per distinct UNS node-type string in your company tree (e.g. enterprise, line, variable). POST /objecttypes/query resolves specific type ids (batch).
{
"success": true,
"result": [
{ "elementId": "variable", "displayName": "variable", "namespaceUri": "urn:capture:uns", "sourceTypeId": "variable", "schema": { "type": "number" } },
{ "elementId": "line", "displayName": "line", "namespaceUri": "urn:capture:uns", "sourceTypeId": "line", "schema": { "type": "object" } }
]
}
The type elementId is the UNS node-type string.
Relationship Types
GET /relationshiptypes lists the built-in relationship types; POST /relationshiptypes/query resolves specific ones (batch). v1 serves the four hierarchy/composition built-ins:
| elementId | displayName | reverseOf |
|---|---|---|
HasParent | Has Parent | HasChildren |
HasChildren | Has Children | HasParent |
HasComponent | Has Component | ComponentOf |
ComponentOf | Component Of | HasComponent |
All sit in the i3X core namespace https://cesmii.org/i3x.
Reading values — POST /objects/value
Current value(s) for the given elementIds. A leaf returns a scalar value; a composition returns its descendant-variable values under components (only when maxDepth > 1).
// request
{ "elementIds": ["c91a…", "8b2e…"], "maxDepth": 2 }
// response
{
"success": true,
"results": [
{
"success": true,
"elementId": "c91a…",
"result": { "isComposition": false, "value": 23.5, "quality": "Good", "timestamp": "2026-06-29T08:00:00.0000000Z" }
},
{
"success": true,
"elementId": "8b2e…",
"result": {
"isComposition": true,
"quality": "GoodNoData",
"components": {
"c91a…": { "value": 23.5, "quality": "Good", "timestamp": "2026-06-29T08:00:00.0000000Z" },
"d72b…": { "value": 1.2, "quality": "Good", "timestamp": "2026-06-29T08:00:00.0000000Z" }
}
}
}
]
}
| Field | Type | Notes |
|---|---|---|
value | number | string | — | Omitted when there is no data. |
quality | string | Good when a value is present, else GoodNoData. (Capture does not surface Bad/Uncertain.) |
timestamp | string | — | RFC 3339 UTC; omitted when there is no data. |
components | object | — | Present only for compositions with maxDepth > 1. |
History — POST /objects/history
Historical value series over the half-open window [startTime, endTime) (endTime exclusive). A leaf returns a values series; a composition returns descendant-variable series under components (only when maxDepth > 1).
// request
{ "elementIds": ["c91a…"], "startTime": "2026-06-29T00:00:00Z", "endTime": "2026-06-30T00:00:00Z", "maxDepth": 1 }
// response
{
"success": true,
"results": [
{
"success": true,
"elementId": "c91a…",
"result": {
"isComposition": false,
"values": [
{ "value": 23.5, "quality": "Good", "timestamp": "2026-06-29T08:00:00.0000000Z" },
{ "value": 23.7, "quality": "Good", "timestamp": "2026-06-29T08:00:10.0000000Z" }
]
}
}
]
}
Each series is capped at 5000 points per request and is not paged — points beyond the cap are silently dropped. For full or paged history (and for aggregated history, which i3X does not offer), use the native UNS Read API. i3X history is best for modest windows.
startTime/endTime are required and endTime must be after startTime, otherwise the call returns 422.
Subscriptions (poll-sync)
i3X delivers value changes by polling, not streaming. The lifecycle is create → register objects → sync (repeatedly) → unregister / delete. All subscriptions are owned by the caller's company; another company's subscription id resolves to "Subscription not found".
| Endpoint | Purpose |
|---|---|
POST /subscriptions | Create a subscription. Returns a subscriptionId. |
POST /subscriptions/register | Add monitored objects (elementIds, maxDepth). Per-element batch. |
POST /subscriptions/sync | Poll for values that changed since the last sync. |
POST /subscriptions/unregister | Remove monitored objects. Per-element batch (removing a non-monitored id is a no-op success). |
POST /subscriptions/list | List subscriptions (empty subscriptionIds ⇒ all of your company's). |
POST /subscriptions/delete | Delete subscriptions by id. |
Create
// request { "displayName": "My integration" }
// result { "subscriptionId": "9f3c…", "displayName": "My integration" }
Register
// request { "subscriptionId": "9f3c…", "elementIds": ["8b2e…"], "maxDepth": 2 }
Registering an asset with maxDepth > 1 monitors its descendant variables. Duplicate ids are ignored.
Sync — call repeatedly to drain new values:
// request
{ "subscriptionId": "9f3c…", "lastSequenceNumber": 41 }
// response — batches of updates, each tagged with a sequence number
{
"success": true,
"result": [
{
"sequenceNumber": 42,
"updates": [
{ "elementId": "c91a…", "value": 24.1, "quality": "Good", "timestamp": "2026-06-29T08:05:00.0000000Z" }
]
}
]
}
Sync returns only values newer than the last poll (the server tracks the last-seen timestamp per monitored variable). An empty result list means nothing changed. Carry the highest sequenceNumber you have seen forward as lastSequenceNumber on the next call.
List returns each subscription's monitored objects:
{ "success": true, "results": [ { "success": true, "subscriptionId": "9f3c…", "result": { "subscriptionId": "9f3c…", "displayName": "My integration", "monitoredObjects": [ { "elementId": "8b2e…", "maxDepth": 2 } ] } } ] }
Error responses
Top-level HTTP errors (the whole request fails):
| Status | When |
|---|---|
400 | UNS is not enabled for the company. |
401 | AuthVersion is not V0.0.1, or the token is missing/invalid/expired. |
403 | Valid token but missing Data Explorer → View on the company. |
404 | The i3X feature is disabled for this environment (every endpoint returns 404 until enabled). |
422 | History request invalid (startTime/endTime missing, or endTime <= startTime). |
500 | Connector resolution failure or any unexpected exception. |
Per-element failures in batch (POST) endpoints do not fail the request — they return 200 with success: false and a responseDetail on the individual element (see Response envelope).
Examples
# Capabilities (no auth)
curl -s "https://portal.captureplatform.com/v2/i3x/v1/info"
# Root objects of your address space
curl -s "https://portal.captureplatform.com/v2/i3x/v1/objects" \
-H "AuthVersion: V0.0.1" \
-H "Authorization: Bearer <token>"
# Browse down: direct children of an asset
curl -s "https://portal.captureplatform.com/v2/i3x/v1/objects/related" \
-H "AuthVersion: V0.0.1" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "elementIds": ["8b2e..."], "relationshipType": "HasChildren" }'
# Current value of a variable
curl -s "https://portal.captureplatform.com/v2/i3x/v1/objects/value" \
-H "AuthVersion: V0.0.1" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "elementIds": ["c91a..."], "maxDepth": 1 }'
# History of a variable over a window
curl -s "https://portal.captureplatform.com/v2/i3x/v1/objects/history" \
-H "AuthVersion: V0.0.1" \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "elementIds": ["c91a..."], "startTime": "2026-06-29T00:00:00Z", "endTime": "2026-06-30T00:00:00Z" }'