API reference
All endpoints are mounted at /v1/modules/scaiqueue/ and authenticate with the standard ScaiGrid bearer token. Responses use ScaiGrid's standard envelope ({ "data": ... } for success, { "error": ... } for failures). All routes require a tenant-scoped caller — super_admin without a tenant cannot use these endpoints.
Scopes#
A scope is a tenant-owned namespace for queues. Creating a scope also creates five system queues: _dead_letter, _events, _audit, _integrity, _corrections.
POST /scopes#
Create a scope. Requires scaiqueue:manage.
| Field | Required | Notes |
|---|---|---|
slug |
yes | Unique within tenant. |
display_name |
no | Defaults to slug. |
description |
no | |
defaults |
no | Object of default settings inherited by queues. |
GET /scopes#
List scopes in the caller's tenant. Requires scaiqueue:view.
GET /scopes/{scope_id}#
Fetch one scope. Requires scaiqueue:view.
POST /scopes/{scope_id}/{pause|resume|drain|archive|unarchive}#
State transitions, each requiring scaiqueue:manage. Allowed moves:
active→paused,draining,archivedpaused→active,draining,archiveddraining→archivedarchived→active
Paused or archived scopes reject new publishes.
DELETE /scopes/{scope_id}#
Hard-delete. Scope must be archived first. Requires scaiqueue:manage.
Queues#
A queue lives in a scope and has an ordering mode (fifo, priority, deadline) and a consumer mode (competing, broadcast).
POST /scopes/{scope_id}/queues#
Create a queue. Requires scaiqueue:manage.
| Field | Required | Notes |
|---|---|---|
slug |
yes | Unique within scope. |
display_name |
no | Defaults to slug. |
description |
no | |
consumer_mode |
no | competing (default) or broadcast. |
ordering |
no | fifo (default), priority, or deadline. |
max_depth |
no | 0 means unlimited. |
overflow_policy |
no | reject (default) or other strategies. |
GET /scopes/{scope_id}/queues#
List queues in a scope. Requires scaiqueue:view.
GET /scopes/{scope_id}/queues/{queue_id}#
Fetch one queue. Requires scaiqueue:view.
GET /scopes/{scope_id}/queues/{queue_id}/stats#
Current depth_current, depth_pending, depth_claimed. Requires scaiqueue:view.
POST /scopes/{scope_id}/queues/{queue_id}/{pause|resume}#
Pause and resume. Requires scaiqueue:manage. Paused queues reject new publishes.
DELETE /scopes/{scope_id}/queues/{queue_id}#
Delete a non-system queue with depth_current == 0. Requires scaiqueue:manage.
Messages#
POST /scopes/{scope_id}/queues/{queue_id}/messages#
Publish. Requires scaiqueue:publish.
| Field | Required | Notes |
|---|---|---|
body |
yes | String or object; objects are JSON-serialised. |
type |
no | message_type; default task. |
priority.tier |
no | critical, high, normal (default), low, background. |
priority.score |
no | 0–1000; default 500. |
labels |
no | {key: value} map. |
content_type |
no | application/json default. |
correlation_id, causation_id, parent_id |
no | Lineage. |
ttl_seconds |
no | If set, expiry enforcer terminalises after this. |
max_retries |
no | Default 3. |
visibility_timeout_s |
no | Default 30. |
idempotency_key |
no | Replays return original message id. |
hitl_spec |
no | Object with rendering spec. |
POST /scopes/{scope_id}/queues/{queue_id}/messages/claim#
Claim messages. Requires scaiqueue:consume. Body: { "batch_size": int, "visibility_timeout_s": int }. Returns a list of full message representations including body and HITL spec.
POST /scopes/{scope_id}/messages/{msg_id}/complete#
Mark complete. Requires scaiqueue:consume. Body: { "response": object | null }. Emits a scaiqueue.message.completed event on the event bus carrying the original correlation_id.
POST /scopes/{scope_id}/messages/{msg_id}/fail#
Mark failed. Requires scaiqueue:consume. Body: { "reason": string }. Triggers retry or dead-letter depending on attempts vs max_retries.
POST /scopes/{scope_id}/messages/{msg_id}/release#
Return a claimed message to pending. Requires scaiqueue:consume.
POST /scopes/{scope_id}/messages/{msg_id}/extend#
Extend the visibility timeout. Requires scaiqueue:consume. Body: { "seconds": int }.
POST /scopes/{scope_id}/messages/{msg_id}/cancel#
Cancel a pending or claimed message. Requires scaiqueue:manage.
GET /scopes/{scope_id}/queues/{queue_id}/messages#
List messages in a queue. Requires scaiqueue:view. Query params: state (one of pending, claimed, completed, failed, dead_lettered, cancelled, expired), limit (default 50), cursor.
GET /scopes/{scope_id}/queues/{queue_id}/messages/{msg_id}#
Full message including body, hitl_spec, response. Requires scaiqueue:view.
GET /scopes/{scope_id}/messages?correlation_id=...#
Return every message in a correlation chain across the scope. Requires scaiqueue:view.
Routing rules#
Rules live on a scope and fire on triggers (message_published is the default). First matching rule (priority ascending) wins; rule actions move/transform messages, with a 5-hop circuit breaker.
POST /scopes/{scope_id}/routing-rules#
Create. Requires scaiqueue:manage. Body: { name, description, priority, enabled, trigger, conditions, action, source }.
GET /scopes/{scope_id}/routing-rules#
List rules in priority-ascending order. Requires scaiqueue:view.
GET /scopes/{scope_id}/routing-rules/{rule_id}#
Fetch one rule. Requires scaiqueue:view.
PATCH /scopes/{scope_id}/routing-rules/{rule_id}#
Update name, description, priority, trigger, conditions, action, enabled. Requires scaiqueue:manage.
DELETE /scopes/{scope_id}/routing-rules/{rule_id}#
Delete. Requires scaiqueue:manage.
POST /scopes/{scope_id}/routing-rules/{rule_id}/{enable|disable}#
Toggle enabled. Requires scaiqueue:manage.
POST /scopes/{scope_id}/routing-rules/test#
Dry-run rules against a hypothetical message. Body: { "trigger": "message_published", "message": { ... } }. Returns the rules that would match. Requires scaiqueue:view.
Streams#
A stream is a sequence of chunk messages that the stream service can assemble.
GET /scopes/{scope_id}/streams#
List streams, optional state filter. Requires scaiqueue:view.
GET /scopes/{scope_id}/streams/{stream_id}#
Stream metadata plus a summary of chunks. Requires scaiqueue:view.
POST /scopes/{scope_id}/streams/{stream_id}/cancel#
Cancel an open stream. Requires scaiqueue:manage.
GET /scopes/{scope_id}/streams/{stream_id}/assembled#
Assembled content (default concatenate mode). Requires scaiqueue:view.
Subscriptions#
A subscription binds a consumer (user, agent) to a queue with a filter and a delivery mode.
POST /scopes/{scope_id}/subscriptions#
Create. Requires scaiqueue:consume. Body fields include subscriber_type, subscriber_id, queue_id, filter, delivery_mode (pull default), auto_claim, max_in_flight.
GET /scopes/{scope_id}/subscriptions#
List for a scope. Requires scaiqueue:view.
GET /scopes/{scope_id}/subscriptions/{sub_id}#
Fetch one. Requires scaiqueue:view.
PATCH /scopes/{scope_id}/subscriptions/{sub_id}#
Update filter, delivery_mode, auto_claim, max_in_flight. Requires scaiqueue:manage.
DELETE /scopes/{scope_id}/subscriptions/{sub_id}#
Delete. Requires scaiqueue:manage.
POST /scopes/{scope_id}/subscriptions/{sub_id}/{pause|resume}#
Toggle active. Requires scaiqueue:manage.
POST /subscriptions/{sub_id}/check-processed#
Return a {message_id: bool} map of which message ids the subscription has already processed (Redis-backed dedup). Requires scaiqueue:consume.
Message schemas#
JSON-Schema definitions per scope. Used to validate payloads.
POST /scopes/{scope_id}/schemas#
Register a schema. Requires scaiqueue:manage. Body: { name, version, schema }.
GET /scopes/{scope_id}/schemas#
List schemas in scope. Requires scaiqueue:view.
GET /scopes/{scope_id}/schemas/{name}/{version}#
Fetch one. Requires scaiqueue:view.
POST /scopes/{scope_id}/schemas/{name}/{version}/validate#
Validate a payload. Body: { "payload": ... }. Returns { valid, errors }. Requires scaiqueue:view.
DELETE /scopes/{scope_id}/schemas/{name}/{version}#
Soft-delete (sets deprecated=true). Requires scaiqueue:manage.
HITL pattern registry#
Reusable rendering specs that messages can reference by name.
POST /scopes/{scope_id}/hitl-patterns#
Register a pattern. Requires scaiqueue:manage. Body: { name, version, spec, parameters }.
GET /scopes/{scope_id}/hitl-patterns#
List. Requires scaiqueue:view.
GET /scopes/{scope_id}/hitl-patterns/{name}/{version}#
Fetch the spec and parameters. Requires scaiqueue:view.
POST /scopes/{scope_id}/hitl-patterns/{name}/expand#
Expand a pattern with parameters (substitutes {{key}} placeholders). Body: { version, parameters }. Requires scaiqueue:view.
ACL#
Per-scope grants, per-queue ACL entries, and cross-scope trust grants. All routes require scaiqueue:manage.
GET /scopes/{scope_id}/acl#
Return { grants, queue_acl, trusted_scopes } for the scope.
POST /scopes/{scope_id}/acl/grants#
Add a scope grant. Body: { actor_type, actor_id, role, conditions }.
DELETE /scopes/{scope_id}/acl/grants/{grant_id}#
Revoke a grant.
POST /scopes/{scope_id}/acl/queue-acl#
Add a per-queue ACL entry. Body: { queue_id, actor_type, actor_id, role, effect, conditions } with effect of allow (default) or deny.
DELETE /scopes/{scope_id}/acl/queue-acl/{entry_id}#
Remove a per-queue ACL entry.
POST /scopes/{scope_id}/acl/trusted-scopes#
Trust another scope for cross-scope routing. Body: { target_scope_id, direction, allowed_types, allowed_queues, identity_mode }.
DELETE /scopes/{scope_id}/acl/trusted-scopes/{trust_id}#
Revoke a cross-scope trust.
API keys#
ScaiQueue-specific API keys for service/agent callers, separate from ScaiGrid's tenant API keys. All routes require scaiqueue:manage.
POST /tenants/{tenant_id}/api-keys#
Mint a key. Body fields include subject_id, subject_type, key_type, label, allowed_scopes, allowed_operations, ip_allowlist, expires_in_days, grace_period_seconds. Returns the raw key once.
GET /tenants/{tenant_id}/api-keys#
List keys.
GET /tenants/{tenant_id}/api-keys/{key_id}#
Fetch metadata for one key.
POST /tenants/{tenant_id}/api-keys/{key_id}/rotate#
Rotate. Returns the new raw key; the old key remains valid for grace_period_seconds.
POST /tenants/{tenant_id}/api-keys/{key_id}/revoke#
Revoke. Body: { reason }.
Audit log#
GET /scopes/{scope_id}/audit#
Query audit events. Filters: event_type, actor_id, resource_type, correlation_id, limit (default 50). Requires scaiqueue:view.
GET /scopes/{scope_id}/audit/trace/{correlation_id}#
Every audit event for a correlation chain, oldest first. Requires scaiqueue:view.
GET /scopes/{scope_id}/audit/stats#
{event_type: count} aggregate over the scope. Requires scaiqueue:view.
System agents#
GET /system-agents#
Status of every system agent (visibility-timeout enforcer, expiry enforcer, archiver, dead-letter monitor, priority-aging worker): status, total_runs, total_processed, total_errors, last_run_at, last_run_duration_ms, last_error. Requires scaiqueue:view.
GDPR#
POST /tenants/{tenant_id}/data-erasure#
Submit an erasure request. Body: { mode, actor_type, actor_id } with mode of redact (default) or other supported modes. Returns a job id. Requires scaiqueue:manage.
GET /tenants/{tenant_id}/data-erasure/jobs/{job_id}#
Job status. Requires scaiqueue:manage.
POST /tenants/{tenant_id}/data-export#
Submit an export request. Requires scaiqueue:manage.
GET /tenants/{tenant_id}/data-export/jobs/{job_id}#
Job status. Requires scaiqueue:manage.
Errors#
All endpoints return ScaiGrid's standard error envelope:
1 2 3 4 5 6 7 8 | |
ScaiQueue-specific codes:
| Code | HTTP | Meaning |
|---|---|---|
SCAIQUEUE_SCOPE_NOT_FOUND |
404 | Scope id doesn't exist or isn't visible. |
SCAIQUEUE_QUEUE_NOT_FOUND |
404 | Queue id doesn't exist or isn't visible. |
SCAIQUEUE_MESSAGE_NOT_FOUND |
404 | Message id doesn't exist or isn't visible. |
SCAIQUEUE_SLUG_CONFLICT |
409 | Scope or queue slug already exists at that level. |
SCAIQUEUE_CLAIM_FAILED |
409 | Claim raced with another consumer. |
SCAIQUEUE_NOT_CLAIMED |
409 | Tried to complete/fail/extend a message that isn't claimed. |
SCAIQUEUE_INVALID_TRANSITION |
409 | Disallowed state transition (e.g. resume an archived scope, delete a non-empty queue, delete a system queue). |
SCAIQUEUE_QUEUE_FULL |
429 | Queue's max_depth reached and overflow_policy=reject. |
SCAIQUEUE_RATE_LIMITED |
429 | Tenant-level rate limit hit. |
SCAIQUEUE_IDEMPOTENCY_CONFLICT |
409 | Idempotency key seen with a different body. |
SCAIQUEUE_SCOPE_PAUSED |
409 | Scope is paused or archived; no publishes accepted. |
SCAIQUEUE_QUEUE_PAUSED |
409 | Queue is paused. |
SCAIQUEUE_ATTACHMENT_ERROR |
500 | Attachment storage failed. |