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.
Sign up at queuelo.com, subscribe to a plan, and create an API key in the dashboard. Your key starts with qlo_.
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"
}'{
"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_keyAPI 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.
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
/api/actionsCreate 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.
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
}'action_type | stringrequired | A short label for the kind of action, e.g. send_email, deploy, delete_user. |
summary | stringrequired | Human-readable summary of what the action will do. Max 200 characters. |
details | string | Longer explanation with context for the approver. Supports any length. |
payload | object | Arbitrary JSON data attached to the action. Max 64 KB. Visible to approvers and included in audit events. |
risk_level | string | One of low, medium, high, or critical. Defaults to medium. |
callback_url | string | An HTTPS URL to receive the decision via POST when the action is approved or rejected. Must use https://. |
idempotency_key | string | A unique key to prevent duplicate submissions. If an action with the same key already exists, the existing action is returned with a 202 status. |
reversibility | string | One of full, partial, or none. Indicates whether the action can be undone. Defaults to none. Used by policy rules to auto-decide actions. |
reasoning | string | A free-text explanation from the agent describing why it wants to take this action. Shown to approvers for context. |
expires_in_seconds | number | Seconds until the action expires automatically. Sets the expires_at timestamp on the action. |
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.
{
"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
}If you resubmit with the same idempotency_key, the API returns the existing action instead of creating a duplicate.
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"status": "pending",
"created_at": "2025-06-14T10:30:00.000Z",
"idempotent": true
}Get actions
/api/actionsRetrieve a paginated list of actions. This endpoint uses session authentication (your browser session from the dashboard), not API key authentication.
curl https://queuelo.com/api/actions?status=pending&limit=10 \
-H "Authorization: Bearer <session_access_token>"status | string | Filter by status: pending, approved, or rejected. Omit to return all. |
risk_level | string | Filter by risk level: low, medium, high, or critical. |
agent_id | string | Filter by agent ID (the key used to submit). |
limit | number | Number of results to return. Default 50, max 200. |
offset | number | Number of results to skip for pagination. Default 0. |
{
"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
/api/actions/:id/decideMake a decision on a pending action. Only team members with the owner, admin, or approver role can decide. This endpoint uses session authentication.
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."
}'decision | stringrequired | Either approved or rejected. |
reason | string | Optional explanation for the decision. Recorded in the audit log. |
{
"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"
}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.
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.
{
"name": "Auto-approve safe actions",
"action_type": null,
"risk_level": "low",
"reversibility": "full",
"decision": "auto_approve",
"priority": 10
}{
"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.
Queuelo sends the following JSON body to 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."
}action_id | string | The ID of the action that was decided. |
status | string | Either approved or rejected. |
action_type | string | The action_type from the original submission. |
decided_at | string | ISO 8601 timestamp of when the decision was made. |
decision_reason | string | null | The reason provided by the approver, or null. |
If your endpoint returns a non-2xx status code or the request times out, Queuelo retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 10 seconds |
| 2nd retry | 20 seconds |
| 3rd retry | Final 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.
Routine operations that are safe to approve quickly. E.g., sending a status update, logging a metric.
Standard actions that warrant a quick review. E.g., sending an email, updating a record. This is the default.
Significant actions that could have meaningful impact. E.g., deploying to production, modifying billing.
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": "A description of what went wrong"
}| Status | Meaning | When it happens |
|---|---|---|
400 | Bad Request | Missing required fields, invalid risk_level, payload too large (> 64 KB), summary exceeds 200 characters, or callback_url doesn't use HTTPS. |
401 | Unauthorized | Missing or invalid API key. Check your Authorization header format: Bearer qlo_xxx. |
403 | Forbidden | Your role doesn't have permission for this action. Deciding requires the owner, admin, or approver role. |
404 | Not Found | The action ID doesn't exist or doesn't belong to your organization. |
409 | Conflict | The action has already been decided. Each action can only be approved or rejected once. |
Need help? Reach out at support@queuelo.com