Skip to content

Endpoints

An endpoint is a device or service you can act on, such as a phone, TV, lightbulb or vacuum.

Customers interact with endpoints whenever they want to control their lights or find where their phone is.

Endpoints declare a set of capabilities. These capabilities denote what functions an endpoint has. For example, an endpoint that declares the power interface can be turned on and off. Similarly, the capability tells customers they can check whether the device is on or off.

Enumerate Endpoints

View source specification ↗
GET /endpoints

List the endpoints that a customer has access to. For example, you enumerate to list the customer's lights, vacuums, or similar devices.

Endpoints contain information such as:

  1. The endpoint's name, description, and other top-level data.
  2. The capabilities the endpoint has, like power, camera, etc.
  3. The state of the endpoint.

Usage of the API is controlled by the query parameters. By default it lists enabled endpoints owned by the authenticated user. Type and serialNumber filters stay within that scope. An explicit owner can select another owner's endpoints when the caller can read them.

An exact id lookup takes precedence over the owner, type, serialNumber, and enablement filters. It can return a readable shared endpoint, including a disabled one, but still requires endpoint-read permission.

To retrieve the state of a specific endpoint, send id=<endpoint-id> together with expand=interfaces.attributes. Add forceDeviceAttributeQuery=true to refresh that state from the device before the response is returned.

Required scope

endpoint:read

Query parameters

enablementstring

Filter the results by enablement. Enablement is a customer setting that stops Port OS from using a resource without deleting it. Port OS uses it in place of deletion because it cannot delete a device on the provider's side. Defaults to ENABLED. Use DISABLED to list only disabled resources, or '*' to include both enabled and disabled resources. Looking up a resource by its exact id ignores this filter.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED
  • *
ownerstring

Filter the results by the owner of the resource. Defaults to the authenticated caller's resources when omitted. Use '~caller' to make that scope explicit. Another owner can be selected only for resources the caller can read.

idstring

The unique identifier of a specific endpoint to retrieve. When provided, this exact-ID filter takes precedence over owner, type, serialNumber and enablement filters. It can return a shared or disabled endpoint when the caller has endpoint-read permission.

typestring

Filter endpoints by their primary type

serialNumberstring

Filter endpoints by their serial number

nextTokenstring

Opaque server-issued continuation token. Repeat the same selection, page size, expansion, force-refresh setting and authenticated grant. Modified, expired or differently bound tokens return 400; restart without nextToken.

minLength: 1

maxResultsinteger

The maximum number of results to return, from 1 through 100.

minimum: 1

maximum: 100

expandarray<string>

Expand determines what data we retrieve for each endpoint. Use `interfaces.attributes` to populate each endpoint's `attributes` array so you can, for example, find their states. When omitted, the response returns only a limited set of data.

uniqueItems: true

Itemstring

Allowed values

  • interfaces.attributes
includeChildEndpointsboolean

A list returns root endpoints only: an endpoint that is part of another endpoint (for example an oven cavity of its range, which reports `parentEndpointId`) is left out so one physical device is one entry, and the parent lists its parts in `childEndpointIds`. Send `true` to list those parts too. An exact `id` lookup always returns the endpoint it names, part or not. A part whose parent the caller cannot read is still listed.

Default: false

forceDeviceAttributeQueryboolean

Forces a live device-backed attribute refresh for endpoint-state queries. This makes Port OS call into the device to get its data, if the device provider does not update the state automatically. This flag is only applied when `expand` includes `interfaces.attributes`. Send `true` to force the refresh; absent or `false` values use stored state. Invalid values, or `true` without the required expansion, return 400. A forced read asks the provider; it cannot make a provider's old sample newer. Each returned attribute carries `sampledAt` and `freshness`: treat a `STALE` value as the provider's last known reading, not the present state. When the provider answers a forced read but gives no value for a declared, requested attribute, that attribute is returned with no `value` and an `error` whose code is `PROVIDER_NO_STATE`. It is not omitted and the request does not fail; treat the state as unknown.

Returns

200

Endpoints retrieved successfully. Responses without expand=interfaces.attributes return the default shallow endpoint shape. Responses with that expansion populate deep attribute state in each endpoint's attributes array. If endpoint enumeration succeeds but one or more forced deep-query items fail, the response can include an errors array describing those partial state-refresh failures; request-level failures still use HTTP error responses.

Fields
resultsarray<Endpoint>Required
etagstringRequired

Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.

enablementstringRequired

Whether Port OS uses an endpoint or group. A disabled one is hidden from collections by default and cannot be sent device messages or targeted by them; exact authorized reads still return it. Rediscovery never changes it, so disabling is how a user hides a discovered device or room for good.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED
idstringRequired

The unique identifier for the endpoint

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

nameTypeValueRequired

The name of the endpoint

typestringRequired

The type of endpoint

interfacesarray<ApplicationInterface>Required

List of interfaces supported by the endpoint

namestringRequired

The name of the interface

versionstring

The version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported message subset. An omitted or empty list declares no supported messages.

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

Interface-specific configuration published for discovery and enumeration.

ownerIdstringRequired

The ID of the owner of the endpoint

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

parentEndpointIdstring

