The broker on its own has no users: anything that reaches its port can use it. The proxy compiled into the same binary adds them. With it on, every request presents an API key or a console session, and the proxy maps that credential to one tenant’s cluster, checks it against the plan’s limits, meters it, and hands the request to the broker inside the same process. The proxy keeps its own state (tenants, users, API-key hashes, plans and usage) as rows in the broker’s replicated KV, under a reserved system tenant, so every node of a cluster runs the same proxy and there is no database to give it.
Turn it on
Generate the secrets once and keep them in your secret store, because every node needs the same values:
SESSION_SECRET=$(openssl rand -hex 32) # signs console sessions
CP_TOKEN=$(openssl rand -hex 32) # opens the control plane, /api/cp/*
QUEEN_KEY="qk_live_$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')"docker run -d --name queen --platform linux/amd64 -p 6711:6711 -p 127.0.0.1:6632:6632 \
-v queen-data:/var/lib/queen/raft \
-e QUEEN_PROXY_EMBEDDED=true \
-e QUEEN_PROXY_PORT=6711 \
-e QUEEN_PROXY_JWT_SECRET="$SESSION_SECRET" \
-e QUEEN_PROXY_CP_TOKEN="$CP_TOKEN" \
-e QUEEN_PROXY_SPOOL_DIR=/var/lib/queen/raft/proxy-spool \
-e QUEEN_PROXY_BOOTSTRAP_TENANT=acme \
-e QUEEN_PROXY_BOOTSTRAP_API_KEY="$QUEEN_KEY" \
-e QUEEN_PROXY_DEFAULT_CLUSTER=acme \
ghcr.io/queen-mq/queen:latestThe boot log says where each part went:
INFO boot: single binary: proxy in-process on its own port; the broker router serves PORT (internal) proxy=0.0.0.0:6711 broker=0.0.0.0:6632
INFO proxy: bootstrap tenant ready tenant=acme created=trueA push through the proxy’s port now needs the key:
curl -s -X POST localhost:6711/api/v1/push -H "authorization: Bearer $QUEEN_KEY" \
-H 'content-type: application/json' \
-d '{"items":[{"queue":"orders","partition":"customer-123","payload":{"orderId":8891}}]}'[{"index":0,"message_id":"01a0fcca-5436-7000-ab29-ef2bea95314f","transaction_id":"01a0fcca-5436-7000-ab29-ef2bea95314f","queueName":"orders","status":"queued","offset":0}]Without it the answer is 401 {"code":"unauthorized","error":"missing bearer credential"}.
Clients send the key the same way:
const queen = new Queen({ url: 'https://acme.queen.example.com', bearerToken: process.env.QUEEN_KEY })The bootstrap runs at every boot on every node and changes nothing once its rows exist, so the
same environment can stay on all nodes for good. It creates the tenant acme, a cluster of the
same name on the dev plan (QUEEN_PROXY_BOOTSTRAP_PLAN), an admin user
(QUEEN_PROXY_BOOTSTRAP_EMAIL, default admin@localhost, who can sign in with a password only if
you set QUEEN_PROXY_BOOTSTRAP_PASSWORD), and a key with every scope on that cluster from
QUEEN_PROXY_BOOTSTRAP_API_KEY. A key has to start with qk_, which is how the proxy tells an API
key from a session token. Keep QUEEN_PROXY_SPOOL_DIR on the data volume; its default is relative
to the working directory, which is read-only in a hardened container.
Two ports
QUEEN_PROXY_PORT decides what the broker’s own port, PORT (6632), still serves:
QUEEN_PROXY_PORT |
The proxy listens on | PORT serves |
|---|---|---|
unset, or equal to PORT |
PORT |
nothing else: every request needs a key or a session |
another port, e.g. 6711 |
that port | the broker itself, under its own JWT setting (off by default) |
Run a cluster with the proxy on its own port. The nodes talk to each other over PORT (ephemeral
partitions are forwarded and handed over there), and the membership and kill-switch routes under
/api/v1/system/* are blocked through the proxy for every credential, so a cluster needs a broker
port the proxy is not in front of. That port is for trusted clients inside the network, probes and
scrapers, and it never faces the internet. TLS for the proxy’s port is QUEEN_TLS_CERT and
QUEEN_TLS_KEY (security).
Tenants and clusters
A tenant is an organisation, and its users belong to it. A tenant owns clusters, and a cluster is what clients talk to: a slug, a plan, and a broker tenant of its own (a random UUID), so the queues, KV and timers of one cluster are invisible to every other.
The proxy finds a request’s cluster from the first DNS label of its Host, so
acme.queen.example.com is cluster acme. A Host that names no cluster, like localhost, falls
back to QUEEN_PROXY_DEFAULT_CLUSTER, and a host listed in QUEEN_PROXY_SHARED_HOSTS fronts many
clusters and takes the cluster from the credential instead. Whatever x-queen-tenant header a
client sends is dropped. A key is bound to its cluster for life, so presenting it on another
cluster’s host fails:
{"code":"forbidden","error":"key/cluster mismatch"}proxy/src/routes.rs, server/src/tenant.rsQUEEN_PROXY_TENANT_HEADER=false stops the proxy from scoping requests at all: every cluster lands
in the broker’s default tenant, the one the internal port sees. That suits a single team that
wants keys and a console in front of one shared broker, and nothing else, because the clusters
then share every queue. The control-plane routes that act on a cluster’s broker data refuse to run
in that mode (409 system_tenant).
A cluster’s status is active, push_blocked, suspended or deleting, a tenant’s is active,
grace, suspended or deleting, and the worse of the two applies. push_blocked and grace
refuse pushes and keep consumption open, so a customer can drain what is there; suspended and
deleting answer the whole data plane 403 cluster_suspended.
API keys and roles
A key is qk_<env>_ followed by 43 base64url characters, and only its sha256 is stored. Each key
carries a non-empty set of scopes, while humans hold one role per cluster:
| Route class | Key scope | Human roles |
|---|---|---|
| Produce: push, transaction | produce |
admin, producer |
| Consume: pop, ack, lease extension | consume |
admin, consumer |
| Queue admin: configure, deletes, seeks, DLQ replay | admin |
admin |
| Read: listings, status, message and DLQ reads | read or admin |
every role |
| KV, timers, ephemeral, streams, traces, when the plan has the feature | produce or consume; their reads take any scope |
every role but viewer; their reads every role |
A produce-only key that tries to list queues gets
403 {"code":"forbidden","error":"operation not permitted for this credential"}. A revoked key stops
working on every node within about a second, because each node polls the replicated invalidation
feed every QUEEN_PROXY_INVAL_POLL_MS (1000). API keys are refused on the console, which is for
humans only. The complete classification of every broker route is at the end of this page.
Plans and quotas
Four plans are seeded at the first boot. A cluster takes its plan when it is created (free by
default through the control plane, dev through the bootstrap), and per-cluster overrides change
single limits:
free |
dev |
pro |
dedicated-s |
|
|---|---|---|---|---|
| requests/s (burst) | 5 (25) | 10 (50) | 50 (200) | 200 (800) |
| messages/s (burst) | 20 (100) | 40 (200) | 200 (800) | 600 (2000) |
| queues, partitions per queue | 20, 8 | 50, 16 | 200, 32 | 1000, 64 |
| parked long-poll pops | 50 | 150 | 1000 | 5000 |
| payload, items per batch | 256 KiB, 1000 | 512 KiB, 2000 | 1 MiB, 5000 | 4 MiB, 10000 |
| retained bytes, longest retention | 1 GiB, 7 days | 3 GiB, 14 days | 20 GiB, 30 days | 200 GiB, 90 days |
| features | KV, timers, ephemeral | KV, timers, ephemeral | the same, plus streams and traces | the same, plus streams and traces |
curl -s -X PUT localhost:6711/api/cp/clusters/$CLUSTER_ID/overrides \
-H "x-queen-cp-token: $CP_TOKEN" -H 'content-type: application/json' \
-d '{"max_queues": 500, "max_retained_bytes": null}'A null limit is unlimited, and a body of null clears every override.
The proxy starts in shadow mode (QUEEN_PROXY_ENFORCE=false): rate limits, queue and partition
caps and parked-pop caps are computed and logged with target: limits and would_block=true, and
the request goes through. That lets you watch a plan against real traffic before it bites. With
QUEEN_PROXY_ENFORCE=true the same decisions answer 429 with Retry-After, or 403. Three
limits apply in shadow mode too, because they bound what the proxy itself has to hold or store: the
size caps (413 payload_too_large), the storage quota (max_retained_bytes, after which pushes
answer 403 storage_quota_exceeded) and the monthly message quota (monthly_msgs_quota, unset on
every seeded plan).
Metering
Every proxied request is metered per cluster, minute and class (push, delivery, txn,
configure, read): requests, messages, and bytes in and out. Items the broker refused as error
are not counted, and a duplicate is counted once. Each node writes its own rows every 15 seconds
(QUEEN_PROXY_METER_FLUSH_MS), keeps the minutes for 90 days (QUEEN_PROXY_USAGE_KEEP_DAYS) and
rolls them into days every hour. Usage a node cannot write during a long outage, or at shutdown,
goes to QUEEN_PROXY_SPOOL_DIR and is written back at the next start. The control plane reads the
last hour, summed over the nodes:
curl -s localhost:6711/api/cp/clusters/$CLUSTER_ID/usage -H "x-queen-cp-token: $CP_TOKEN"{"minutes":[{"bytes_in":70,"bytes_out":173,"minute":"2026-10-02T13:25:00Z","msgs":1,"op":"push","reqs":1}]}The console and sign-in
/console on the proxy’s port is for people: the cluster’s plan, limits and month-to-date usage,
usage graphs, a read-only queue list, its API keys and, for admins, its members. The dashboard is
served at / on the same port behind the same login. Sign-in is at /auth/login, with a local
password (the bootstrap admin’s), Google (GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET,
GOOGLE_ALLOWED_DOMAINS) or GitHub (GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET), and
QUEEN_PROXY_PUBLIC_URL set so the callbacks have an address. An identity the proxy has never
seen gets no account unless you turn on QUEEN_PROXY_AUTOPROVISION=true and name the tenant it
joins with QUEEN_PROXY_AUTOPROVISION_TENANT; it then gets QUEEN_PROXY_DEFAULT_ROLE (viewer)
on every cluster of that tenant.
Operators are the people who run the deployment itself:
QUEEN_PROXY_OPERATOR_ENABLED=true
QUEEN_PROXY_OPERATORS=ops@example.com,alice@example.comAn operator is admin on every cluster and can open the cell-wide pages: node status, host metrics,
and the raft status and members behind the dashboard’s System page. At each boot the listed
accounts are granted and every other operator is revoked, so the list in your deployment is the
whole truth; an empty list revokes everyone, and leaving the variable unset leaves the flags as they
are. No API route grants the flag, and with QUEEN_PROXY_OPERATOR_ENABLED off (the default) the
operator routes answer 404 to everyone.
The control plane
Everything after the bootstrap can be driven over /api/cp/* on the proxy’s port, with
x-queen-cp-token: $CP_TOKEN on every call. The token is checked before any body is read, bodies
are capped at 1 MiB, and with QUEEN_PROXY_CP_TOKEN unset the whole surface answers 404. We
designed it for a provisioning system that delivers its commands at least once, so every route is
safe to repeat: a retry of a call that already took effect answers success with the same ids.
| Route | What it does |
|---|---|
POST /api/cp/provision |
The tenant, its cluster, a user under your own id, that user’s role, a key from your sha256 and the overrides, in one atomic write. A deleting tenant is refused |
POST /api/cp/bootstrap |
A tenant, its cluster, an admin and a key the proxy generates. The key’s plaintext is in this answer only |
POST /api/cp/tenants |
A tenant, from {slug, name?} |
PUT /api/cp/tenants/:slug/status |
active, grace, suspended or deleting |
POST /api/cp/tenants/:slug/purge |
Deletes the broker data of every cluster of a deleting tenant. Repeat it until it answers done: true |
DELETE /api/cp/tenants/:slug |
Removes a deleting tenant whose broker data is gone; ?force=true skips both checks |
GET /api/cp/clusters, POST /api/cp/clusters |
Every cluster (?plan= filters); ensure a cluster and its tenant exist |
GET /api/cp/clusters/:slug |
The cluster with its tenant, plan, statuses and overrides |
GET /api/cp/clusters/:slug/queues, POST .../configure |
The broker’s queue listing and configure, run as that cluster. Refused while it is deleting |
PUT /api/cp/clusters/:id/overrides, PUT .../status |
One cluster’s limits; its status |
GET /api/cp/clusters/:id/usage |
The last hour of metered minutes, summed over the nodes |
POST /api/cp/activity |
For up to 256 slugs: the last active minute, the first push, the last key use, the retained bytes |
POST /api/cp/keys, DELETE /api/cp/keys/:id |
A key from {cluster_id, name, key_hash, scopes}; its revocation |
provision is the call to build on. You mint the key yourself and send only its sha256, so the
plaintext never reaches the proxy, and you choose the user’s id, which is the subject of the
sessions your own sign-in issues:
KEY="qk_live_$(openssl rand -base64 32 | tr '+/' '-_' | tr -d '=')"
HASH=$(printf %s "$KEY" | sha256sum | cut -d' ' -f1)
curl -s -X POST localhost:6711/api/cp/provision -H "x-queen-cp-token: $CP_TOKEN" \
-H 'content-type: application/json' -d '{
"tenant_slug": "globex", "cluster_slug": "globex", "plan": "pro",
"user_id": "308d3f3d-2306-41de-95f1-e32b12ec7470", "email": "ops@globex.example",
"role": "admin", "key_name": "default", "key_hash": "'"$HASH"'",
"scopes": ["produce", "consume", "read"], "overrides": {"max_queues": 500}}'{
"broker_tenant_uuid": "ff2ab01d-c30e-45e3-960b-5bd7deecd6f5",
"cluster_id": "0acf78a8-567a-4a9b-b01d-89be075fe56a",
"created": { "cluster": true, "key": true, "tenant": true, "user": true },
"key_id": "76648399-b1b0-469e-ba7a-a2ebfb2466da",
"overrides": { "max_queues": 500 },
"plan_code": "pro",
"tenant_id": "b52683ee-7a9b-4e5d-b831-c4806931d866",
"user_id": "308d3f3d-2306-41de-95f1-e32b12ec7470"
}Sent again, the same call answers the same ids with every created flag false. Taking a tenant
down is three steps, and the proxy refuses them out of order. The delete answers
409 not_deleting while the tenant is active, and 409 not_purged while its broker still lists a
queue; the purge is done only on a pass that finds nothing left to delete, which is why the first
pass below answers done: false:
curl -s -X PUT localhost:6711/api/cp/tenants/globex/status -H "x-queen-cp-token: $CP_TOKEN" \
-H 'content-type: application/json' -d '{"status":"deleting"}'
curl -s -X POST localhost:6711/api/cp/tenants/globex/purge -H "x-queen-cp-token: $CP_TOKEN"
curl -s -X POST localhost:6711/api/cp/tenants/globex/purge -H "x-queen-cp-token: $CP_TOKEN"
curl -s -X DELETE localhost:6711/api/cp/tenants/globex -H "x-queen-cp-token: $CP_TOKEN"{"clusters":[{"broker_tenant_uuid":"ff2ab01d-c30e-45e3-960b-5bd7deecd6f5","id":"0acf78a8-567a-4a9b-b01d-89be075fe56a","slug":"globex"}],"ok":true,"tenant_id":"b52683ee-7a9b-4e5d-b831-c4806931d866"}
{"clusters":[{"broker_tenant_uuid":"ff2ab01d-c30e-45e3-960b-5bd7deecd6f5","done":false,"partitions_deleted":1,"slug":"globex"}],"done":false,"existed":true}
{"clusters":[{"broker_tenant_uuid":"ff2ab01d-c30e-45e3-960b-5bd7deecd6f5","done":true,"partitions_deleted":0,"slug":"globex"}],"done":true,"existed":true}
{"clusters":[{"broker_tenant_uuid":"ff2ab01d-c30e-45e3-960b-5bd7deecd6f5","cluster_id":"0acf78a8-567a-4a9b-b01d-89be075fe56a","slug":"globex"}],"existed":true}From the moment the status is deleting, the tenant’s own traffic answers
403 cluster_suspended. The control plane never acts on the broker’s default tenant or on the
proxy’s own system tenant, whatever a request names.
Limits
Rate buckets and parked-pop gauges live in each node’s memory, so behind a load balancer over three nodes a cluster can reach three times its plan’s rate. The storage quota is read from the broker’s own measurement, which every node shares.
Ephemeral queues behind the proxy are safe on a single node only, for now. In a cluster, an ephemeral request that the receiving node forwards to the partition’s owner does not keep its tenant and lands in the broker’s default tenant; durable queues are isolated as described above. Separately, an ephemeral hand-over to a node that is still restarting can drop that partition’s messages, which we have seen during rolling restarts (ephemeral queues).
The proxy does not isolate tenants from the people who run it. A live operator, and anyone who
holds QUEEN_PROXY_CP_TOKEN, can act on every cluster, and the broker port behind the proxy
answers whatever reaches it under the broker’s own JWT setting (security).
No route edits a plan or moves a cluster to another deployment; overrides are how one cluster’s
limits change. When the replicated KV cannot answer (a cluster without a majority), a key the proxy
has recently checked keeps authenticating for up to 10 more minutes
(QUEEN_PROXY_STALE_GRACE_MS), while a key it has not seen is refused.
Route classes
The proxy classifies every broker-bound request into exactly one class, and anything API-shaped that matches no rule is blocked. The table below applies that classifier to the broker’s own route list.
| Class | What it means |
|---|---|
| produce | Counted against the message quota. May create queues and partitions implicitly. |
| consume | Pop, ack, lease extension, and the three reads a consumer positions itself with: the batched read from an offset that the Kafka facade consumes through, the lookup of the first offset a partition appended at or after a time, and the partition discovery a reader maps a queue with. A wait=true pop also holds a parked-consumer slot; a fetch does not, because its long poll is a field of the body. The three reads move nothing and are never quota-blocked, but between them they hand out message payloads and the offsets to read them by, so they need the authority of the pop they stand in for. The read level every user role has would let a Viewer read every queue by offset. |
| queue admin | Configuration, deletions, seeks, subscription changes and the dead-letter replay. The replay is the one route in this class that also WRITES a message: it re-pushes a dead-letter snapshot and drops the dead-letter record in the same act, so it carries the authority of the deletion and answers the storage and monthly push blocks like a push. Everything else here is never quota-blocked, since deleting and shortening retention are how a tenant that is over a quota gets back under it. |
| read | Listings, status, analytics, DLQ and message reads, all tenant-scoped. |
| gated (streams) | Available when the plan enables the streams feature. Registration and the state read are never quota-blocked. The cycle is the produce half of the family: a cycle whose body carries sink push_items answers the storage and monthly blocks (refused whole, with the same code the equivalent push would get), its sink queues and partitions pass registry admission, its items answer the per-item payload cap, and its accepted sink messages are billed as push. An ack-only or state-only cycle always passes, so a blocked tenant can keep draining its source. |
| gated (traces) | Writing a trace is available when the plan enables the traces feature. |
| gated (kv) | Available when the plan enables the KV feature, which a plan that has never heard of it does not. A PUT is the half a storage quota blocks; a GET is read level; a DELETE is how a tenant at its cap gets back under it and is never quota-blocked. The batch POST carries both halves in one array, so a quota refuses the whole call with a named reason and never drops part of it. One exception is decided on the body, which this table cannot show: a batch that addresses only the Kafka facade’s own consumer-group keys (namespace queen-kafka, keys qk:) is classified consume, so a Kafka client needs neither the KV feature nor room under the storage quota to commit offsets. |
| gated (timers) | Available when the plan enables the timers feature. Scheduling is quota-blockable; cancelling is not, and has its own route for that reason, since a tenant blocked from cancelling would keep producing messages it can no longer stop. |
| gated (ephemeral) | Available when the plan enables the ephemeral feature, which a plan that has never heard of it does not. A push is the half a storage quota blocks and its messages are counted like any other; a pop is metered as a delivery and holds a parked-consumer slot while it waits; ack, configure, reset and the queue DELETE are write level and never quota-blocked, since dropping a queue is how a tenant gets its memory back. The two status reads are read level. |
| operator | Cell-wide surfaces, which no tenant can be scoped to. Only an operator reaches them, on a node with QUEEN_PROXY_OPERATOR_ENABLED=true and an account listed in QUEEN_PROXY_OPERATORS; any other credential gets the same 404 a blocked route returns. |
| blocked | Never exposed to a tenant, whatever the credential. Returns 404. |
produce
| Method | Path |
|---|---|
POST |
/api/v1/push |
POST |
/api/v1/transaction |
consume
| Method | Path |
|---|---|
POST |
/api/v1/ack |
POST |
/api/v1/ack/batch |
POST |
/api/v1/fetch |
POST |
/api/v1/fetch/offsets |
POST |
/api/v1/lease/:leaseId/extend |
POST |
/api/v1/partitions/changed |
GET |
/api/v1/pop/queue/:queue |
GET |
/api/v1/pop/queue/:queue/partition/:partition |
queue admin
| Method | Path |
|---|---|
POST |
/api/v1/configure |
GET |
/api/v1/connectors |
DELETE |
/api/v1/connectors/:name |
GET |
/api/v1/connectors/:name |
PUT |
/api/v1/connectors/:name |
POST |
/api/v1/connectors/:name/resync |
DELETE |
/api/v1/consumer-groups/:group |
DELETE |
/api/v1/consumer-groups/:group/queues/:queue |
POST |
/api/v1/consumer-groups/:group/queues/:queue/partitions/:partition/seek |
POST |
/api/v1/consumer-groups/:group/queues/:queue/seek |
POST |
/api/v1/consumer-groups/:group/subscription |
POST |
/api/v1/consumer-groups/positions |
DELETE |
/api/v1/dlq |
POST |
/api/v1/dlq/:id/replay |
DELETE |
/api/v1/messages/:partitionId/:transactionId |
POST |
/api/v1/messages/:partitionId/:transactionId/retry |
DELETE |
/api/v1/resources/queues/:queue |
read
| Method | Path |
|---|---|
GET |
/api/v1/analytics/dlq-signatures |
GET |
/api/v1/analytics/partition-liveness |
GET |
/api/v1/analytics/queue-lag |
GET |
/api/v1/analytics/queue-ops |
GET |
/api/v1/analytics/queue-parked-replicas |
GET |
/api/v1/analytics/retention |
GET |
/api/v1/analytics/workload |
GET |
/api/v1/consumer-groups |
GET |
/api/v1/consumer-groups/:group |
GET |
/api/v1/consumer-groups/lagging |
GET |
/api/v1/dlq |
GET |
/api/v1/messages |
GET |
/api/v1/messages/:partitionId/:transactionId |
POST |
/api/v1/resources/kv/list |
GET |
/api/v1/resources/kv/namespaces |
GET |
/api/v1/resources/namespaces |
GET |
/api/v1/resources/overview |
GET |
/api/v1/resources/partitions |
GET |
/api/v1/resources/queues |
GET |
/api/v1/resources/queues/:queue |
GET |
/api/v1/resources/queues/:queue/depth |
GET |
/api/v1/resources/queues/:queue/sizes |
GET |
/api/v1/resources/tasks |
GET |
/api/v1/status/analytics |
GET |
/api/v1/status/queues |
GET |
/api/v1/status/queues/:queue |
GET |
/api/v1/traces/:partitionId/:transactionId |
GET |
/api/v1/traces/by-name/:traceName |
GET |
/api/v1/traces/names |
GET |
/auth/login |
POST |
/auth/logout |
GET |
/auth/me |
GET |
/health |
gated (streams)
| Method | Path |
|---|---|
POST |
/streams/v1/cycle |
POST |
/streams/v1/queries |
POST |
/streams/v1/state/get |
gated (traces)
| Method | Path |
|---|---|
POST |
/api/v1/traces |
gated (kv)
| Method | Path |
|---|---|
POST |
/api/v1/kv |
DELETE |
/api/v1/kv/:ns/*key |
GET |
/api/v1/kv/:ns/*key |
PUT |
/api/v1/kv/:ns/*key |
gated (timers)
| Method | Path |
|---|---|
POST |
/api/v1/timers |
GET |
/api/v1/timers/:queue |
DELETE |
/api/v1/timers/:queue/*timerKey |
GET |
/api/v1/timers/:queue/*timerKey |
gated (ephemeral)
| Method | Path |
|---|---|
POST |
/api/v1/ephemeral/ack |
POST |
/api/v1/ephemeral/configure |
GET |
/api/v1/ephemeral/pop |
POST |
/api/v1/ephemeral/push |
DELETE |
/api/v1/ephemeral/queue/:_ |
DELETE |
/api/v1/ephemeral/queue/:queue |
GET |
/api/v1/ephemeral/queues |
GET |
/api/v1/ephemeral/queues/:queue/depth |
POST |
/api/v1/ephemeral/reset |
operator
| Method | Path |
|---|---|
GET |
/api/v1/analytics/system-metrics |
GET |
/api/v1/analytics/worker-metrics |
GET |
/api/v1/raft/members |
GET |
/api/v1/raft/status |
GET |
/api/v1/status |
GET |
/metrics/prometheus |
blocked
| Method | Path |
|---|---|
POST |
/api/v1/ephemeral/_adopt |
POST |
/api/v1/ephemeral/_leaving |
GET |
/api/v1/ephemeral/_ready |
GET |
/api/v1/pop |
GET |
/api/v1/raft/liveness |
POST |
/api/v1/resources/quota |
DELETE |
/api/v1/resources/tenant |
POST |
/api/v1/stats/refresh |
GET |
/api/v1/system/ephemeral |
POST |
/api/v1/system/ephemeral |
GET |
/api/v1/system/kv-timers |
POST |
/api/v1/system/kv-timers |
POST |
/api/v1/system/quota |
POST |
/api/v1/system/quotas |
GET |
/api/v1/system/raft/membership |
POST |
/api/v1/system/raft/membership/learners |
DELETE |
/api/v1/system/raft/membership/members/:id |
POST |
/api/v1/system/raft/membership/promote |
PUT |
/api/v1/system/raft/membership/voters |
GET |
/api/v1/system/shared-state |
GET |
/metrics |
GET |
/status |
81 of the broker’s 109 method + path pairs are reachable with a tenant credential; the rest are operator or blocked surfaces.