QueueloQueuelo
HomeDashboardDocumentationAPI KeysTeamAccountPricingHow it works
Sign inStart Pro — $19/mo

API Reference

Everything you need to integrate Queuelo into your AI agent. Submit actions, receive decisions, get notified via callbacks.

Quick start

Go from zero to your first approval in three steps.

1
Get your API key

Sign up at queuelo.com, subscribe to a plan, and create an API key in the dashboard. Your key starts with qlo_.

2
Submit your first action
Terminal
curl -X POST https://queuelo.com/api/actions \
  -H "Authorization: Bearer qlo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "action_type": "send_email",
    "summary": "Send invoice to client@acme.com",
    "details": "Invoice #1042 for $2,400 — 30 days overdue",
    "risk_level": "medium"
  }'
3
Check the response
Response · 201 Created
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "created_at": "2025-06-14T10:30:00.000Z",
  "expires_at": null
}

Your action is now queued. A team member will approve or reject it from the dashboard, and you'll be notified via callback if you provided a callback_url.

Authentication

All API requests are authenticated with an API key. Include it as a Bearer token in the Authorization header.

Authorization: Bearer qlo_your_api_key

API keys are created in the API Keys section of your dashboard. Keys are scoped to your organization — any key can submit actions on behalf of your team.

How keys are stored

Keys are hashed with SHA-256 before storage. The full key is shown only once at creation time. The dashboard displays a qlo_ prefix so you can identify which key is which.

Submit an action

POST/api/actions

Create an action request that your team can approve or reject from the Queuelo dashboard. The action stays in pending status until a team member with the owner, admin, or approver role makes a decision.

Request
curl -X POST https://queuelo.com/api/actions \
  -H "Authorization: Bearer qlo_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "action_type": "deploy",
    "summary": "Deploy v2.4.1 to production",
    "details": "Includes database migration for users table. Estimated 30s downtime.",
    "reasoning": "Sprint 12 is complete and all tests pass. Deploying to ship the new billing flow.",
    "reversibility": "partial",
    "payload": {
      "version": "2.4.1",
      "environment": "production",
      "commit": "a1b2c3d"
    },
    "risk_level": "high",
    "callback_url": "https://your-app.com/webhooks/queuelo",
    "idempotency_key": "deploy-v2.4.1-prod",
    "expires_in_seconds": 3600
  }'
Request body
action_typestringrequiredA short label for the kind of action, e.g. send_email, deploy, delete_user.
summarystringrequiredHuman-readable summary of what the action will do. Max 200 characters.
detailsstringLonger explanation with context for the approver. Supports any length.
payloadobjectArbitrary JSON data attached to the action. Max 64 KB. Visible to approvers and included in audit events.
risk_levelstringOne of low, medium, high, or critical. Defaults to medium.
callback_urlstringAn HTTPS URL to receive the decision via POST when the action is approved or rejected. Must use https://.
idempotency_keystringA unique key to prevent duplicate submissions. If an action with the same key already exists, the existing action is returned with a 202 status.
reversibilitystringOne of full, partial, or none. Indicates whether the action can be undone. Defaults to none. Used by policy rules to auto-decide actions.
reasoningstringA free-text explanation from the agent describing why it wants to take this action. Shown to approvers for context.
expires_in_secondsnumberSeconds until the action expires automatically. Sets the expires_at timestamp on the action.
Response

If a matching policy rule auto-decides the action, the response will show auto_decided: true and the matched_policy_id. The status will be approved or rejected immediately.

201 Created
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "created_at": "2025-06-14T10:30:00.000Z",
  "expires_at": "2025-06-14T11:30:00.000Z",
  "auto_decided": false,
  "matched_policy_id": null
}
Idempotent response

If you resubmit with the same idempotency_key, the API returns the existing action instead of creating a duplicate.

202 Accepted
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "pending",
  "created_at": "2025-06-14T10:30:00.000Z",
  "idempotent": true
}

Get actions

GET/api/actions

Retrieve a paginated list of actions. This endpoint uses session authentication (your browser session from the dashboard), not API key authentication.

Request
curl https://queuelo.com/api/actions?status=pending&limit=10 \
  -H "Authorization: Bearer <session_access_token>"
Query parameters
statusstringFilter by status: pending, approved, or rejected. Omit to return all.
risk_levelstringFilter by risk level: low, medium, high, or critical.
agent_idstringFilter by agent ID (the key used to submit).
limitnumberNumber of results to return. Default 50, max 200.
offsetnumberNumber of results to skip for pagination. Default 0.
Response · 200 OK
{
  "items": [
    {
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "action_type": "send_email",
      "summary": "Send invoice to client@acme.com",
      "details": "Invoice #1042 for $2,400",
      "risk_level": "medium",
      "status": "pending",
      "created_at": "2025-06-14T10:30:00.000Z",
      "decided_at": null,
      "expires_at": null,
      "decided_by_user_id": null,
      "decision_reason": null,
      "callback_url": null,
      "callback_status": null,
      "callback_attempts": 0,
      "agent_id": "key-uuid",
      "payload_json": null
    }
  ],
  "count": 42,
  "limit": 50,
  "offset": 0
}