The endpoint this endpoint is part of, when a provider reports it as a component of another endpoint (for example a SmartThings oven cavity of its range). Derived from `IS_PART_OF` relationships between routes; when routes disagree the lowest parent endpoint ID is returned. Absent when the endpoint has no parent. Endpoint lists leave such endpoints out unless `includeChildEndpoints` is true; read one by its ID.

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

childEndpointIdsarray<string>

The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.

Itemstring

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

resourceGroupsarray<ResourceGroup>

List of associated resource groups

idstringRequired

The unique identifier for the resource group

pattern: "^port1\\.resourcegroup\\..*"

namestringRequired

The name of the resource group

ownerPrincipal
membersarray<ResourceGroupMember>

List of members in the resource group

idstringRequired

The ID of the member

typestringRequired

The type of member (principal or nested group)

Allowed values

  • PRINCIPAL
  • GROUP
resourcesarray<ResourceGroupResource>

List of resources in the resource group

idstringRequired

The ID of the resource

typestringRequired

The type of resource

Allowed values

  • ENDPOINT
  • PLUGIN
  • FLOW
  • QUERY_STREAM
permissionsarray<Permission>

List of permissions attached to the resource group

idstringRequired

The unique identifier for the permission

principalIdstringRequired

The ID of the associated principal

resourceTypestringRequired

The type of resource this permission grants access to

resourceIdstringRequired

The ID of the resource this permission grants access to

routesarray<Route>

List of associated routes

etagstringRequired

Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.

pluginProfileIdstring

Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.

minLength: 1

idstringRequired

The server-assigned, owner-scoped Port OS route identifier. Use this ID when replacing or deleting a stored route. Provider input uses the separate ProviderDiscoveredRoute schema; its id may identify an existing authorized route only. Use associatedPluginRouteId to match the stable plugin-native identity across reports.

pattern: "^port1/[^/]+/[^/]+/routes/[^/]+$"

associatedPluginIdstringRequired

The ID of the associated plugin

associatedPluginRouteIdstringRequired

The stable plugin-owned route identifier associated with this Port OS route. For synchronized plugin capability contracts and fixture parity checks, use this field to match a route from enumeration back to the discovery payload.

externalIdstringRequired

The external ID of the route given by the reporting system

associatedAuthLinkIdstringRequired

The ID of the associated auth link

associatedEndpointIdstringRequired

The ID of the associated endpoint

nameTypeValue

The name of the route as a human readable string or a localizable asset. This is either a raw string or a localizable asset reference.

interfacesarray<RouteInterface>Required

List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.

namestringRequired

The name of the interface

versionstring

the version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported inbound message subset for the declared interface version. An omitted or empty list declares no supported messages; null also declares none. A supplied array contains distinct canonical names for implemented messages.

nullable: true

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

The configuration of the interface

ontologicalTypesarray<string>Required

List of ontological types for the route. These are used mostly for customers to know what an endpoint is, like if its a lightbulb, or a speaker, etc.

pluginCustomMetadataobject

A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

attributesarray<AttributeState>

Device state attributes for this endpoint. Query responses populate this array when `GET /endpoints` is called with `expand=interfaces.attributes`; otherwise it remains the default shallow shape.

namespacestringRequired

The capability interface namespace for this attribute

namestringRequired

The name of the attribute within the namespace

retrievabilitystringRequired

Whether the serving route supports retrieving this attribute.

Allowed values

  • RETRIEVABLE
  • NOT_RETRIEVABLE
autoUpdateFrequencystringRequired

Declared frequency at which the serving route automatically updates this attribute.

Allowed values

  • REALTIME
  • MINUTES
  • HOURLY
  • DAILY
  • NEVER
errorError

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

valueobject

The attribute value payload, structure depends on the attribute schema

versionstring

Version of the capability attribute schema used for this value.

sampledAtstring

Device or provider reported sample time in UTC. Omitted when the source did not report a sample time; fetching the value does not make an unknown or old sample fresh. Compare with `freshness`, which says whether the sample is recent enough to treat as current.

format: "date-time"

freshnessstring

Whether the value is current enough to present as the device's present state. `FRESH`: the provider reported a sample within the last 30 seconds, or a forced refresh (`forceDeviceAttributeQuery=true` or `forceDeviceQuery`) read the provider during this request and the provider reported no sample time. `STALE`: the value is older than 30 seconds, came from stored state, or is a provider's own last known value. A forced refresh cannot make a provider's old sample newer: when the provider (for example a thermostat reached through a voice-assistant account) answers with the sample it already holds, the value keeps its original `sampledAt` and is `STALE`. Report the value together with `sampledAt`, never as the present reading.

Allowed values

  • FRESH
  • STALE
paginationContextPaginationContext
errorsarray<EndpointQueryResponseError>

Partial deep-query failures collected while building expanded endpoint state. This field is present only when endpoint enumeration succeeded but one or more live attribute refresh items failed; request-level failures still use HTTP error responses.

Response-level error describing a partial deep endpoint-state query failure. These errors report deep-query item failures after endpoint enumeration has succeeded; they do not replace HTTP error responses for request-level failures.

locationstringRequired

Approximate response location affected by the partial deep-query failure.

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

messagestringRequired

Human-readable failure message.

Errors

400 BAD_REQUEST

Missing or malformed endpoint query parameters

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Unauthorized - invalid or missing authentication token

Obtain a valid access token, then retry.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Upsert Endpoint

