Skip to content

Message Envelopes

FlowLayer V1 messages share one common JSON envelope.

{
"type": "<message_type>",
"id": "<correlation_id>",
"name": "<command_or_event_name>",
"payload": {}
}

Envelope fields are omitted when not applicable.

FieldTypeRequiredNotes
typestringAlwaysOne of command, ack, result, event, error
idstringRequired for command, ack, resultCorrelates command lifecycle; optional on error
namestringRequired for command, eventCommand or event name
payloadobjectType-dependentRequired shape depends on message type
typeDirectionPurpose
commandclient -> serverRequest an operation
ackserver -> clientImmediate acceptance/rejection of a command
resultserver -> clientFinal outcome of an accepted command
eventserver -> clientAsynchronous runtime notification
errorserver -> clientProtocol-level validation/routing error

The same id links one command lifecycle:

  1. client sends command with id
  2. server sends ack with same id
  3. if ack.payload.accepted is true, server later sends result with same id

When ack.payload.accepted is false, no result follows for that command.

{
"type": "command",
"id": "cmd-42",
"name": "get_snapshot"
}
{
"type": "ack",
"id": "cmd-42",
"payload": {
"accepted": true
}
}
{
"type": "result",
"id": "cmd-42",
"payload": {
"ok": true,
"data": {
"services": []
}
}
}
{
"type": "event",
"name": "service_status",
"payload": {
"service": "api",
"status": "running",
"timestamp": "2026-04-25T10:00:00Z"
}
}
{
"type": "error",
"payload": {
"code": "invalid_json",
"message": "invalid json message"
}
}

The protocol validator enforces these envelope-level checks:

RuleError code
Frame is not valid JSONinvalid_json
type missing or emptymissing_type
type is unknownunknown_type
id missing on command/ack/resultmissing_id
name missing on command/eventmissing_name
Invalid required payload shapeinvalid_payload

Type-specific payload checks at validation layer:

  • ack.payload.accepted must be present
  • result.payload.ok must be present
  • error.payload.code and error.payload.message must both be present and non-empty

Command-specific payload checks (for example payload.service or payload.limit) are handled by command processing and can also produce invalid_payload.

See Errors for the full code catalog and WebSocket Lifecycle for transport and session sequencing.