HTTP REST API Reference
TinyMQ exposes a language-agnostic HTTP API. Any client capable of making HTTP requests — curl, Python requests, PHP, Node.js, Rust — can interact with the broker without any special libraries.
Base URL: http://localhost:7800 (or your PORT setting)
Endpoints Summary
| Method | Endpoint | Description |
|---|---|---|
POST | /publish/{topic} | Publish a message |
GET | /consume/{topic} | Consume / long-poll for messages |
POST | /ack/{topic}/{id} | Acknowledge a message |
POST | /requeue | Re-queue a message (increment retry count) |
POST | /api/queues/redrive | Redrive dead-lettered messages from DLQ |
POST | /webhook/{topic} | Register a push webhook |
POST | /api/topics | Create a topic manually |
POST | /api/groups | Create a Consumer Group |
GET | /api/groups | List Consumer Groups for a topic |
GET | /api/cluster/status | Get cluster diagnostics |
POST | /api/drain | Mark node as draining (graceful maintenance) |
GET | /api/stats | Get broker statistics |
GET | /metrics | Get Prometheus metrics |
GET | /healthz | Healthcheck endpoint |
GET | /dashboard | Interactive web dashboard |
Dashboard/JSON API (Alternative):
| Method | Endpoint | Description |
|---|---|---|
GET | /api/queues | List all queues |
POST | /api/queues/publish | Publish via JSON body |
POST | /api/queues/consume | Consume via JSON body |
GET | /api/queues/peek | Peek at queue contents |
DELETE | /api/queues/purge | Purge all messages from a queue |
DELETE | /api/queues/delete | Delete queue entirely |
GET | /api/queues/webhooks | List webhooks for a queue |
POST /publish/{topic}
Publish a message to a topic. The topic is created automatically on first publish.
Query Parameters
| Parameter | Type | Description |
|---|---|---|
ttl | duration | Time-To-Live. Message is dropped if not consumed before expiry. Examples: 30s, 5m, 1h |
delay | duration | Delivery delay. Message is hidden until this duration passes. Examples: 10s, 1m |
broadcast | bool | If true, delivers to all waiting consumers simultaneously (ephemeral — not persisted) |
priority | string | Enqueue with priority: high, normal, or low. (Default: normal) |
idempotency | string | Set to auto to use payload SHA256 as idempotency key |
Headers
| Header | Description |
|---|---|
Idempotency-Key | A unique string (e.g. uuid). If a duplicate key is sent within 5 minutes, it is silently accepted but discarded. |
X-MQ-* | Any custom header starting with X-MQ- is stored with the message. |
Request Body
Raw bytes (JSON, plain text, binary). Maximum size: 2MB.
curl -X POST "http://localhost:7800/publish/orders.eu?ttl=10m&priority=high" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: txn-12345" \
-d '{"user_id": 42, "item": "laptop"}'
GET /consume/{topic}
Consume one or more messages from a topic. Supports long-polling.
Query Parameters
| Parameter | Type | Default | Description |
|---|---|---|---|
timeout | duration | 0s | Hold connection open this long if queue is empty (long-polling). E.g., 5s, 10s |
limit | int | 1 | Number of messages to extract in one call |
auto_ack | bool | false | If true, messages are ACK'd immediately upon delivery |
group | string | (empty) | Consumer Group name for Pub/Sub. E.g. billing |
peek | bool | false | If true, reads messages without consuming/ACKing them |
filter_key | string | (empty) | Smart Routing: Only return messages with this exact JSON key |
filter_val | string | (empty) | Smart Routing: Value to match against filter_key |
# Consume with 10s long-poll, batch of 5, auto-acknowledged, as group "billing"
curl "http://localhost:7800/consume/orders.eu?timeout=10s&limit=5&auto_ack=true&group=billing"
Response
Single message (limit=1, default):
{
"id": "a1b2c3d4-7c89-4b1a-9f5e-123456789abc",
"topic": "orders.eu",
"payload": "eyJ1c2VyX2lkIjogNDIsICJpdGVtIjogImxhcHRvcCJ9",
"payload_text": "{\"user_id\": 42, \"item\": \"laptop\"}",
"timestamp": "2026-06-18T10:00:00Z",
"retry_count": 0
}
payload is returned as Base64-encoded bytes. If the bytes form valid UTF-8 text, payload_text is also populated for convenience.
POST /ack/{topic}/{id}
Acknowledge a message, removing it from RAM and writing an ACK record to the WAL. Required when auto_ack=false.
curl -X POST http://localhost:7800/ack/orders.eu/a1b2c3d4-7c89-4b1a-9f5e-123456789abc
POST /requeue
Re-queue a message, incrementing its retry_count. After 3 attempts, the broker routes it to {topic}.dlq.
The request body must be a full message JSON object.
POST /api/queues/redrive?queue={topic}
Redrives all dead-lettered messages from {topic}.dlq back to the main {topic} queue.
The retry counters are reset, and the messages are removed from the DLQ.
curl -X POST http://localhost:7800/api/queues/redrive?queue=orders.eu
POST /webhook/{topic}
Register a URL to receive messages from a topic via HTTP POST (push/webhook pattern).
curl -X POST http://localhost:7800/webhook/orders.eu \
-H "Content-Type: application/json" \
-d '{"url": "https://api.my-service.com/hook", "secret": "my-hmac-secret"}'
If secret is provided, outbound POSTs will include an X-TinyMQ-Signature header containing an HMAC-SHA256 signature of the payload.
POST /api/topics
Pre-initialize a topic. Useful for Consumer Group wiring or setting Retain rules.
curl -X POST http://localhost:7800/api/topics \
-H "Content-Type: application/json" \
-d '{"name": "analytics.events", "policy": "reject", "retain": "24h"}'
policy: Overflow policy (rejectordrop-oldest) when max limit (100k) is hit.retain: Auto-apply this TTL to all messages published to this topic.
GET /metrics
Returns standard Prometheus metrics for observability.
curl http://localhost:7800/metrics
GET /healthz
Healthcheck endpoint used for Docker/Kubernetes probes.
200 OK— broker is healthy and ready503 Service Unavailable— returned mid-election (no recognized leader yet). Kubernetes readiness probes will stop routing traffic automatically.
curl http://localhost:7800/healthz
Response in standalone mode:
{ "status": "ok", "version": "3.1.0", "uptime_seconds": 3600 }
Response in cluster mode:
{
"status": "ok",
"version": "3.1.0",
"uptime_seconds": 3600,
"cluster_role": "leader",
"cluster_term": 3
}
cluster_role can be: "leader", "follower", or "candidate".
Response during election:
{ "status": "electing" }
POST /api/drain
Marks the node as draining immediately. All subsequent requests will return 503 Service Unavailable. Intended for controlled maintenance restarts — load balancers and Kubernetes readiness probes will automatically stop routing traffic.
curl -X POST http://localhost:7800/api/drain
Response:
{ "status": "draining", "in_flight_requests": 3 }
There is no un-drain API. To recover, restart the process. Use tmq cluster drain <node-url> from the CLI to avoid accidentally targeting the wrong node.
POST /api/groups & GET /api/groups
Manage Consumer Groups explicitly. Groups allow multiple independent services to consume identical messages without stealing from each other.
Create a Group:
curl -X POST http://localhost:7800/api/groups \
-H "Content-Type: application/json" \
-d '{"topic": "orders.eu", "group": "billing"}'
List Groups:
curl http://localhost:7800/api/groups?topic=orders.eu
GET /api/cluster/status
Returns diagnostic information about the node's participation in the TinyMQ High Availability cluster, including its role, current term, the leader's address, and peer health status.
curl http://localhost:7800/api/cluster/status
Dashboard JSON APIs (/api/queues/*)
These endpoints accept JSON bodies instead of URL path parameters. They are heavily used by the embedded dashboard.
GET /api/queues: Returns a list of all active queues.POST /api/queues/publish: JSON body with{"queue": "topic", "payload": "...", "ttl": "...", "delay": "...", "priority": "...", "broadcast": false}POST /api/queues/consume: JSON body with{"queue": "topic"}GET /api/queues/peek?queue=orders.eu: Returns an array of up to 10 messages without removing them.POST /api/queues/redrive?queue=orders.eu: Redrives messages from DLQ to main topic.DELETE /api/queues/purge?queue=orders.eu: Empties the queue.DELETE /api/queues/delete?queue=orders.eu: Deletes the queue and its WAL file.GET /api/queues/webhooks?queue=orders.eu: Returns a list of webhook URLs for the queue.
Error Reference
| HTTP Status | Meaning | Typical Cause |
|---|---|---|
400 Bad Request | Malformed request | Missing topic, empty body, invalid duration |
403 Forbidden | Access Denied | TINYMQ_MAX_TOPICS limit reached |
404 Not Found | Resource not found | Empty queue (on consume), unknown message ID |
409 Conflict | Already exists | Creating a topic that already exists |
413 Request Entity Too Large | Payload too big | Payload exceeds 2MB |
429 Too Many Requests | Backpressure | Queue RAM limit (100k messages) reached |