View source specification ↗
POST /endpoints

Creates an endpoint when id is omitted, or fully replaces its writable document when id names an existing endpoint. Replacements require its current If-Match. Responses are retained for exact replay for 24 hours.

Required scope

endpoint:write

Header parameters

Idempotency-KeystringRequired

Client-chosen key that makes a non-idempotent request retry-safe, following draft-ietf-httpapi-idempotency-key-header. A committed response is stored for 24 hours and replayed for the same principal, operation, key and payload. Missing key returns 400 IDEMPOTENCY_KEY_REQUIRED, a key longer than 255 characters returns 400 IDEMPOTENCY_KEY_INVALID, the same key with a different payload returns 422, and the same key while the first request is still in flight returns 409. Requests rolled back before external provider attempts do not consume the key. Group mutations retain terminal failed responses after provider attempts together with received provider truth; their operation contract defines these replayable outcomes.

minLength: 1

maxLength: 255

If-Matchstring

Required for a full replacement when the request identifies an existing resource. Send that resource's quoted strong etag from its last GET. A missing condition on a replacement returns 428 PRECONDITION_REQUIRED; a stale condition returns 412 PRECONDITION_FAILED. Omit this header when creating a new resource without an id. Wildcards are accepted only where the operation explicitly permits them.

minLength: 1

Request body

Required

Fields

idstring

Existing endpoint to replace. Omit on create; the server assigns the ID.

minLength: 1

nameTypeValueRequired
typestringRequired

The endpoint type

enablementstringRequired

Whether Port OS uses an endpoint or group. A disabled one is hidden from collections by default and cannot be sent device messages or targeted by them; exact authorized reads still return it. Rediscovery never changes it, so disabling is how a user hides a discovered device or room for good.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED

Returns

200

Endpoint stored successfully.

Fields
etagstringRequired

Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.

enablementstringRequired

Whether Port OS uses an endpoint or group. A disabled one is hidden from collections by default and cannot be sent device messages or targeted by them; exact authorized reads still return it. Rediscovery never changes it, so disabling is how a user hides a discovered device or room for good.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED
idstringRequired

The unique identifier for the endpoint

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

nameTypeValueRequired

The name of the endpoint

typestringRequired

The type of endpoint

interfacesarray<ApplicationInterface>Required

List of interfaces supported by the endpoint

namestringRequired

The name of the interface

versionstring

The version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported message subset. An omitted or empty list declares no supported messages.

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

Interface-specific configuration published for discovery and enumeration.

ownerIdstringRequired

The ID of the owner of the endpoint

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

parentEndpointIdstring

The endpoint this endpoint is part of, when a provider reports it as a component of another endpoint (for example a SmartThings oven cavity of its range). Derived from `IS_PART_OF` relationships between routes; when routes disagree the lowest parent endpoint ID is returned. Absent when the endpoint has no parent. Endpoint lists leave such endpoints out unless `includeChildEndpoints` is true; read one by its ID.

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

childEndpointIdsarray<string>

The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.

Itemstring

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

resourceGroupsarray<ResourceGroup>

List of associated resource groups

idstringRequired

The unique identifier for the resource group

pattern: "^port1\\.resourcegroup\\..*"

namestringRequired

The name of the resource group

ownerPrincipal
membersarray<ResourceGroupMember>

List of members in the resource group

idstringRequired

The ID of the member

typestringRequired

The type of member (principal or nested group)

Allowed values

  • PRINCIPAL
  • GROUP
resourcesarray<ResourceGroupResource>

List of resources in the resource group

idstringRequired

The ID of the resource

typestringRequired

The type of resource

Allowed values

  • ENDPOINT
  • PLUGIN
  • FLOW
  • QUERY_STREAM
permissionsarray<Permission>

List of permissions attached to the resource group

idstringRequired

The unique identifier for the permission

principalIdstringRequired

The ID of the associated principal

resourceTypestringRequired

The type of resource this permission grants access to

resourceIdstringRequired

The ID of the resource this permission grants access to

routesarray<Route>

List of associated routes

etagstringRequired

Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.

pluginProfileIdstring

Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.

minLength: 1

idstringRequired

The server-assigned, owner-scoped Port OS route identifier. Use this ID when replacing or deleting a stored route. Provider input uses the separate ProviderDiscoveredRoute schema; its id may identify an existing authorized route only. Use associatedPluginRouteId to match the stable plugin-native identity across reports.

pattern: "^port1/[^/]+/[^/]+/routes/[^/]+$"

associatedPluginIdstringRequired

The ID of the associated plugin

associatedPluginRouteIdstringRequired

The stable plugin-owned route identifier associated with this Port OS route. For synchronized plugin capability contracts and fixture parity checks, use this field to match a route from enumeration back to the discovery payload.

externalIdstringRequired

The external ID of the route given by the reporting system

associatedAuthLinkIdstringRequired

The ID of the associated auth link

associatedEndpointIdstringRequired

The ID of the associated endpoint

nameTypeValue

The name of the route as a human readable string or a localizable asset. This is either a raw string or a localizable asset reference.

interfacesarray<RouteInterface>Required

List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.

namestringRequired

The name of the interface

versionstring

the version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported inbound message subset for the declared interface version. An omitted or empty list declares no supported messages; null also declares none. A supplied array contains distinct canonical names for implemented messages.

