REST API

Base URL: https://rest.qpub.io/v1

JSON fields use snake_case.

Authentication

SchemeHeader / query
API keyAuthorization: Basic <base64(publicId:secret)> or api_key
JWTAuthorization: Bearer <jwt> or access_token

Optional: X-Alias: <alias>.

Token issue requires API key auth. Token request uses a signed body (no Basic header).

Tokens

Issue JWT

POST /v1/key/:keyID/token/issue

Body (optional, camelCase): alias, permission, expiresIn (seconds).

200: { "token": "<jwt>" }

Exchange token request

POST /v1/key/:keyID/token/request

Body: aki, timestamp, optional alias / permission, signature. Prefer SDK createTokenRequest / requestToken.

200: { "token": "<jwt>" }

Publish

One channel

POST /v1/channel/:channelName/messages
{
  "messages": [
    { "event": "greeting", "data": { "text": "Hello" }, "alias": "api" }
  ]
}

201 response shape:

{
  "published": [
    {
      "channel": "demo",
      "message_id": "...",
      "published_at": "2026-07-16T00:00:00Z",
      "payload_count": 1
    }
  ]
}

Many channels

POST /v1/channels/messages
{
  "channels": ["a", "b"],
  "messages": [{ "data": { "ok": true } }]
}

Partial failure may return 207 with an error envelope (code: PARTIAL_CONTENT) whose details include published and failed_channels. Rate limits return 429.

Queues

MethodPathNotes
PUT/v1/queue/:queueNameCreate if missing (max_attempts, webhooks); existing queues returned unchanged
GET/v1/queue/:queueNameRead config
POST/v1/queue/:queueName/jobsEnqueue
GET/v1/queue/:queueName/jobsList (?status=)
GET/v1/queue/:queueName/jobs/:jobIdGet job
DELETE/v1/queue/:queueName/jobs/:jobIdCancel
POST/v1/queue/:queueName/jobs/:jobId/retryRetry
POST/v1/queue/:queueName/pullPull jobs
POST/v1/queue/:queueName/jobs/:jobId/ackAck
POST/v1/queue/:queueName/jobs/:jobId/nackNack
POST/v1/workers/registerRegister worker
POST/v1/workers/heartbeatHeartbeat

See Queue for request bodies and SDK usage.

Health

GET /health
→ { "status": "healthy" }

Errors

Error responses use an HTTP status and a JSON body with code and message (for example UNAUTHORIZED, FORBIDDEN, RATE_LIMITED, BAD_REQUEST). Some responses include a details field.