Skip to content

Tenants, API keys and quotas

The proxy built into the broker: tenants and their clusters, API keys and roles, plan quotas, metering, the console, and the /api/cp control plane a provisioning system drives.

Updated View as Markdown

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:latest

The 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=true

A 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"}
Two requests through the proxy. One arrives for acme.queen.example.com with acme's API key, the other for globex.queen.example.com with globex's. The proxy finds each request's cluster from the first label of its Host, checks that the key belongs to it, and hands the request to the broker under that cluster's own broker tenant, a random UUID, so the queues, KV and timers of one cluster are invisible to the other. Each broker tenant lives in exactly one raft group, placed by a hash of its name or by QUEEN_TENANT_GROUPS.acme.queen…acme's API keyglobex.queen…globex's API keyproxyHost → cluster,key checkedtenant 7f3c…acme's queues, KV,timers: one raft grouptenant 2a91…globex's, invisibleto acme
A cluster is a broker tenant of its own, and a tenant is one raft group with one leader, which is why a transaction inside it is one entry and why none can span two. Source: proxy/src/routes.rs, server/src/tenant.rs

QUEEN_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.com

An 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.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close