nullable: true

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

The configuration of the interface

ontologicalTypesarray<string>Required

List of ontological types for the route. These are used mostly for customers to know what an endpoint is, like if its a lightbulb, or a speaker, etc.

pluginCustomMetadataobject

A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

attributesarray<AttributeState>

Device state attributes for this endpoint. Query responses populate this array when `GET /endpoints` is called with `expand=interfaces.attributes`; otherwise it remains the default shallow shape.

namespacestringRequired

The capability interface namespace for this attribute

namestringRequired

The name of the attribute within the namespace

retrievabilitystringRequired

Whether the serving route supports retrieving this attribute.

Allowed values

  • RETRIEVABLE
  • NOT_RETRIEVABLE
autoUpdateFrequencystringRequired

Declared frequency at which the serving route automatically updates this attribute.

Allowed values

  • REALTIME
  • MINUTES
  • HOURLY
  • DAILY
  • NEVER
errorError

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

valueobject

The attribute value payload, structure depends on the attribute schema

versionstring

Version of the capability attribute schema used for this value.

sampledAtstring

Device or provider reported sample time in UTC. Omitted when the source did not report a sample time; fetching the value does not make an unknown or old sample fresh. Compare with `freshness`, which says whether the sample is recent enough to treat as current.

format: "date-time"

freshnessstring

Whether the value is current enough to present as the device's present state. `FRESH`: the provider reported a sample within the last 30 seconds, or a forced refresh (`forceDeviceAttributeQuery=true` or `forceDeviceQuery`) read the provider during this request and the provider reported no sample time. `STALE`: the value is older than 30 seconds, came from stored state, or is a provider's own last known value. A forced refresh cannot make a provider's old sample newer: when the provider (for example a thermostat reached through a voice-assistant account) answers with the sample it already holds, the value keeps its original `sampledAt` and is `STALE`. Report the value together with `sampledAt`, never as the present reading.

Allowed values

  • FRESH
  • STALE
Response headers
ETagstring

Opaque strong entity tag of the returned resource version. Send it back in `If-Match` on the next mutation of the same resource.

Errors

400 IDEMPOTENCY_KEY_REQUIRED

Invalid request payload

Check the request fields and any validation details, then correct the payload.

404 NOT_FOUND

The endpoint ID does not exist.

Verify the target identifier and that its endpoint or plugin route still exists.

409 IDEMPOTENCY_KEY_IN_FLIGHT

This idempotency key is in flight.

Check the device’s current mode or state. Retry only after the conflict is resolved.

412 PRECONDITION_FAILED

If-Match does not match the stored writable document.

Inspect the returned code and family and follow the error handling guide.

422 IDEMPOTENCY_KEY_REUSED

This idempotency key was used with a different payload.

Correct the rejected value using the constraints in the error details or request schema.

428 PRECONDITION_REQUIRED

A replacement requires If-Match.

Inspect the returned code and family and follow the error handling guide.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Endpoint Query

View source specification ↗
POST /endpoint-query

Return a bounded page of authorized endpoints matching the shared Query expression. An empty query and filters such as type or interfaces default to enabled endpoints owned by the caller. An explicit ownerId, groupId, or required exact id selector can include readable endpoints owned by others; endpoint-read permission is still required for each result. Collections exclude disabled endpoints unless enablement is filtered, while a query that requires specific exact endpoint IDs can return disabled endpoint metadata without an enablement filter. See the request schema for supported fields and operators. Use groupId to select members of a readable room/group, then intersect type or declared interfaces to select lights. Group predicates additionally require group:read for delegated OAuth. Repeat the complete query settings and grant when following nextToken; cursors expire after fifteen minutes. Device attributes are returned only when expanded. Report per-target command acceptance and observed state separately; querying a group does not grant permission to control its members.

Required scope

endpoint:read

When using groupId: group:read

Request body

Required

Fields

queryQueryRequired

A bounded shared Query expression. By default, an empty object and filters such as type or interfaces select enabled endpoints owned by the caller. An explicit ownerId, groupId, or required exact id selector can include readable endpoints owned by others; endpoint-read permission is still required for every result. This endpoint supports match, and, or, and not. Scalar match keys are id, name, type, ownerId, manufacturer, model, serialNumber, and enablement. interfaces matches membership in the endpoint's declared interface names; groupId matches membership in a readable endpoint group. Comparisons, patterns, freeform search, unknown keys, ambiguous nodes, expressions deeper than eight levels, or more than 64 nodes return 400. Values are exact strings. Collections exclude disabled endpoints unless the expression filters enablement. A query that requires specific exact endpoint IDs can also return disabled endpoint metadata without an enablement filter, subject to endpoint-read permission. A groupId predicate additionally requires group:read for delegated OAuth and read permission on that group.

paginationContextPaging
expandarray<string>

Optional reported state expansion; only interfaces.attributes is supported.

uniqueItems: true

Itemstring

Allowed values

  • interfaces.attributes
includeChildEndpointsboolean

A query returns root endpoints only: an endpoint that is part of another endpoint (for example an oven cavity of its range, which reports `parentEndpointId`) is left out, and the parent lists its parts in `childEndpointIds`. Send true to match those parts too. A query that selects endpoints by exact id or by groupId returns them either way. Repeat the same setting when following nextToken. A part whose parent the caller cannot read is still returned.

