control
controlControl connected devices and services, retrieve results, and capture camera snapshots.
Discover the device with endpoint_query or the room with group_query. Copy its full id, message and optional routeId; use the documented payload for the declared message. Send a matching payload ({} for a command without fields). Preserve the account that returned the IDs and clarify ambiguous targets before writes.
Most controls return status accepted: dispatch succeeded, but the physical outcome is unconfirmed. For result-returning commands, such as search, library pages and get-snapshot, set waitForResult=true. A correlated result returns status responded; snapshots also return image pixels and timeOfSample. Outbound declarations include events, so they do not guarantee that every command responds. For playback, volume and power, omit waitForResult and verify fresh state using endpoint_query or group_query with declared expand capabilities and forceDeviceAttributeQuery=true.
Use only capabilities and commands declared by the selected device or service. Examples of device classes and providers, subject to the connected integration's support:
- Lights, switches and plugs: on/off and brightness (Philips Hue, Tuya, TP-Link).
- Phones, tablets, laptops, wallets and trackers: locate or ring (Apple Find My, Tile).
- Thermostats and temperature sensors: heat/cool settings; read ambient temperature with endpoint_query (Nest, Tuya, ecobee).
- Cameras: request a declared get-snapshot command and inspect the returned pixels (Ring, Nest and other cameras). A snapshot is distinct from live video.
- Connectivity and battery: check declared observations with endpoint_query for phones, watches, locks and other devices.
- Smart locks and PINs: use declared lock and PIN commands (August, Yale, Ring, Seam).
- Home appliances: supported controls and running-state observations (Samsung, LG, Xiaomi).
- Robot vacuums: clean rooms and return to dock (Roomba, Roborock, Dreame). Send clean-room to the robot listing the room in controllableGroups with {"groupIds": [<group ID>]}. Bounded remote driving requires fresh visual feedback; cleaning is not navigation.
- Speakers and announcements: supported speech and audio playback (Sonos, Alexa, Nest cameras).
- TVs, remotes and media libraries: playback, volume, search and declared playlist operations (Spotify, Fire TV, YouTube, Chrome, TCL, Samsung, LG).
- Files and photos: declared browse, download, upload, rename, move and delete commands (iCloud Photos, iCloud Drive, Google Drive, Outlook). download-file returns a URI; catalog presence alone does not establish upload support.
- Litter robots and pet appliances: declared cleaning, waste and dispensing observations or controls.
- Water sensors and sprinklers: declared water detection, watering state and controls.
- Calendars and reminders: declared list, create, complete, reschedule and delete operations (iCloud Calendar and Reminders). Connected reminders are distinct from assistant-created scheduled tasks.
Read the relevant bundled skill reference or portos://guides/index for unfamiliar workflows. File/reminder deletion and PIN changes modify account data. Inspect partial or uncertain writes before another action. result_timeout means unknown outcome: read state before considering a retry. MESSAGE_UNSUPPORTED or MESSAGE_AMBIGUOUS means nothing was sent; correct the message from discovery. An unreachable device rejected the command. Never automatically retry a state-changing command or claim success from conflicting observations.
Use endpoint_manage/group_manage to change names, types, membership or merges.
Required scope
message:sendInput
Fields
- id
stringRequired Full Port OS endpoint ID (…/endpoints/…) from endpoint_query or group ID (…/endpoint-groups/…) from group_query.
- message
stringRequired Full message ID copied from the target's messages: <capability-interface-namespace>/messages/<message-name>, with an @<version> suffix only when the listed ID has one.
- payload
objectRequired JSON object matching the message payload schema. Use {} for messages without fields.
- routeId
string Optional provider route ID copied from the target routes. Reuse it for pause, resume and volume after playing through that provider. It must belong to id and advertise the requested message. Without it, the route declaring the most interfaces is used, then the highest route ID.
- waitForResult
boolean Wait for one correlated, schema-validated result for commands that retrieve results, such as camera snapshots, media search or library pages, when outboundMessages are declared. Playback and volume commands do not return correlated results. For power and other response-less controls omit it, then read fresh state with endpoint_query.
Errors
A failed call returns this error object as its result instead.
Fields
- 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_FOUND, BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, CONFLICT, GONE, PRECONDITION_FAILED, PRECONDITION_REQUIRED, PAYLOAD_TOO_LARGE, UNSUPPORTED_MEDIA_TYPE, UNPROCESSABLE_ENTITY, LOCKED, TOO_MANY_REQUESTS, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, NOT_IMPLEMENTED, INTERNAL_SERVER_ERROR, REQUEST_INVALID, AUTHENTICATION, PERMISSION, ENDPOINT_NOT_FOUND, ENDPOINT_STATE_CONFLICT, ENDPOINT_UNAVAILABLE, RATE_LIMIT, PROVIDER_BAD_RESPONSE, PROVIDER_UNAVAILABLE, PROVIDER_TIMEOUT.
- 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_REQUEST, UNAUTHORIZED, FORBIDDEN, INSUFFICIENT_SCOPE, NOT_FOUND, CONFLICT, UNPROCESSABLE_ENTITY, UNSUPPORTED_OPERATION, TOO_MANY_REQUESTS, SERVICE_UNAVAILABLE, NOT_IMPLEMENTED, INTERNAL, CHECKSUM_MISMATCH, FILE_TOO_LARGE, STORAGE_UNAVAILABLE, INSUFFICIENT_PERMISSIONS, INVALID_FILE_TYPE, QUOTA_EXCEEDED, CONCURRENT_MODIFICATION, ENDPOINT_UNREACHABLE, BRIDGE_UNREACHABLE, CLOUD_CONTROL_DISABLED, ENDPOINT_BUSY, ENDPOINT_LOW_POWER, AUTHORIZATION_CREDENTIAL_INVALID, AUTHORIZATION_CREDENTIAL_EXPIRED, INVALID_DIRECTIVE, INVALID_VALUE, VALUE_OUT_OF_RANGE, NOT_SUPPORTED_IN_CURRENT_MODE, RATE_LIMIT_EXCEEDED, PROVIDER_SERVICE_UNAVAILABLE, PROVIDER_TIMEOUT, PROVIDER_INTERNAL_ERROR, INVALID_PROVIDER_RESPONSE, OUTCOME_UNKNOWN, PRECONDITION_FAILED, AUTH_LINK_NOT_READY, AUTH_LINK_NOT_DISCONNECTABLE, PRECONDITION_REQUIRED, IDEMPOTENCY_KEY_REQUIRED, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_KEY_IN_FLIGHT, IDEMPOTENCY_KEY_INVALID, GROUP_MERGED, MULTI_ROOM_UNSUPPORTED, MAP_NOT_ACTIVE, TARGET_UNSUPPORTED, TARGET_AMBIGUOUS, TARGET_GROUP_NOT_FOUND, TARGET_GROUP_DISABLED, DUPLICATE_TARGET_GROUP, MESSAGE_UNSUPPORTED, MESSAGE_AMBIGUOUS, ENDPOINT_DISABLED, ENDPOINT_ROUTE_CHANGED, ENDPOINT_HAS_DEPENDENCIES, ENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVE, ENDPOINT_COMMITTED_CLEANUP_PENDING, DEEP_QUERY_FAILED, PROVIDER_NO_STATE, EVENT_MANAGEMENT_DISABLED, SUBSCRIPTION_IDENTITY_IMMUTABLE, UNSUPPORTED_MEDIA_TYPE, EVENT_PAYLOAD_TOO_LARGE, REQUEST_BODY_TOO_LARGE, EVENT_IDENTITY_CONFLICT, EVENT_INGRESS_QUOTA_EXCEEDED, EVENT_RECEIPT_EXPIRED, EVENT_STORAGE_UNAVAILABLE, EVENT_DEAD_LETTER_NOT_FOUND, EVENT_REDRIVE_CONFLICT, EVENT_REDRIVE_EXPIRED, RECEIPT_CONTEXT_EXPIRED, EVENT_MAINTENANCE_INCOMPLETE, UNKNOWN_INTERFACE, INVALID_CONFIGURATION, INVALID_ATTRIBUTE, INVALID_PROVIDER_MESSAGE, UNDECLARED_CAPABILITY, PLUGIN_ROUTE_ID_CONFLICT, UNRESOLVED_REFERENCE, INVALID_RELATIONSHIP, RELATIONSHIP_CYCLE, MULTIPLE_PARENTS, FLOW_VALIDATION_FAILED.
- details
ErrorDetails Optional typed context for an error. Fields are additive and only populated when the error can safely expose that context to API clients.
- discoveryEndpointId
string Port OS provider endpoint (type ENDPOINT_PLUGIN) of the connection to send `discover-routes` to when `code` is `TARGET_UNSUPPORTED` because the route must be rediscovered.
- retryAfterSeconds
integer Suggested retry delay for rate-limit or provider-unavailable failures.
minimum: 0
- providerCode
string The third-party provider's own error code, for support. It is opaque and provider-specific; branch on `code` and `family` instead.
- discoveryEndpointId
- errors
array<SynchronizationItemError> Every rejected item when a request that is validated item by item and applied atomically fails, such as a discovery `SynchronizationRequest` whose routes, group routes or relationships are rejected. Omitted for single-item failures.
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_REQUEST, UNAUTHORIZED, FORBIDDEN, INSUFFICIENT_SCOPE, NOT_FOUND, CONFLICT, UNPROCESSABLE_ENTITY, UNSUPPORTED_OPERATION, TOO_MANY_REQUESTS, SERVICE_UNAVAILABLE, NOT_IMPLEMENTED, INTERNAL, CHECKSUM_MISMATCH, FILE_TOO_LARGE, STORAGE_UNAVAILABLE, INSUFFICIENT_PERMISSIONS, INVALID_FILE_TYPE, QUOTA_EXCEEDED, CONCURRENT_MODIFICATION, ENDPOINT_UNREACHABLE, BRIDGE_UNREACHABLE, CLOUD_CONTROL_DISABLED, ENDPOINT_BUSY, ENDPOINT_LOW_POWER, AUTHORIZATION_CREDENTIAL_INVALID, AUTHORIZATION_CREDENTIAL_EXPIRED, INVALID_DIRECTIVE, INVALID_VALUE, VALUE_OUT_OF_RANGE, NOT_SUPPORTED_IN_CURRENT_MODE, RATE_LIMIT_EXCEEDED, PROVIDER_SERVICE_UNAVAILABLE, PROVIDER_TIMEOUT, PROVIDER_INTERNAL_ERROR, INVALID_PROVIDER_RESPONSE, OUTCOME_UNKNOWN, PRECONDITION_FAILED, AUTH_LINK_NOT_READY, AUTH_LINK_NOT_DISCONNECTABLE, PRECONDITION_REQUIRED, IDEMPOTENCY_KEY_REQUIRED, IDEMPOTENCY_KEY_REUSED, IDEMPOTENCY_KEY_IN_FLIGHT, IDEMPOTENCY_KEY_INVALID, GROUP_MERGED, MULTI_ROOM_UNSUPPORTED, MAP_NOT_ACTIVE, TARGET_UNSUPPORTED, TARGET_AMBIGUOUS, TARGET_GROUP_NOT_FOUND, TARGET_GROUP_DISABLED, DUPLICATE_TARGET_GROUP, MESSAGE_UNSUPPORTED, MESSAGE_AMBIGUOUS, ENDPOINT_DISABLED, ENDPOINT_ROUTE_CHANGED, ENDPOINT_HAS_DEPENDENCIES, ENDPOINT_EVENT_SUBSCRIPTIONS_ACTIVE, ENDPOINT_COMMITTED_CLEANUP_PENDING, DEEP_QUERY_FAILED, PROVIDER_NO_STATE, EVENT_MANAGEMENT_DISABLED, SUBSCRIPTION_IDENTITY_IMMUTABLE, UNSUPPORTED_MEDIA_TYPE, EVENT_PAYLOAD_TOO_LARGE, REQUEST_BODY_TOO_LARGE, EVENT_IDENTITY_CONFLICT, EVENT_INGRESS_QUOTA_EXCEEDED, EVENT_RECEIPT_EXPIRED, EVENT_STORAGE_UNAVAILABLE, EVENT_DEAD_LETTER_NOT_FOUND, EVENT_REDRIVE_CONFLICT, EVENT_REDRIVE_EXPIRED, RECEIPT_CONTEXT_EXPIRED, EVENT_MAINTENANCE_INCOMPLETE, UNKNOWN_INTERFACE, INVALID_CONFIGURATION, INVALID_ATTRIBUTE, INVALID_PROVIDER_MESSAGE, UNDECLARED_CAPABILITY, PLUGIN_ROUTE_ID_CONFLICT, UNRESOLVED_REFERENCE, INVALID_RELATIONSHIP, RELATIONSHIP_CYCLE, MULTIPLE_PARENTS, FLOW_VALIDATION_FAILED.
- 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_FOUND, BAD_REQUEST, UNAUTHORIZED, FORBIDDEN, CONFLICT, GONE, PRECONDITION_FAILED, PRECONDITION_REQUIRED, PAYLOAD_TOO_LARGE, UNSUPPORTED_MEDIA_TYPE, UNPROCESSABLE_ENTITY, LOCKED, TOO_MANY_REQUESTS, BAD_GATEWAY, SERVICE_UNAVAILABLE, GATEWAY_TIMEOUT, NOT_IMPLEMENTED, INTERNAL_SERVER_ERROR, REQUEST_INVALID, AUTHENTICATION, PERMISSION, ENDPOINT_NOT_FOUND, ENDPOINT_STATE_CONFLICT, ENDPOINT_UNAVAILABLE, RATE_LIMIT, PROVIDER_BAD_RESPONSE, PROVIDER_UNAVAILABLE, PROVIDER_TIMEOUT.
- pluginRouteId