Action Endpoint
The unified POST /api/request endpoint for channel management and sending or receiving messages from tooling and the dashboard.
Use the SDKs for application code
This endpoint exists for tooling and the built-in dashboard — channel management and ad-hoc send/receive from an operator console. For application messaging — producing and consuming Events, Events Store, Queues, Commands, and Queries — use the language SDKs, which give you streaming, batching, acknowledgements, and reconnection that this single request endpoint does not.
All channel-management and message operations on the management API go through a single
endpoint, which dispatches on the type field. It lives on the management API port
(:8080), uses the standard response envelope, and is
gated by the readiness check.
POST /api/request
The request body always has the same two top-level fields: an action type and an
action-specific data object.
{
"type": "<action_type>",
"data": { }
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Action-type identifier (see the table below). |
data | object | Yes | Action-specific parameters. |
Supported action types
| Type | Description | Returns data |
|---|---|---|
create_channel | Create a new channel. | No |
delete_channel | Delete an existing channel. | No |
send_queue_message | Send a message to a queue channel. | Yes |
receive_queue_messages | Receive or peek messages from a queue. | Yes |
purge_queue_channel | Purge all messages from a queue. | Yes |
send_pubsub_message | Publish an Events or Events Store message. | No |
send_cqrs_message_request | Send a command or query. | Yes |
send_cqrs_message_response | Respond to a received command or query. | No |
get_charts_array | Get time-series chart data for a channel or client. | Yes |
Channel management
create_channel
Creates a new channel of the given type. The channel is registered in metrics immediately.
{
"type": "create_channel",
"data": {
"type": "queues",
"name": "orders.process"
}
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Channel type: "queues", "events", "events_store", "commands", "queries". |
name | string | Yes | Channel name. |
A success response carries data: null:
{
"error": false,
"error_string": "",
"data": null
}delete_channel
Deletes an existing channel. This is a cluster-wide operation: the deletion is queued and
propagated across nodes, and the server waits up to 10 seconds for confirmation. Only
queues and events_store channels have durable storage to remove; events, commands,
and queries channels are cleared from metrics and topology only.
{
"type": "delete_channel",
"data": {
"type": "events_store",
"channel": "notifications"
}
}| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Channel type. See the warning below. |
channel | string | Yes | Channel name to delete. |
Always include type when deleting
Server-side validation only checks that channel is non-empty — it does not validate
type. But the downstream delete logic uses type to decide which durable storage is
cleaned, which metric series are removed, and which topology entries are deleted. Omitting
type returns a "successful" response with incomplete cleanup (storage and metrics are
left behind). Always send type for a reliable delete.
A success response carries data: null. A delete can also fail with a cluster propagation
error or a "timeout waiting for delete channel request" if no confirmation arrives within
10 seconds — both returned in the envelope.
Queue actions
send_queue_message
Sends a message to a queue channel.
{
"type": "send_queue_message",
"data": {
"messageId": "msg-001",
"channel": "orders.process",
"metadata": "order metadata",
"body": "order payload data",
"tags": "priority=high,region=us-east",
"maxReceiveCount": 3,
"maxReceiveQueue": "orders.dead-letter",
"expirationAt": 60,
"delayedTo": 10
}
}| Field | Type | Required | Description |
|---|---|---|---|
messageId | string | No | Custom message ID (auto-generated if empty). |
channel | string | Yes | Target queue channel. |
metadata | string | No | Message metadata string. |
body | any | Yes | Message body — a string, JSON object, or JSON array. |
tags | string | No | Comma-separated key=value pairs. |
maxReceiveCount | int | No | Max delivery attempts before rerouting (0 = unlimited). |
maxReceiveQueue | string | No | Dead-letter queue for messages exceeding the max receive count. |
expirationAt | int | No | Message expiration in seconds. |
delayedTo | int | No | Delay delivery by this many seconds. |
The response returns the assigned message ID and formatted timestamps:
{
"error": false,
"error_string": "",
"data": {
"messageId": "msg-001",
"sentAt": "2024-03-01T12:00:00Z",
"expiresAt": "2024-03-01 12:01:00",
"delayedTo": "2024-03-01 12:00:10"
}
}receive_queue_messages
Receives — or peeks at — messages from a queue channel.
{
"type": "receive_queue_messages",
"data": {
"channel": "orders.process",
"isPeek": false,
"count": 10
}
}| Field | Type | Required | Description |
|---|---|---|---|
channel | string | Yes | Queue channel to receive from. |
isPeek | boolean | No | If true, peek without consuming — messages stay in the queue. Default false. |
count | int | No | Maximum messages to receive (must be > 0 if set). |
The response data is an array of messages:
{
"error": false,
"error_string": "",
"data": [
{
"messageId": "msg-001",
"clientId": "order-service",
"metadata": "order metadata",
"body": "order payload data",
"timestamp": 1709312400000,
"sequence": 42,
"tags": "{\"priority\":\"high\"}",
"receivedCount": 1,
"reRoutedFrom": "",
"expirationAt": 1709312460000,
"delayedTo": 0
}
]
}The body field is auto-detected: a valid JSON object or array is returned as such,
otherwise as a string.
purge_queue_channel
Acknowledges and removes all waiting messages from a queue channel.
{
"type": "purge_queue_channel",
"data": {
"channel": "orders.process"
}
}| Field | Type | Required | Description |
|---|---|---|---|
channel | string | Yes | Queue channel to purge. |
The response returns the number of messages purged:
{
"error": false,
"error_string": "",
"data": {
"count": 150
}
}Pub/Sub action
send_pubsub_message
Publishes a message to an Events or Events Store channel. The isEvents flag selects which.
{
"type": "send_pubsub_message",
"data": {
"messageId": "evt-001",
"channel": "notifications",
"metadata": "event metadata",
"body": { "event": "user.created", "userId": 123 },
"tags": "source=api,priority=normal",
"isEvents": true
}
}| Field | Type | Required | Description |
|---|---|---|---|
messageId | string | No | Custom event ID. |
channel | string | Yes | Target channel name. |
metadata | string | No | Event metadata. |
body | any | Yes | Event body — a string, JSON object, or JSON array. |
tags | string | No | Comma-separated key=value pairs. |
isEvents | boolean | No | true for transient Events, false for persistent Events Store. Default false. |
The isEvents flag controls the pattern:
true— the message goes to the Events channel (fire-and-forget, no persistence). Only online subscribers receive it.false— the message goes to the Events Store channel (persistent). Subscribers can replay from any point.
A success response carries data: null.
CQRS actions
send_cqrs_message_request
Sends a command or query to a channel and waits for a response. The isCommands flag
selects the pattern; timeout is required.
{
"type": "send_cqrs_message_request",
"data": {
"requestId": "req-001",
"channel": "user-service",
"metadata": "get-user",
"body": { "userId": 123 },
"tags": "version=2",
"isCommands": false,
"timeout": 30
}
}| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | No | Custom request ID. |
channel | string | Yes | Target channel. |
metadata | string | No | Request metadata. |
body | any | Yes | Request body. |
tags | string | No | Comma-separated key=value pairs. |
isCommands | boolean | No | true for a command (fire-and-confirm), false for a query (request-response). Default false. |
timeout | int | Yes | Response timeout in seconds (must be > 0). |
A query response includes the responder's body and metadata:
{
"error": false,
"error_string": "",
"data": {
"metadata": "user-data",
"body": { "name": "John", "email": "john@example.com" },
"tags": "{\"version\":\"2\"}",
"timestamp": 1709312400000,
"executed": true,
"error": ""
}
}A command response carries only the execution status — no body:
{
"error": false,
"error_string": "",
"data": {
"tags": "",
"timestamp": 1709312400000,
"executed": true,
"error": ""
}
}send_cqrs_message_response
Sends a response to a previously received command or query — used by a subscriber that is processing requests over a WebSocket.
{
"type": "send_cqrs_message_response",
"data": {
"requestId": "req-001",
"replyChannel": "reply-abc123",
"metadata": "response metadata",
"body": { "result": "success" },
"tags": "processed=true",
"executed": true,
"error": ""
}
}| Field | Type | Required | Description |
|---|---|---|---|
requestId | string | No | The original request ID being responded to. |
replyChannel | string | Yes | The reply channel supplied on the received request (the subscriber receives it on the incoming request message). Echo it back unchanged so the response reaches the original sender. |
metadata | string | No | Response metadata. |
body | any | Yes | Response body. |
tags | string | No | Comma-separated key=value pairs. |
executed | boolean | No | Whether execution succeeded. |
error | string | No | Error message if execution failed. |
A success response carries data: null.
Chart data
get_charts_array
Retrieves time-series chart data for a channel or client. The response is four aligned series — incoming/outgoing message counts and volumes — ready to plot.
{
"type": "get_charts_array",
"data": {
"channel": "queues/orders.process",
"time_range": "1h",
"time_zone": 300
}
}| Field | Type | Required | Description |
|---|---|---|---|
channel | string | One of channel / client | Channel identifier, format {type}/{name}. |
client | string | One of channel / client | Client identifier, format {type}/{channel}/{clientId}. |
time_range | string | Yes | One of "1h", "2h", "6h", "12h", "1d", "7d", "14d", "30d". |
time_zone | int | No | Timezone offset in minutes — pass the browser's getTimezoneOffset() value (e.g. 300 for UTC-5, 0 for UTC, -330 for UTC+5:30). Applied to the chart labels. |
The response carries four ChartDataDTO series that share one label set for alignment:
{
"error": false,
"error_string": "",
"data": {
"incomingMessages": {
"labels": ["12:00", "12:05", "12:10", "12:15"],
"data": ["150", "200", "175", "180"]
},
"incomingVolume": {
"labels": ["12:00", "12:05", "12:10", "12:15"],
"data": ["30720", "40960", "35840", "36864"]
},
"outgoingMessages": {
"labels": ["12:00", "12:05", "12:10", "12:15"],
"data": ["145", "198", "170", "178"]
},
"outgoingVolume": {
"labels": ["12:00", "12:05", "12:10", "12:15"],
"data": ["29696", "40550", "34816", "36454"]
}
}
}Feed labels as the x-axis and data as the y-axis to any charting library. See
Data Models for the ChartsArrayDTO and
ChartDataDTO schemas.
Errors
Every action returns errors in the standard envelope with error: true — like all
business-logic errors, these come back with HTTP 200 (see
status codes).
{
"error": true,
"error_string": "descriptive error message",
"data": null
}Common cross-action errors:
error_string | Cause |
|---|---|
"unknown action type: <type>" | Unrecognized type field. |
"api service not ready" | The management API is still initializing. |
"the broker is not ready to accept traffic" | The broker is not yet ready to send or receive. |
Each action also has its own validation errors — for example a missing channel, a missing
body, a malformed tag, or a non-positive count or timeout. These too are returned with
HTTP 200 and error: true.
Related
Was this page helpful?