Default: false

forceDeviceQueryboolean

Refresh reported device attributes for the selected page. Requires expand to contain interfaces.attributes. An accepted command is not proof of device state; inspect each attribute's sampledAt and freshness and the partial errors. A provider can answer with its own last known sample, which is returned as STALE. Disabled endpoints cannot be forcibly refreshed.

Default: false

Returns

200

Endpoints retrieved successfully

Fields
resultsarray<Endpoint>Required
etagstringRequired

Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.

enablementstringRequired

Whether Port OS uses an endpoint or group. A disabled one is hidden from collections by default and cannot be sent device messages or targeted by them; exact authorized reads still return it. Rediscovery never changes it, so disabling is how a user hides a discovered device or room for good.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED
idstringRequired

The unique identifier for the endpoint

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

nameTypeValueRequired

The name of the endpoint

typestringRequired

The type of endpoint

interfacesarray<ApplicationInterface>Required

List of interfaces supported by the endpoint

namestringRequired

The name of the interface

versionstring

The version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported message subset. An omitted or empty list declares no supported messages.

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

Interface-specific configuration published for discovery and enumeration.

ownerIdstringRequired

The ID of the owner of the endpoint

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

parentEndpointIdstring

The endpoint this endpoint is part of, when a provider reports it as a component of another endpoint (for example a SmartThings oven cavity of its range). Derived from `IS_PART_OF` relationships between routes; when routes disagree the lowest parent endpoint ID is returned. Absent when the endpoint has no parent. Endpoint lists leave such endpoints out unless `includeChildEndpoints` is true; read one by its ID.

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

childEndpointIdsarray<string>

The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.

Itemstring

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

resourceGroupsarray<ResourceGroup>

List of associated resource groups

idstringRequired

The unique identifier for the resource group

pattern: "^port1\\.resourcegroup\\..*"

namestringRequired

The name of the resource group

ownerPrincipal
membersarray<ResourceGroupMember>

List of members in the resource group

idstringRequired

The ID of the member

typestringRequired

The type of member (principal or nested group)

Allowed values

  • PRINCIPAL
  • GROUP
resourcesarray<ResourceGroupResource>

List of resources in the resource group

idstringRequired

The ID of the resource

typestringRequired

The type of resource

Allowed values

  • ENDPOINT
  • PLUGIN
  • FLOW
  • QUERY_STREAM
permissionsarray<Permission>

List of permissions attached to the resource group

idstringRequired

The unique identifier for the permission

principalIdstringRequired

The ID of the associated principal

resourceTypestringRequired

The type of resource this permission grants access to

resourceIdstringRequired

The ID of the resource this permission grants access to

routesarray<Route>

List of associated routes

etagstringRequired

Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.

pluginProfileIdstring

Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.

minLength: 1

idstringRequired

The server-assigned, owner-scoped Port OS route identifier. Use this ID when replacing or deleting a stored route. Provider input uses the separate ProviderDiscoveredRoute schema; its id may identify an existing authorized route only. Use associatedPluginRouteId to match the stable plugin-native identity across reports.

pattern: "^port1/[^/]+/[^/]+/routes/[^/]+$"

associatedPluginIdstringRequired

The ID of the associated plugin

associatedPluginRouteIdstringRequired

The stable plugin-owned route identifier associated with this Port OS route. For synchronized plugin capability contracts and fixture parity checks, use this field to match a route from enumeration back to the discovery payload.

externalIdstringRequired

The external ID of the route given by the reporting system

associatedAuthLinkIdstringRequired

The ID of the associated auth link

associatedEndpointIdstringRequired

The ID of the associated endpoint

nameTypeValue

The name of the route as a human readable string or a localizable asset. This is either a raw string or a localizable asset reference.

interfacesarray<RouteInterface>Required

List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.

namestringRequired

The name of the interface

versionstring

the version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported inbound message subset for the declared interface version. An omitted or empty list declares no supported messages; null also declares none. A supplied array contains distinct canonical names for implemented messages.

nullable: true

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

The configuration of the interface

ontologicalTypesarray<string>Required

List of ontological types for the route. These are used mostly for customers to know what an endpoint is, like if its a lightbulb, or a speaker, etc.

pluginCustomMetadataobject

A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

attributesarray<AttributeState>

Device state attributes for this endpoint. Query responses populate this array when `GET /endpoints` is called with `expand=interfaces.attributes`; otherwise it remains the default shallow shape.

namespacestringRequired

The capability interface namespace for this attribute

namestringRequired

The name of the attribute within the namespace

retrievabilitystringRequired

Whether the serving route supports retrieving this attribute.

Allowed values

  • RETRIEVABLE
  • NOT_RETRIEVABLE
autoUpdateFrequencystringRequired

Declared frequency at which the serving route automatically updates this attribute.

Allowed values

  • REALTIME
  • MINUTES
  • HOURLY
  • DAILY
  • NEVER
errorError

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

valueobject

The attribute value payload, structure depends on the attribute schema

versionstring

Version of the capability attribute schema used for this value.

sampledAtstring

Device or provider reported sample time in UTC. Omitted when the source did not report a sample time; fetching the value does not make an unknown or old sample fresh. Compare with `freshness`, which says whether the sample is recent enough to treat as current.

format: "date-time"

freshnessstring

