REST API
The PREQSTATION API is split into two surfaces:
- Bearer-token endpoints for agents
- Session-cookie endpoints for the web UI
Base URL
https://your-domain.com/apiAuthentication
- Bearer token:
Authorization: Bearer <preq_xxxxx>for agent-facing task APIs - Session cookie: used by the web UI after login
See Authentication for setup details.
Bearer-Token Endpoints
These are the endpoints agents use during PREQ execution.
Tasks
| Method | Endpoint | Purpose |
|---|---|---|
GET | /tasks | List tasks |
POST | /tasks | Create a task |
GET | /tasks/:id | Fetch one task by task key or UUID |
PATCH | /tasks/:id | Update fields or run a lifecycle action |
DELETE | /tasks/:id | Delete a task |
PATCH | /tasks/:id/status | Update workflow status only |
Project Settings
| Method | Endpoint | Purpose |
|---|---|---|
GET | /projects/:id/settings | Fetch resolved project settings by project key |
Health
| Method | Endpoint | Purpose |
|---|---|---|
GET | /health | Health check |
Task Endpoints
GET /tasks
curl -H "Authorization: Bearer preq_xxxxx" \ "https://your-domain.com/api/tasks?status=todo&engine=claude-code&label=backend"Query parameters:
status:inbox,todo,hold,ready,done,archivedengine:claude-code,codex,gemini-clilabel: label name
Response shape:
{ "tasks": [ { "id": "PROJ-123", "uuid": "550e8400-e29b-41d4-a716-446655440000", "task_key": "PROJ-123", "status": "todo", "priority": "high", "engine": "claude-code", "run_state": "working", "run_state_updated_at": "2026-03-12T14:10:00.000Z" } ], "available_labels": [ { "name": "backend", "color": "blue" } ]}POST /tasks
Creates a task in inbox by default. The repo value must match a registered project repository URL.
curl -X POST \ -H "Authorization: Bearer preq_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "title": "Add authentication", "description": "Implement JWT auth for API", "repo": "https://github.com/acme/my-app", "engine": "claude-code", "priority": "high", "labels": ["backend", "auth"], "acceptance_criteria": [ "Users can sign up", "Users can log in", "Protected routes require auth" ] }' \ https://your-domain.com/api/tasksGET /tasks/:id
curl -H "Authorization: Bearer preq_xxxxx" \ https://your-domain.com/api/tasks/PROJ-123Response shape:
{ "task": { "id": "PROJ-123", "uuid": "550e8400-e29b-41d4-a716-446655440000", "task_key": "PROJ-123", "title": "Add authentication", "description": "Implement JWT auth for API", "status": "todo", "priority": "high", "repo": "https://github.com/acme/my-app", "branch": "task/proj-123/add-authentication", "engine": "claude-code", "run_state": null, "deploy_strategy": { "strategy": "feature_branch", "default_branch": "main", "auto_pr": true, "commit_on_review": true, "squash_merge": true } }, "available_labels": [ { "name": "backend", "color": "blue" } ]}PATCH /tasks/:id
Use this endpoint for normal lifecycle actions or field updates.
Lifecycle actions:
planstartcompletereviewblock
Example complete call:
curl -X PATCH \ -H "Authorization: Bearer preq_xxxxx" \ -H "Content-Type: application/json" \ -d '{ "lifecycle_action": "complete", "engine": "claude-code", "branch": "preqstation/PROJ/rate-limit", "result": { "summary": "Implemented rate limiting", "tests": "npm test", "pr_url": "https://github.com/acme/my-app/pull/123", "completed_at": "2026-03-12T14:22:00.000Z" } }' \ https://your-domain.com/api/tasks/PROJ-123Common mutable fields:
titledescriptionplanMarkdownpriorityrepobranchlabelsacceptance_criteriaengineresult
PATCH /tasks/:id/status
Manual status-only override:
curl -X PATCH \ -H "Authorization: Bearer preq_xxxxx" \ -H "Content-Type: application/json" \ -d '{"status":"hold","engine":"codex"}' \ https://your-domain.com/api/tasks/PROJ-123/statusAllowed values: inbox, todo, hold, ready, done, archived
GET /projects/:id/settings
The :id parameter is the project key, not the UUID.
curl -H "Authorization: Bearer preq_xxxxx" \ https://your-domain.com/api/projects/PROJ/settingsResponse shape:
{ "settings": { "deploy_strategy": "feature_branch", "deploy_default_branch": "main", "deploy_auto_pr": "true", "deploy_commit_on_review": "true", "deploy_squash_merge": "true" }}Session-Cookie Endpoints
These endpoints are used by projects-manager.
Projects
| Method | Endpoint | Purpose |
|---|---|---|
GET | /projects | List projects |
POST | /projects | Create project |
PATCH | /projects/:id | Update project and project settings |
API Keys
| Method | Endpoint | Purpose |
|---|---|---|
GET | /api-keys | List API keys |
POST | /api-keys | Issue a new API key |
DELETE | /api-keys/:id | Revoke an API key |
Todos and Labels
| Method | Endpoint | Purpose |
|---|---|---|
GET | /todos | List board cards |
POST | /todos | Create board card |
PATCH | /todos/:id | Update board card |
DELETE | /todos/:id | Delete board card |
POST | /todos/rebalance | Rebalance sort order |
POST | /todos/archive-done | Archive done cards |
GET | /task-labels | List task labels |
POST | /task-labels | Create task label |
PATCH | /task-labels/:id | Update task label |
DELETE | /task-labels/:id | Delete task label |
Work Logs and Events
| Method | Endpoint | Purpose |
|---|---|---|
GET | /work-logs | List recent work logs |
POST | /work-logs | Create work log |
PATCH | /work-logs/:id | Update work log |
DELETE | /work-logs/:id | Delete work log |
GET | /events | Read event outbox |
POST | /events/cleanup | Clean old events |
Settings and Messaging
| Method | Endpoint | Purpose |
|---|---|---|
GET | /settings | Read settings page data |
POST | /telegram/send | Send Telegram message |
POST | /telegram/test | Send Telegram test message |
POST | /send-to-openclaw | Legacy OpenClaw relay |
Response Format
Successful responses return plain JSON objects, not a top-level data wrapper. For example:
{ "task": { "id": "PROJ-123", "status": "ready", "run_state": null }}Error Format
Errors usually look like this:
{ "error": "Invalid payload", "issues": []}