Decide on an action

POST/api/actions/:id/decide

Make a decision on a pending action. Only team members with the owner, admin, or approver role can decide. This endpoint uses session authentication.

Request
curl -X POST https://queuelo.com/api/actions/a1b2c3d4-e5f6-7890-abcd-ef1234567890/decide \
  -H "Authorization: Bearer <session_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "decision": "approved",
    "reason": "Looks good, deploy is clear to proceed."
  }'
Request body
decisionstringrequiredEither approved or rejected.
reasonstringOptional explanation for the decision. Recorded in the audit log.
Response · 200 OK
{
  "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "approved",
  "decided_at": "2025-06-14T10:35:22.000Z",
  "decided_by_email": "admin@acme.com",
  "decided_by_role": "admin"
}
What happens next

If the action had a callback_url, Queuelo immediately POSTs the decision to that URL. The decision is also recorded in your audit log.

Policy rules

Policy rules let you automate approval decisions. Define conditions on action_type, risk_level, and reversibility — when an incoming action matches, it's automatically approved, rejected, or routed for manual review.

How matching works

Rules are evaluated by priority (highest first). The first matching rule wins. If no rules match, the action requires manual approval (default behavior).

The action_type condition supports trailing wildcards — e.g. send_* matches send_email, send_sms, etc. Set a condition to null (or omit it) to match any value.

Example rules
Auto-approve low-risk reversible actions
{
  "name": "Auto-approve safe actions",
  "action_type": null,
  "risk_level": "low",
  "reversibility": "full",
  "decision": "auto_approve",
  "priority": 10
}
Block all critical actions
{
  "name": "Block critical",
  "action_type": null,
  "risk_level": "critical",
  "reversibility": null,
  "decision": "auto_reject",
  "priority": 100
}

Manage policy rules from the Policies page in your dashboard, or via the POST /api/policies endpoint (owner/admin only).

Callbacks

When you include a callback_url on an action, Queuelo sends a POST request to that URL as soon as the action is approved or rejected. This lets your agent react to decisions without polling.

Callback payload

Queuelo sends the following JSON body to your callback URL:

POST → your callback_url
{
  "action_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "status": "approved",
  "action_type": "deploy",
  "decided_at": "2025-06-14T10:35:22.000Z",
  "decision_reason": "Looks good, deploy is clear to proceed."
}
Callback fields
action_idstringThe ID of the action that was decided.
statusstringEither approved or rejected.
action_typestringThe action_type from the original submission.
decided_atstringISO 8601 timestamp of when the decision was made.
decision_reasonstring | nullThe reason provided by the approver, or null.
Retry behavior

If your endpoint returns a non-2xx status code or the request times out, Queuelo retries with exponential backoff:

AttemptDelay
1st retry10 seconds
2nd retry20 seconds
3rd retryFinal attempt — no further retries

After 3 failed attempts, the callback is marked as failed. You can check callback status in the dashboard or via the GET /api/actions response (callback_status and callback_attempts fields).

Risk levels

Every action has a risk level that helps approvers prioritize their review queue. Set it when submitting an action — it defaults to medium if omitted.

low

Routine operations that are safe to approve quickly. E.g., sending a status update, logging a metric.

medium

Standard actions that warrant a quick review. E.g., sending an email, updating a record. This is the default.

high

Significant actions that could have meaningful impact. E.g., deploying to production, modifying billing.

critical

Irreversible or high-stakes actions. E.g., deleting data, transferring funds, revoking access.

Error codes

The API returns standard HTTP status codes. Error responses include a JSON body with a human-readable error message.

Error response format
{
  "error": "A description of what went wrong"
}
StatusMeaningWhen it happens
400Bad RequestMissing required fields, invalid risk_level, payload too large (> 64 KB), summary exceeds 200 characters, or callback_url doesn't use HTTPS.
401UnauthorizedMissing or invalid API key. Check your Authorization header format: Bearer qlo_xxx.
403ForbiddenYour role doesn't have permission for this action. Deciding requires the owner, admin, or approver role.
404Not FoundThe action ID doesn't exist or doesn't belong to your organization.
409ConflictThe action has already been decided. Each action can only be approved or rejected once.

Need help? Reach out at support@queuelo.com