Whether the value is current enough to present as the device's present state. `FRESH`: the provider reported a sample within the last 30 seconds, or a forced refresh (`forceDeviceAttributeQuery=true` or `forceDeviceQuery`) read the provider during this request and the provider reported no sample time. `STALE`: the value is older than 30 seconds, came from stored state, or is a provider's own last known value. A forced refresh cannot make a provider's old sample newer: when the provider (for example a thermostat reached through a voice-assistant account) answers with the sample it already holds, the value keeps its original `sampledAt` and is `STALE`. Report the value together with `sampledAt`, never as the present reading.

Allowed values

  • FRESH
  • STALE
paginationContextPaginationContext
errorsarray<EndpointQueryResponseError>

Partial deep-query failures collected while building expanded endpoint state. This field is present only when endpoint enumeration succeeded but one or more live attribute refresh items failed; request-level failures still use HTTP error responses.

Response-level error describing a partial deep endpoint-state query failure. These errors report deep-query item failures after endpoint enumeration has succeeded; they do not replace HTTP error responses for request-level failures.

locationstringRequired

Approximate response location affected by the partial deep-query failure.

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

messagestringRequired

Human-readable failure message.

Errors

400 BAD_REQUEST

Invalid query, unsupported expansion, or invalid/expired/mismatched cursor.

Check the request fields and any validation details, then correct the payload.

401 UNAUTHORIZED

Unauthorized - invalid or missing authentication token

Obtain a valid access token, then retry.

403 FORBIDDEN

Missing conditional OAuth scope or permission to read a referenced group.

Check the linked account and its permissions for the device or resource.

404 NOT_FOUND

A referenced group does not exist.

Verify the target identifier and that its endpoint or plugin route still exists.

409 ENDPOINT_DISABLED

A selected disabled endpoint cannot be forcibly refreshed.

Check the device’s current mode or state. Retry only after the conflict is resolved.

500 INTERNAL

Internal server error

Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.

Get Endpoint

View source specification ↗
GET /endpoints/{id}

Read one authorized endpoint with its persisted writable-document etag and current effective metadata.

Required scope

endpoint:read

Path parameters

idstringRequired

URL-encoded complete endpoint identifier.

Returns

200

Endpoint retrieved.

Fields
etagstringRequired

Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.

enablementstringRequired

Whether Port OS uses an endpoint or group. A disabled one is hidden from collections by default and cannot be sent device messages or targeted by them; exact authorized reads still return it. Rediscovery never changes it, so disabling is how a user hides a discovered device or room for good.

Default: ENABLED

Allowed values

  • ENABLED
  • DISABLED
idstringRequired

The unique identifier for the endpoint

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

nameTypeValueRequired

The name of the endpoint

typestringRequired

The type of endpoint

interfacesarray<ApplicationInterface>Required

List of interfaces supported by the endpoint

namestringRequired

The name of the interface

versionstring

The version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported message subset. An omitted or empty list declares no supported messages.

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

Interface-specific configuration published for discovery and enumeration.

ownerIdstringRequired

The ID of the owner of the endpoint

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

parentEndpointIdstring

The endpoint this endpoint is part of, when a provider reports it as a component of another endpoint (for example a SmartThings oven cavity of its range). Derived from `IS_PART_OF` relationships between routes; when routes disagree the lowest parent endpoint ID is returned. Absent when the endpoint has no parent. Endpoint lists leave such endpoints out unless `includeChildEndpoints` is true; read one by its ID.

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

childEndpointIdsarray<string>

The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.

Itemstring

pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"

resourceGroupsarray<ResourceGroup>

List of associated resource groups

idstringRequired

The unique identifier for the resource group

pattern: "^port1\\.resourcegroup\\..*"

namestringRequired

The name of the resource group

ownerPrincipal
membersarray<ResourceGroupMember>

List of members in the resource group

idstringRequired

The ID of the member

typestringRequired

The type of member (principal or nested group)

Allowed values

  • PRINCIPAL
  • GROUP
resourcesarray<ResourceGroupResource>

List of resources in the resource group

idstringRequired

The ID of the resource

typestringRequired

The type of resource

Allowed values

  • ENDPOINT
  • PLUGIN
  • FLOW
  • QUERY_STREAM
permissionsarray<Permission>

List of permissions attached to the resource group

idstringRequired

The unique identifier for the permission

principalIdstringRequired

The ID of the associated principal

resourceTypestringRequired

The type of resource this permission grants access to

resourceIdstringRequired

The ID of the resource this permission grants access to

routesarray<Route>

List of associated routes

etagstringRequired

Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.

pluginProfileIdstring

Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.

minLength: 1

idstringRequired

The server-assigned, owner-scoped Port OS route identifier. Use this ID when replacing or deleting a stored route. Provider input uses the separate ProviderDiscoveredRoute schema; its id may identify an existing authorized route only. Use associatedPluginRouteId to match the stable plugin-native identity across reports.

pattern: "^port1/[^/]+/[^/]+/routes/[^/]+$"

associatedPluginIdstringRequired

The ID of the associated plugin

associatedPluginRouteIdstringRequired

The stable plugin-owned route identifier associated with this Port OS route. For synchronized plugin capability contracts and fixture parity checks, use this field to match a route from enumeration back to the discovery payload.

externalIdstringRequired

