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.
/endpointsList 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:
- The endpoint's name, description, and other top-level data.
- The capabilities the endpoint has, like power, camera, etc.
- 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:readQuery parameters
- enablement
string 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:
ENABLEDAllowed values
ENABLEDDISABLED*
- owner
string 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.
- id
string 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.
- nextToken
string 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
- expand
array<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
- includeChildEndpoints
boolean 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- forceDeviceAttributeQuery
boolean 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
- results
array<Endpoint>Required - etag
stringRequired Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.
- enablement
stringRequired 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:
ENABLEDAllowed values
ENABLEDDISABLED
- id
stringRequired The unique identifier for the endpoint
pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"
- manufacturer
TypeValue The manufacturer of the route as a human readable string or a localizable asset.
- serialNumber
TypeValue The serial number of the route as a human readable string or a localizable asset.
- parentEndpointId
string 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/[^/]+$"
- childEndpointIds
array<string> The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.
- resourceGroups
array<ResourceGroup> List of associated resource groups
- permissions
array<Permission> List of permissions attached to the resource group
- resourceType
stringRequired The type of resource this permission grants access to
Allowed values
flowsflownodesflowportsflowlinksflow-runsprincipalssystemsaccountsaccess-control-rulestokenssecretsauth-linksoauth-clientspluginsendpointsendpoint-simulatorsendpoint-groupsvirtual-endpoint-groupsendpoint-group-routesroutesdevice-interfacesapplication-interfacesmessagessubscriptionsplugin-subscriptionviews
- resourceType
- permissions
- routes
array<Route> List of associated routes
- etag
stringRequired Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.
- pluginProfileId
string Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.
minLength: 1
- id
stringRequired 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/[^/]+$"
- associatedPluginRouteId
stringRequired 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.
- name
TypeValue 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.
- interfaces
array<RouteInterface>Required List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.
- ontologicalTypes
array<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.
- pluginCustomMetadata
object A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.
- etag
- attributes
array<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.
- retrievability
stringRequired Whether the serving route supports retrieving this attribute.
Allowed values
RETRIEVABLENOT_RETRIEVABLE
- autoUpdateFrequency
stringRequired Declared frequency at which the serving route automatically updates this attribute.
Allowed values
REALTIMEMINUTESHOURLYDAILYNEVER
- error
Error 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.
- sampledAt
string 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"
- freshness
string 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
FRESHSTALE
- retrievability
- etag
- errors
array<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.
- code
stringRequired 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.
Allowed values
BAD_REQUESTUNAUTHORIZEDFORBIDDENINSUFFICIENT_SCOPENOT_FOUNDCONFLICTUNPROCESSABLE_ENTITYUNSUPPORTED_OPERATIONTOO_MANY_REQUESTSSERVICE_UNAVAILABLENOT_IMPLEMENTEDINTERNALCHECKSUM_MISMATCHFILE_TOO_LARGESTORAGE_UNAVAILABLEINSUFFICIENT_PERMISSIONSINVALID_FILE_TYPEQUOTA_EXCEEDEDCONCURRENT_MODIFICATIONENDPOINT_UNREACHABLEBRIDGE_UNREACHABLECLOUD_CONTROL_DISABLEDENDPOINT_BUSYENDPOINT_LOW_POWERAUTHORIZATION_CREDENTIAL_INVALIDAUTHORIZATION_CREDENTIAL_EXPIREDINVALID_DIRECTIVEINVALID_VALUEVALUE_OUT_OF_RANGENOT_SUPPORTED_IN_CURRENT_MODERATE_LIMIT_EXCEEDEDPROVIDER_SERVICE_UNAVAILABLEPROVIDER_TIMEOUTPROVIDER_INTERNAL_ERRORINVALID_PROVIDER_RESPONSEOUTCOME_UNKNOWNPRECONDITION_FAILEDAUTH_LINK_NOT_READYAUTH_LINK_NOT_DISCONNECTABLEPRECONDITION_REQUIREDIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDIDEMPOTENCY_KEY_IN_FLIGHTIDEMPOTENCY_KEY_INVALIDGROUP_MERGEDMULTI_ROOM_UNSUPPORTEDMAP_NOT_ACTIVETARGET_UNSUPPORTEDTARGET_AMBIGUOUSTARGET_GROUP_NOT_FOUNDTARGET_GROUP_DISABLEDDUPLICATE_TARGET_GROUPMESSAGE_UNSUPPORTEDMESSAGE_AMBIGUOUSENDPOINT_DISABLEDENDPOINT_ROUTE_CHANGEDENDPOINT_HAS_DEPENDENCIESENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVEENDPOINT_COMMITTED_CLEANUP_PENDINGDEEP_QUERY_FAILEDPROVIDER_NO_STATEEVENT_MANAGEMENT_DISABLEDSUBSCRIPTION_IDENTITY_IMMUTABLEUNSUPPORTED_MEDIA_TYPEEVENT_PAYLOAD_TOO_LARGEREQUEST_BODY_TOO_LARGEEVENT_IDENTITY_CONFLICTEVENT_INGRESS_QUOTA_EXCEEDEDEVENT_RECEIPT_EXPIREDEVENT_STORAGE_UNAVAILABLEEVENT_DEAD_LETTER_NOT_FOUNDEVENT_REDRIVE_CONFLICTEVENT_REDRIVE_EXPIREDRECEIPT_CONTEXT_EXPIREDEVENT_MAINTENANCE_INCOMPLETEUNKNOWN_INTERFACEINVALID_CONFIGURATIONINVALID_PLUGIN_MANIFESTINVALID_ATTRIBUTEINVALID_PROVIDER_MESSAGEUNDECLARED_CAPABILITYPLUGIN_ROUTE_ID_CONFLICTUNRESOLVED_REFERENCEINVALID_RELATIONSHIPRELATIONSHIP_CYCLEMULTIPLE_PARENTSFLOW_VALIDATION_FAILEDPROVIDER_SYNC_UNSUPPORTED
- family
stringRequired 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.
Allowed values
NOT_FOUNDBAD_REQUESTUNAUTHORIZEDFORBIDDENCONFLICTGONEPRECONDITION_FAILEDPRECONDITION_REQUIREDPAYLOAD_TOO_LARGEUNSUPPORTED_MEDIA_TYPEUNPROCESSABLE_ENTITYLOCKEDTOO_MANY_REQUESTSBAD_GATEWAYSERVICE_UNAVAILABLEGATEWAY_TIMEOUTNOT_IMPLEMENTEDINTERNAL_SERVER_ERRORREQUEST_INVALIDAUTHENTICATIONPERMISSIONENDPOINT_NOT_FOUNDENDPOINT_STATE_CONFLICTENDPOINT_UNAVAILABLERATE_LIMITPROVIDER_BAD_RESPONSEPROVIDER_UNAVAILABLEPROVIDER_TIMEOUT
- code
Errors
400 BAD_REQUESTMissing or malformed endpoint query parameters
Check the request fields and any validation details, then correct the payload.
401 UNAUTHORIZEDUnauthorized - invalid or missing authentication token
Obtain a valid access token, then retry.
500 INTERNALInternal server error
Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.
/endpointsCreates 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:writeHeader parameters
- Idempotency-Key
stringRequired 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-Match
string 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
Fields
- enablement
stringRequired 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:
ENABLEDAllowed values
ENABLEDDISABLED
Returns
200
Endpoint stored successfully.
Fields
- etag
stringRequired Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.
- enablement
stringRequired 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:
ENABLEDAllowed values
ENABLEDDISABLED
- id
stringRequired The unique identifier for the endpoint
pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"
- manufacturer
TypeValue The manufacturer of the route as a human readable string or a localizable asset.
- serialNumber
TypeValue The serial number of the route as a human readable string or a localizable asset.
- parentEndpointId
string 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/[^/]+$"
- childEndpointIds
array<string> The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.
- resourceGroups
array<ResourceGroup> List of associated resource groups
- permissions
array<Permission> List of permissions attached to the resource group
- resourceType
stringRequired The type of resource this permission grants access to
Allowed values
flowsflownodesflowportsflowlinksflow-runsprincipalssystemsaccountsaccess-control-rulestokenssecretsauth-linksoauth-clientspluginsendpointsendpoint-simulatorsendpoint-groupsvirtual-endpoint-groupsendpoint-group-routesroutesdevice-interfacesapplication-interfacesmessagessubscriptionsplugin-subscriptionviews
- resourceType
- permissions
- routes
array<Route> List of associated routes
- etag
stringRequired Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.
- pluginProfileId
string Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.
minLength: 1
- id
stringRequired 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/[^/]+$"
- associatedPluginRouteId
stringRequired 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.
- name
TypeValue 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.
- interfaces
array<RouteInterface>Required List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.
- ontologicalTypes
array<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.
- pluginCustomMetadata
object A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.
- etag
- attributes
array<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.
- retrievability
stringRequired Whether the serving route supports retrieving this attribute.
Allowed values
RETRIEVABLENOT_RETRIEVABLE
- autoUpdateFrequency
stringRequired Declared frequency at which the serving route automatically updates this attribute.
Allowed values
REALTIMEMINUTESHOURLYDAILYNEVER
- error
Error 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.
- sampledAt
string 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"
- freshness
string 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
FRESHSTALE
- retrievability
Response headers
- ETag
string 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_REQUIREDInvalid request payload
Check the request fields and any validation details, then correct the payload.
404 NOT_FOUNDThe endpoint ID does not exist.
Verify the target identifier and that its endpoint or plugin route still exists.
409 IDEMPOTENCY_KEY_IN_FLIGHTThis idempotency key is in flight.
Check the device’s current mode or state. Retry only after the conflict is resolved.
412 PRECONDITION_FAILEDIf-Match does not match the stored writable document.
Inspect the returned code and family and follow the error handling guide.
422 IDEMPOTENCY_KEY_REUSEDThis idempotency key was used with a different payload.
Correct the rejected value using the constraints in the error details or request schema.
428 PRECONDITION_REQUIREDA replacement requires If-Match.
Inspect the returned code and family and follow the error handling guide.
500 INTERNALInternal server error
Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.
/endpoint-queryReturn 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:readWhen using groupId: group:read
Request body
Fields
- query
QueryRequired 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.
- expand
array<string> Optional reported state expansion; only interfaces.attributes is supported.
uniqueItems: true
- includeChildEndpoints
boolean 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- forceDeviceQuery
boolean 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
- results
array<Endpoint>Required - etag
stringRequired Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.
- enablement
stringRequired 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:
ENABLEDAllowed values
ENABLEDDISABLED
- id
stringRequired The unique identifier for the endpoint
pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"
- manufacturer
TypeValue The manufacturer of the route as a human readable string or a localizable asset.
- serialNumber
TypeValue The serial number of the route as a human readable string or a localizable asset.
- parentEndpointId
string 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/[^/]+$"
- childEndpointIds
array<string> The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.
- resourceGroups
array<ResourceGroup> List of associated resource groups
- permissions
array<Permission> List of permissions attached to the resource group
- resourceType
stringRequired The type of resource this permission grants access to
Allowed values
flowsflownodesflowportsflowlinksflow-runsprincipalssystemsaccountsaccess-control-rulestokenssecretsauth-linksoauth-clientspluginsendpointsendpoint-simulatorsendpoint-groupsvirtual-endpoint-groupsendpoint-group-routesroutesdevice-interfacesapplication-interfacesmessagessubscriptionsplugin-subscriptionviews
- resourceType
- permissions
- routes
array<Route> List of associated routes
- etag
stringRequired Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.
- pluginProfileId
string Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.
minLength: 1
- id
stringRequired 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/[^/]+$"
- associatedPluginRouteId
stringRequired 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.
- name
TypeValue 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.
- interfaces
array<RouteInterface>Required List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.
- ontologicalTypes
array<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.
- pluginCustomMetadata
object A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.
- etag
- attributes
array<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.
- retrievability
stringRequired Whether the serving route supports retrieving this attribute.
Allowed values
RETRIEVABLENOT_RETRIEVABLE
- autoUpdateFrequency
stringRequired Declared frequency at which the serving route automatically updates this attribute.
Allowed values
REALTIMEMINUTESHOURLYDAILYNEVER
- error
Error 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.
- sampledAt
string 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"
- freshness
string 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
FRESHSTALE
- retrievability
- etag
- errors
array<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.
- code
stringRequired 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.
Allowed values
BAD_REQUESTUNAUTHORIZEDFORBIDDENINSUFFICIENT_SCOPENOT_FOUNDCONFLICTUNPROCESSABLE_ENTITYUNSUPPORTED_OPERATIONTOO_MANY_REQUESTSSERVICE_UNAVAILABLENOT_IMPLEMENTEDINTERNALCHECKSUM_MISMATCHFILE_TOO_LARGESTORAGE_UNAVAILABLEINSUFFICIENT_PERMISSIONSINVALID_FILE_TYPEQUOTA_EXCEEDEDCONCURRENT_MODIFICATIONENDPOINT_UNREACHABLEBRIDGE_UNREACHABLECLOUD_CONTROL_DISABLEDENDPOINT_BUSYENDPOINT_LOW_POWERAUTHORIZATION_CREDENTIAL_INVALIDAUTHORIZATION_CREDENTIAL_EXPIREDINVALID_DIRECTIVEINVALID_VALUEVALUE_OUT_OF_RANGENOT_SUPPORTED_IN_CURRENT_MODERATE_LIMIT_EXCEEDEDPROVIDER_SERVICE_UNAVAILABLEPROVIDER_TIMEOUTPROVIDER_INTERNAL_ERRORINVALID_PROVIDER_RESPONSEOUTCOME_UNKNOWNPRECONDITION_FAILEDAUTH_LINK_NOT_READYAUTH_LINK_NOT_DISCONNECTABLEPRECONDITION_REQUIREDIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDIDEMPOTENCY_KEY_IN_FLIGHTIDEMPOTENCY_KEY_INVALIDGROUP_MERGEDMULTI_ROOM_UNSUPPORTEDMAP_NOT_ACTIVETARGET_UNSUPPORTEDTARGET_AMBIGUOUSTARGET_GROUP_NOT_FOUNDTARGET_GROUP_DISABLEDDUPLICATE_TARGET_GROUPMESSAGE_UNSUPPORTEDMESSAGE_AMBIGUOUSENDPOINT_DISABLEDENDPOINT_ROUTE_CHANGEDENDPOINT_HAS_DEPENDENCIESENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVEENDPOINT_COMMITTED_CLEANUP_PENDINGDEEP_QUERY_FAILEDPROVIDER_NO_STATEEVENT_MANAGEMENT_DISABLEDSUBSCRIPTION_IDENTITY_IMMUTABLEUNSUPPORTED_MEDIA_TYPEEVENT_PAYLOAD_TOO_LARGEREQUEST_BODY_TOO_LARGEEVENT_IDENTITY_CONFLICTEVENT_INGRESS_QUOTA_EXCEEDEDEVENT_RECEIPT_EXPIREDEVENT_STORAGE_UNAVAILABLEEVENT_DEAD_LETTER_NOT_FOUNDEVENT_REDRIVE_CONFLICTEVENT_REDRIVE_EXPIREDRECEIPT_CONTEXT_EXPIREDEVENT_MAINTENANCE_INCOMPLETEUNKNOWN_INTERFACEINVALID_CONFIGURATIONINVALID_PLUGIN_MANIFESTINVALID_ATTRIBUTEINVALID_PROVIDER_MESSAGEUNDECLARED_CAPABILITYPLUGIN_ROUTE_ID_CONFLICTUNRESOLVED_REFERENCEINVALID_RELATIONSHIPRELATIONSHIP_CYCLEMULTIPLE_PARENTSFLOW_VALIDATION_FAILEDPROVIDER_SYNC_UNSUPPORTED
- family
stringRequired 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.
Allowed values
NOT_FOUNDBAD_REQUESTUNAUTHORIZEDFORBIDDENCONFLICTGONEPRECONDITION_FAILEDPRECONDITION_REQUIREDPAYLOAD_TOO_LARGEUNSUPPORTED_MEDIA_TYPEUNPROCESSABLE_ENTITYLOCKEDTOO_MANY_REQUESTSBAD_GATEWAYSERVICE_UNAVAILABLEGATEWAY_TIMEOUTNOT_IMPLEMENTEDINTERNAL_SERVER_ERRORREQUEST_INVALIDAUTHENTICATIONPERMISSIONENDPOINT_NOT_FOUNDENDPOINT_STATE_CONFLICTENDPOINT_UNAVAILABLERATE_LIMITPROVIDER_BAD_RESPONSEPROVIDER_UNAVAILABLEPROVIDER_TIMEOUT
- code
Errors
400 BAD_REQUESTInvalid query, unsupported expansion, or invalid/expired/mismatched cursor.
Check the request fields and any validation details, then correct the payload.
401 UNAUTHORIZEDUnauthorized - invalid or missing authentication token
Obtain a valid access token, then retry.
403 FORBIDDENMissing conditional OAuth scope or permission to read a referenced group.
Check the linked account and its permissions for the device or resource.
404 NOT_FOUNDA referenced group does not exist.
Verify the target identifier and that its endpoint or plugin route still exists.
409 ENDPOINT_DISABLEDA selected disabled endpoint cannot be forcibly refreshed.
Check the device’s current mode or state. Retry only after the conflict is resolved.
500 INTERNALInternal server error
Retry with backoff only when the operation is safe to repeat. Include the error code when reporting persistent failures.
/endpoints/{id}Read one authorized endpoint with its persisted writable-document etag and current effective metadata.
Required scope
endpoint:readReturns
200
Endpoint retrieved.
Fields
- etag
stringRequired Opaque strong version of the writable endpoint document. Send it in If-Match when replacing or deleting.
- enablement
stringRequired 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:
ENABLEDAllowed values
ENABLEDDISABLED
- id
stringRequired The unique identifier for the endpoint
pattern: "^port1/[^/]+/[^/]+/endpoints/[^/]+$"
- manufacturer
TypeValue The manufacturer of the route as a human readable string or a localizable asset.
- serialNumber
TypeValue The serial number of the route as a human readable string or a localizable asset.
- parentEndpointId
string 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/[^/]+$"
- childEndpointIds
array<string> The IDs of the endpoints that are part of this endpoint, sorted. Absent when the endpoint has no children.
- resourceGroups
array<ResourceGroup> List of associated resource groups
- permissions
array<Permission> List of permissions attached to the resource group
- resourceType
stringRequired The type of resource this permission grants access to
Allowed values
flowsflownodesflowportsflowlinksflow-runsprincipalssystemsaccountsaccess-control-rulestokenssecretsauth-linksoauth-clientspluginsendpointsendpoint-simulatorsendpoint-groupsvirtual-endpoint-groupsendpoint-group-routesroutesdevice-interfacesapplication-interfacesmessagessubscriptionsplugin-subscriptionviews
- resourceType
- permissions
- routes
array<Route> List of associated routes
- etag
stringRequired Opaque strong version of the writable route document. Send in If-Match when replacing or deleting. Provider observations do not advance it.
- pluginProfileId
string Stable profile ID selected from the registered plugin declaration. Required for V2 plugin discovery; retained with the route for admission and presentation.
minLength: 1
- id
stringRequired 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/[^/]+$"
- associatedPluginRouteId
stringRequired 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.
- name
TypeValue 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.
- interfaces
array<RouteInterface>Required List of interfaces supported by the route. These denote what the route is capable of performing such as turning off/on, etc.
- ontologicalTypes
array<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.
- pluginCustomMetadata
object A set of custom metadata that the plugin uses and attaches to the route, this is meant specifically for the plugin to use.
- etag
- attributes
array<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.
- retrievability
stringRequired Whether the serving route supports retrieving this attribute.
Allowed values
RETRIEVABLENOT_RETRIEVABLE
- autoUpdateFrequency
stringRequired Declared frequency at which the serving route automatically updates this attribute.
Allowed values
REALTIMEMINUTESHOURLYDAILYNEVER
- error
Error 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.
- sampledAt
string 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"
- freshness
string 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
FRESHSTALE
- retrievability
Response headers
- ETag
string 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_FOUNDEndpoint not found.
Verify the target identifier and that its endpoint or plugin route still exists.
/endpoints/{id}Deletes an existing endpoint and its owned associations atomically. Receipts are retained for 24 hours.
Required scope
endpoint:writeHeader parameters
- Idempotency-Key
stringRequired 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-Match
stringRequired 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_REQUIREDInvalid or missing Idempotency-Key, or a request body was supplied.
Check the request fields and any validation details, then correct the payload.
404 NOT_FOUNDEndpoint not found.
Verify the target identifier and that its endpoint or plugin route still exists.
409 IDEMPOTENCY_KEY_IN_FLIGHTIdempotency key in flight.
Check the device’s current mode or state. Retry only after the conflict is resolved.
412 PRECONDITION_FAILEDStale If-Match.
Inspect the returned code and family and follow the error handling guide.
422 IDEMPOTENCY_KEY_REUSEDIdempotency key payload conflict.
Correct the rejected value using the constraints in the error details or request schema.
428 PRECONDITION_REQUIREDMissing If-Match.
Inspect the returned code and family and follow the error handling guide.
/endpoints-manageAtomically 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:writeHeader parameters
- Idempotency-Key
stringRequired 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
Returns
200
Per-operation results and errors. Any error means no changes committed.
Fields
- status
stringRequired 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
COMMITTEDFAILEDPARTIALLY_SUCCEEDED
- results
array<EndpointManageResult>Required The stored target endpoint for one committed, caller-correlated merge operation.
- errors
array<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.
- requestId
stringRequired 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
- code
stringRequired 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.
Allowed values
BAD_REQUESTUNAUTHORIZEDFORBIDDENINSUFFICIENT_SCOPENOT_FOUNDCONFLICTUNPROCESSABLE_ENTITYUNSUPPORTED_OPERATIONTOO_MANY_REQUESTSSERVICE_UNAVAILABLENOT_IMPLEMENTEDINTERNALCHECKSUM_MISMATCHFILE_TOO_LARGESTORAGE_UNAVAILABLEINSUFFICIENT_PERMISSIONSINVALID_FILE_TYPEQUOTA_EXCEEDEDCONCURRENT_MODIFICATIONENDPOINT_UNREACHABLEBRIDGE_UNREACHABLECLOUD_CONTROL_DISABLEDENDPOINT_BUSYENDPOINT_LOW_POWERAUTHORIZATION_CREDENTIAL_INVALIDAUTHORIZATION_CREDENTIAL_EXPIREDINVALID_DIRECTIVEINVALID_VALUEVALUE_OUT_OF_RANGENOT_SUPPORTED_IN_CURRENT_MODERATE_LIMIT_EXCEEDEDPROVIDER_SERVICE_UNAVAILABLEPROVIDER_TIMEOUTPROVIDER_INTERNAL_ERRORINVALID_PROVIDER_RESPONSEOUTCOME_UNKNOWNPRECONDITION_FAILEDAUTH_LINK_NOT_READYAUTH_LINK_NOT_DISCONNECTABLEPRECONDITION_REQUIREDIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDIDEMPOTENCY_KEY_IN_FLIGHTIDEMPOTENCY_KEY_INVALIDGROUP_MERGEDMULTI_ROOM_UNSUPPORTEDMAP_NOT_ACTIVETARGET_UNSUPPORTEDTARGET_AMBIGUOUSTARGET_GROUP_NOT_FOUNDTARGET_GROUP_DISABLEDDUPLICATE_TARGET_GROUPMESSAGE_UNSUPPORTEDMESSAGE_AMBIGUOUSENDPOINT_DISABLEDENDPOINT_ROUTE_CHANGEDENDPOINT_HAS_DEPENDENCIESENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVEENDPOINT_COMMITTED_CLEANUP_PENDINGDEEP_QUERY_FAILEDPROVIDER_NO_STATEEVENT_MANAGEMENT_DISABLEDSUBSCRIPTION_IDENTITY_IMMUTABLEUNSUPPORTED_MEDIA_TYPEEVENT_PAYLOAD_TOO_LARGEREQUEST_BODY_TOO_LARGEEVENT_IDENTITY_CONFLICTEVENT_INGRESS_QUOTA_EXCEEDEDEVENT_RECEIPT_EXPIREDEVENT_STORAGE_UNAVAILABLEEVENT_DEAD_LETTER_NOT_FOUNDEVENT_REDRIVE_CONFLICTEVENT_REDRIVE_EXPIREDRECEIPT_CONTEXT_EXPIREDEVENT_MAINTENANCE_INCOMPLETEUNKNOWN_INTERFACEINVALID_CONFIGURATIONINVALID_PLUGIN_MANIFESTINVALID_ATTRIBUTEINVALID_PROVIDER_MESSAGEUNDECLARED_CAPABILITYPLUGIN_ROUTE_ID_CONFLICTUNRESOLVED_REFERENCEINVALID_RELATIONSHIPRELATIONSHIP_CYCLEMULTIPLE_PARENTSFLOW_VALIDATION_FAILEDPROVIDER_SYNC_UNSUPPORTED
- family
stringRequired 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.
Allowed values
NOT_FOUNDBAD_REQUESTUNAUTHORIZEDFORBIDDENCONFLICTGONEPRECONDITION_FAILEDPRECONDITION_REQUIREDPAYLOAD_TOO_LARGEUNSUPPORTED_MEDIA_TYPEUNPROCESSABLE_ENTITYLOCKEDTOO_MANY_REQUESTSBAD_GATEWAYSERVICE_UNAVAILABLEGATEWAY_TIMEOUTNOT_IMPLEMENTEDINTERNAL_SERVER_ERRORREQUEST_INVALIDAUTHENTICATIONPERMISSIONENDPOINT_NOT_FOUNDENDPOINT_STATE_CONFLICTENDPOINT_UNAVAILABLERATE_LIMITPROVIDER_BAD_RESPONSEPROVIDER_UNAVAILABLEPROVIDER_TIMEOUT
- errors
array<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.
- pluginRouteId
string Plugin-owned identifier of the rejected route or group route. Set unless the item is a relationship.
- relationshipExternalId
string Plugin-owned `externalId` of the rejected relationship. Set only for relationship items.
- interface
string Canonical capability interface name the failure applies to, when the failure is interface-specific.
- version
string Declared capability interface version the failure applies to, when the failure is interface-specific.
- code
stringRequired 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.
Allowed values
BAD_REQUESTUNAUTHORIZEDFORBIDDENINSUFFICIENT_SCOPENOT_FOUNDCONFLICTUNPROCESSABLE_ENTITYUNSUPPORTED_OPERATIONTOO_MANY_REQUESTSSERVICE_UNAVAILABLENOT_IMPLEMENTEDINTERNALCHECKSUM_MISMATCHFILE_TOO_LARGESTORAGE_UNAVAILABLEINSUFFICIENT_PERMISSIONSINVALID_FILE_TYPEQUOTA_EXCEEDEDCONCURRENT_MODIFICATIONENDPOINT_UNREACHABLEBRIDGE_UNREACHABLECLOUD_CONTROL_DISABLEDENDPOINT_BUSYENDPOINT_LOW_POWERAUTHORIZATION_CREDENTIAL_INVALIDAUTHORIZATION_CREDENTIAL_EXPIREDINVALID_DIRECTIVEINVALID_VALUEVALUE_OUT_OF_RANGENOT_SUPPORTED_IN_CURRENT_MODERATE_LIMIT_EXCEEDEDPROVIDER_SERVICE_UNAVAILABLEPROVIDER_TIMEOUTPROVIDER_INTERNAL_ERRORINVALID_PROVIDER_RESPONSEOUTCOME_UNKNOWNPRECONDITION_FAILEDAUTH_LINK_NOT_READYAUTH_LINK_NOT_DISCONNECTABLEPRECONDITION_REQUIREDIDEMPOTENCY_KEY_REQUIREDIDEMPOTENCY_KEY_REUSEDIDEMPOTENCY_KEY_IN_FLIGHTIDEMPOTENCY_KEY_INVALIDGROUP_MERGEDMULTI_ROOM_UNSUPPORTEDMAP_NOT_ACTIVETARGET_UNSUPPORTEDTARGET_AMBIGUOUSTARGET_GROUP_NOT_FOUNDTARGET_GROUP_DISABLEDDUPLICATE_TARGET_GROUPMESSAGE_UNSUPPORTEDMESSAGE_AMBIGUOUSENDPOINT_DISABLEDENDPOINT_ROUTE_CHANGEDENDPOINT_HAS_DEPENDENCIESENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVEENDPOINT_COMMITTED_CLEANUP_PENDINGDEEP_QUERY_FAILEDPROVIDER_NO_STATEEVENT_MANAGEMENT_DISABLEDSUBSCRIPTION_IDENTITY_IMMUTABLEUNSUPPORTED_MEDIA_TYPEEVENT_PAYLOAD_TOO_LARGEREQUEST_BODY_TOO_LARGEEVENT_IDENTITY_CONFLICTEVENT_INGRESS_QUOTA_EXCEEDEDEVENT_RECEIPT_EXPIREDEVENT_STORAGE_UNAVAILABLEEVENT_DEAD_LETTER_NOT_FOUNDEVENT_REDRIVE_CONFLICTEVENT_REDRIVE_EXPIREDRECEIPT_CONTEXT_EXPIREDEVENT_MAINTENANCE_INCOMPLETEUNKNOWN_INTERFACEINVALID_CONFIGURATIONINVALID_PLUGIN_MANIFESTINVALID_ATTRIBUTEINVALID_PROVIDER_MESSAGEUNDECLARED_CAPABILITYPLUGIN_ROUTE_ID_CONFLICTUNRESOLVED_REFERENCEINVALID_RELATIONSHIPRELATIONSHIP_CYCLEMULTIPLE_PARENTSFLOW_VALIDATION_FAILEDPROVIDER_SYNC_UNSUPPORTED
- family
stringRequired 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.
Allowed values
NOT_FOUNDBAD_REQUESTUNAUTHORIZEDFORBIDDENCONFLICTGONEPRECONDITION_FAILEDPRECONDITION_REQUIREDPAYLOAD_TOO_LARGEUNSUPPORTED_MEDIA_TYPEUNPROCESSABLE_ENTITYLOCKEDTOO_MANY_REQUESTSBAD_GATEWAYSERVICE_UNAVAILABLEGATEWAY_TIMEOUTNOT_IMPLEMENTEDINTERNAL_SERVER_ERRORREQUEST_INVALIDAUTHENTICATIONPERMISSIONENDPOINT_NOT_FOUNDENDPOINT_STATE_CONFLICTENDPOINT_UNAVAILABLERATE_LIMITPROVIDER_BAD_RESPONSEPROVIDER_UNAVAILABLEPROVIDER_TIMEOUT
- pluginRouteId
- requestId
Errors
400 IDEMPOTENCY_KEY_REQUIREDInvalid request or missing Idempotency-Key.
Check the request fields and any validation details, then correct the payload.
409 IDEMPOTENCY_KEY_IN_FLIGHTIdempotency key in flight.
Check the device’s current mode or state. Retry only after the conflict is resolved.
422 IDEMPOTENCY_KEY_REUSEDIdempotency key payload conflict.
Correct the rejected value using the constraints in the error details or request schema.