Skip to content

Messages

Port OS allows you to send messages to things. By sending messages to endpoints, customers can turn off lights, play music, etc. A message is an object that is sent around in port OS between different endpoints.

Send a message to an endpoint or group

View source specification ↗
POST /message-requests

Sends a message to an endpoint or group.

Idempotency keys are scoped to the authenticated principal and retained for 24 hours. A retry attaches to the same request and never resends an attempted command. A created request returns HTTP 200 regardless of delivery outcome.

Dispatching a message has a few different fire modes:

  1. FIRE_FORGET returns after storage.
  2. SYNC waits to completion.
  3. AUTO follows each selected plugin declaration.

The default deadline is 30 seconds and the recipient cap is 100. An error that says TIMED_OUT means the external outcome is unknown.

Required scope

message:send

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

targetobjectRequired

Exactly one explicit endpoint, group, plugin or system id, or an endpoint query. Resolution is authorized and frozen once at creation; at most 100 recipients.

message168 variantsRequired

A capability message to send to an endpoint: exactly one of the inbound capability messages. The header namespace, name and version select the variant and the body schema.

headerMessageHeaderRequired

Identifies this capability message.

bodyobjectRequired

Ask the device to report its current air quality reading.

correlationTokenstring

Token used for correlating related messages

responseTypestring

How long creation waits for the durable request. SYNC waits until every selected delivery is final; a plugin declaring FIRE_FORGET completes on its delivery acknowledgment without inventing a response message. AUTO follows each selected route's current plugin declaration. FIRE_FORGET returns after storage, before delivery completes. Omission defaults to FIRE_FORGET. A successful delivery alone does not prove physical state.

POST /message-requests: application/json request body: possible enum values for responseType
ValueMeaning
SYNC—
FIRE_FORGET—
AUTOSelect the operating mode automatically.

Returns

200

Durable request created, including its current delivery outcomes.

Fields
idstringRequired

Server assigned durable request identifier.

statusstringRequired

Allowed values

  • QUEUED
  • IN_PROGRESS
  • SUCCEEDED
  • PARTIALLY_SUCCEEDED
  • FAILED
resultsarray<MessageRequestResult>Required
targetIdstringRequired
routeIdstringRequired
message61 variants

The message that was responded with when there was a unary message response, exactly one of the outbound capability messages. A synchronous send can return one; an acknowledgment with no message back leaves this empty. The header namespace, name and version select the variant and the body schema.

headerMessageHeaderRequired

Identifies this capability message.

bodyAuthorizationInterfaceAuthorizationEstablishedMessageRequired

The authorization established message is sent to a plugin to indicate that the plugin has been installed and authorized for a principal

correlationTokenstring

Token used for correlating related messages

errorsarray<MessageRequestError>Required
targetIdstringRequired
routeIdstring
codestringRequired
POST /message-requests: 200 application/json response: possible enum values for errors[].code
ValueMeaning
REJECTED—
UNREACHABLEThe device cannot currently be reached.
NOT_ACCEPTED—
TIMED_OUT—
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.

deadlinestringRequired

Outstanding deliveries end TIMED_OUT at this deadline; their external outcome remains unknown.

format: "date-time"

syncDeadlineSecondsintegerRequired

Configured delivery deadline in seconds, visible to callers.

Default: 30

minimum: 1

maximum: 3600

Errors

400 BAD_REQUEST

Bad request.

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

403 FORBIDDEN

Forbidden.

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

422 IDEMPOTENCY_KEY_REUSED

Idempotency key reused with a different payload.

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

Get a durable message request

View source specification ↗
GET /message-requests/{id}

Returns the authenticated creator's durable message request and its current outcomes. Expired unfinished deliveries become TIMED_OUT without redispatch. To observe progress without polling, send the ETag of the last representation in If-None-Match together with a Prefer header of wait=<seconds> (at most 30). The server answers at once when the request already differs, otherwise it holds the request until the next change and returns 304 Not Modified when the wait elapses, or when the request is already final and cannot change. The client's cancellation ends the wait.

Required scope

message:send

Path parameters

idstringRequired

Server assigned durable request identifier returned by creation.

Header parameters

If-None-Matchstring

The quoted strong entity tag of the representation the client last read (its `ETag` response header). The server returns the current representation when the tag differs. When it still matches, the server answers 304 Not Modified, after waiting for a change when the `Prefer` wait preference is also sent. Exactly one strong tag is accepted; weak tags, lists and the wildcard return 400.

minLength: 1

Preferstring

RFC 7240 `wait=<seconds>` preference, hold the request open until the resource changes from the `If-None-Match` entity tag, or until the wait elapses (then 304). The server caps the wait at 30 seconds and reports the granted value in `Preference-Applied`. Without `If-None-Match` the preference is ignored and the current representation returns at once. A malformed `wait` value returns 400.

pattern: "^wait=[0-9]+$"

Returns

200

Durable message request.

Fields
idstringRequired

Server assigned durable request identifier.

statusstringRequired

Allowed values

  • QUEUED
  • IN_PROGRESS
  • SUCCEEDED
  • PARTIALLY_SUCCEEDED
  • FAILED
resultsarray<MessageRequestResult>Required
targetIdstringRequired
routeIdstringRequired
message61 variants

The message that was responded with when there was a unary message response, exactly one of the outbound capability messages. A synchronous send can return one; an acknowledgment with no message back leaves this empty. The header namespace, name and version select the variant and the body schema.

headerMessageHeaderRequired

Identifies this capability message.

bodyAuthorizationInterfaceAuthorizationEstablishedMessageRequired

The authorization established message is sent to a plugin to indicate that the plugin has been installed and authorized for a principal

correlationTokenstring

Token used for correlating related messages

errorsarray<MessageRequestError>Required
targetIdstringRequired
routeIdstring
codestringRequired
GET /message-requests/{id}: 200 application/json response: possible enum values for errors[].code
ValueMeaning
REJECTED—
UNREACHABLEThe device cannot currently be reached.
NOT_ACCEPTED—
TIMED_OUT—
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.

deadlinestringRequired

Outstanding deliveries end TIMED_OUT at this deadline; their external outcome remains unknown.

format: "date-time"

syncDeadlineSecondsintegerRequired

Configured delivery deadline in seconds, visible to callers.

Default: 30

minimum: 1

maximum: 3600

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.

Response headers
Preference-Appliedstring

RFC 7240 acknowledgement `wait=<seconds>` returned only when the server honoured the `wait` request preference. The value is the wait actually granted, after the server cap, so it can be lower than the requested value.

304

The request still matches If-None-Match after the wait, or it is final and cannot change.

No response body.

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.

Response headers
Preference-Appliedstring

RFC 7240 acknowledgement `wait=<seconds>` returned only when the server honoured the `wait` request preference. The value is the wait actually granted, after the server cap, so it can be lower than the requested value.

Errors

400 BAD_REQUEST

Malformed `If-None-Match` or `Prefer` wait value.

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

404 NOT_FOUND

Request not found.

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