The external ID of the route given by the reporting system

associatedAuthLinkIdstringRequired

The ID of the associated auth link

associatedEndpointIdstringRequired

The ID of the associated endpoint

nameTypeValue

The name of the route as a human readable string or a localizable asset. This is either a raw string or a localizable asset reference.

interfacesarray<RouteInterface>Required

List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.

namestringRequired

The name of the interface

versionstring

the version of the interface

messagesarray<ApplicationInterfaceMessage>

Supported inbound message subset for the declared interface version. An omitted or empty list declares no supported messages; null also declares none. A supplied array contains distinct canonical names for implemented messages.

nullable: true

namestringRequired

The name of the command

attributesarray<ApplicationInterfaceAttribute>

Supported attribute subset. An omitted or empty list declares no supported attributes.

namestringRequired

The name of the attribute

valueobject

the value of the attribute, this is an opaque resource object, so it can be any type of struct.

configurationobject

The configuration of the interface

ontologicalTypesarray<string>Required

List of ontological types for the route. These are used mostly for customers to know what an endpoint is, like if its a lightbulb, or a speaker, etc.

pluginCustomMetadataobject

A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.

descriptionTypeValue

The description of the route as a human readable string or a localizable asset.

manufacturerTypeValue

The manufacturer of the route as a human readable string or a localizable asset.

modelTypeValue

The model of the route as a human readable string or a localizable asset.

serialNumberTypeValue

The serial number of the route as a human readable string or a localizable asset.

attributesarray<AttributeState>

Device state attributes for this endpoint. Query responses populate this array when `GET /endpoints` is called with `expand=interfaces.attributes`; otherwise it remains the default shallow shape.

namespacestringRequired

The capability interface namespace for this attribute

namestringRequired

The name of the attribute within the namespace

retrievabilitystringRequired

Whether the serving route supports retrieving this attribute.

Allowed values

  • RETRIEVABLE
  • NOT_RETRIEVABLE
autoUpdateFrequencystringRequired

Declared frequency at which the serving route automatically updates this attribute.

Allowed values

  • REALTIME
  • MINUTES
  • HOURLY
  • DAILY
  • NEVER
errorError

The one Port OS error shape, returned by every REST error response and every MCP tool error. `code` names the specific failure and `family` its broad class; both are closed enums, so clients branch on them and show `message`, which says what failed and what to do next.

valueobject

The attribute value payload, structure depends on the attribute schema

versionstring

Version of the capability attribute schema used for this value.

sampledAtstring

Device or provider reported sample time in UTC. Omitted when the source did not report a sample time; fetching the value does not make an unknown or old sample fresh. Compare with `freshness`, which says whether the sample is recent enough to treat as current.

format: "date-time"

freshnessstring

Whether the value is current enough to present as the device's present state. `FRESH`: the provider reported a sample within the last 30 seconds, or a forced refresh (`forceDeviceAttributeQuery=true` or `forceDeviceQuery`) read the provider during this request and the provider reported no sample time. `STALE`: the value is older than 30 seconds, came from stored state, or is a provider's own last known value. A forced refresh cannot make a provider's old sample newer: when the provider (for example a thermostat reached through a voice-assistant account) answers with the sample it already holds, the value keeps its original `sampledAt` and is `STALE`. Report the value together with `sampledAt`, never as the present reading.

Allowed values

  • FRESH
  • STALE
Response headers
ETagstring

Opaque strong entity tag of the returned resource version. Send it back in `If-Match` on the next mutation of the same resource.

Errors

404 NOT_FOUND

Endpoint not found.

Verify the target identifier and that its endpoint or plugin route still exists.

Delete Endpoint

View source specification ↗
DELETE /endpoints/{id}

Deletes an existing endpoint and its owned associations atomically. Receipts are retained for 24 hours.

Required scope

endpoint:write

Path parameters

idstringRequired

URL-encoded complete endpoint identifier.

Header parameters

Idempotency-KeystringRequired

Client-chosen key that makes a non-idempotent request retry-safe, following draft-ietf-httpapi-idempotency-key-header. A committed response is stored for 24 hours and replayed for the same principal, operation, key and payload. Missing key returns 400 IDEMPOTENCY_KEY_REQUIRED, a key longer than 255 characters returns 400 IDEMPOTENCY_KEY_INVALID, the same key with a different payload returns 422, and the same key while the first request is still in flight returns 409. Requests rolled back before external provider attempts do not consume the key. Group mutations retain terminal failed responses after provider attempts together with received provider truth; their operation contract defines these replayable outcomes.

minLength: 1

maxLength: 255

If-MatchstringRequired

The quoted strong entity tag of the resource the client last read (its `etag` field or `ETag` response header). The mutation is applied only when it still matches: a stale value returns 412 PRECONDITION_FAILED and a missing header returns 428 PRECONDITION_REQUIRED. Wildcards are accepted only where the operation explicitly permits them.

minLength: 1

Returns

200

Endpoint deleted.

No response body.

Errors

400 IDEMPOTENCY_KEY_REQUIRED

Invalid or missing Idempotency-Key, or a request body was supplied.

Check the request fields and any validation details, then correct the payload.

404 NOT_FOUND

Endpoint not found.

Verify the target identifier and that its endpoint or plugin route still exists.

409 IDEMPOTENCY_KEY_IN_FLIGHT

Idempotency key in flight.

Check the device’s current mode or state. Retry only after the conflict is resolved.

412 PRECONDITION_FAILED

Stale If-Match.

Inspect the returned code and family and follow the error handling guide.

422 IDEMPOTENCY_KEY_REUSED

Idempotency key payload conflict.

Correct the rejected value using the constraints in the error details or request schema.

428 PRECONDITION_REQUIRED

Missing If-Match.

Inspect the returned code and family and follow the error handling guide.

Manage Endpoints

View source specification ↗
POST /endpoints-manage

Atomically merges endpoints and their references. Every operation names the source and target starting etags. All operations use the versions at the start of the batch; each affected endpoint advances once at commit. If any operation fails, all operations roll back. Responses are retained for 24 hours.

Required scope

endpoint:write

Header parameters

Idempotency-KeystringRequired

Client-chosen key that makes a non-idempotent request retry-safe, following draft-ietf-httpapi-idempotency-key-header. A committed response is stored for 24 hours and replayed for the same principal, operation, key and payload. Missing key returns 400 IDEMPOTENCY_KEY_REQUIRED, a key longer than 255 characters returns 400 IDEMPOTENCY_KEY_INVALID, the same key with a different payload returns 422, and the same key while the first request is still in flight returns 409. Requests rolled back before external provider attempts do not consume the key. Group mutations retain terminal failed responses after provider attempts together with received provider truth; their operation contract defines these replayable outcomes.

minLength: 1

maxLength: 255

Request body

Required

Fields

operationsarray<EndpointManageOperation>Required

One caller-correlated endpoint merge in an atomic management batch.

requestIdstringRequired

Client-chosen identifier for one operation in a batch request. It must be unique within the request and is echoed in the matching result or error so items are correlated by ID, never by position.

minLength: 1

maxLength: 64

mergeEndpointMergeRequired

Source and target identities with their versions observed at the start of the atomic merge batch.

Returns

200

Per-operation results and errors. Any error means no changes committed.

Fields
statusstringRequired

COMMITTED means all customer operations applied. PARTIALLY_SUCCEEDED means they applied with a reported provider fallback. FAILED means customer intent did not commit; operation-specific contracts state whether already received provider observations are retained.

Allowed values

  • COMMITTED
  • FAILED
  • PARTIALLY_SUCCEEDED
resultsarray<EndpointManageResult>Required

The stored target endpoint for one committed, caller-correlated merge operation.

requestIdstringRequired

Client-chosen identifier for one operation in a batch request. It must be unique within the request and is echoed in the matching result or error so items are correlated by ID, never by position.

minLength: 1

maxLength: 64

endpointEndpointRequired
errorsarray<BatchItemError>Required

Error for one operation of an atomic batch, correlated by the operation's `requestId`. `status` is the HTTP status the operation would have returned on its own.

requestIdstringRequired

Client-chosen identifier for one operation in a batch request. It must be unique within the request and is echoed in the matching result or error so items are correlated by ID, never by position.

minLength: 1

maxLength: 64

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

statusintegerRequired

HTTP-equivalent status code of the item failure.

minimum: 400

maximum: 599

messagestringRequired

Plain-language description of the failure and the suggested next action.

resourceIdstring

The resource the failure applies to, when it is not the operation's primary target.

errorsarray<SynchronizationItemError>

Typed validation failures inside this operation when one report contains several rejected routes, interfaces or relationships.

One rejected discovery item of a `SynchronizationRequest`, keyed by the plugin-owned identity of the rejected item: `pluginRouteId` for a route or group route, or `relationshipExternalId` for a relationship. Exactly one of the two is set. It shares the `code`, `family`, `status` and `message` fields of `BatchItemError`; discovery items are keyed by plugin-owned identity because they carry no `requestId`. A request with any rejected item is rejected as a whole and lists every rejected item.

pluginRouteIdstring

Plugin-owned identifier of the rejected route or group route. Set unless the item is a relationship.

relationshipExternalIdstring

Plugin-owned `externalId` of the rejected relationship. Set only for relationship items.

interfacestring

Canonical capability interface name the failure applies to, when the failure is interface-specific.

versionstring

Declared capability interface version the failure applies to, when the failure is interface-specific.

codestringRequired

The specific error, one of a closed set of Port OS codes. Every REST error body, MCP tool error, batch item error and discovery item error uses this enum; each code belongs to an `ErrorFamily` that decides its HTTP status. Provider-specific codes are never codes: they travel in `details.providerCode`. New failure kinds are added here, never as free strings.

familystringRequired

The broad class of an error. The family decides the HTTP status of a REST error, so clients can handle every code of a family alike.

statusintegerRequired

HTTP-equivalent status code of the item failure.

minimum: 400

maximum: 599

messagestringRequired

Plain-language description of the failure and the suggested fix.

Errors

400 IDEMPOTENCY_KEY_REQUIRED

Invalid request or missing Idempotency-Key.

Check the request fields and any validation details, then correct the payload.

409 IDEMPOTENCY_KEY_IN_FLIGHT

Idempotency key in flight.

Check the device’s current mode or state. Retry only after the conflict is resolved.

422 IDEMPOTENCY_KEY_REUSED

Idempotency key payload conflict.

Correct the rejected value using the constraints in the error details or request schema.