Skip to content

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/api

Authentication

  • 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

MethodEndpointPurpose
GET/tasksList tasks
POST/tasksCreate a task
GET/tasks/:idFetch one task by task key or UUID
PATCH/tasks/:idUpdate fields or run a lifecycle action
DELETE/tasks/:idDelete a task
PATCH/tasks/:id/statusUpdate workflow status only

Project Settings

MethodEndpointPurpose
GET/projects/:id/settingsFetch resolved project settings by project key

Health

MethodEndpointPurpose
GET/healthHealth check

Task Endpoints

GET /tasks

Terminal window
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, archived
  • engine: claude-code, codex, gemini-cli
  • label: 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.

Terminal window
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/tasks

GET /tasks/:id

Terminal window
curl -H "Authorization: Bearer preq_xxxxx" \
https://your-domain.com/api/tasks/PROJ-123

Response 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:

  • plan
  • start
  • complete
  • review
  • block

Example complete call:

Terminal window
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-123

Common mutable fields:

  • title
  • description
  • planMarkdown
  • priority
  • repo
  • branch
  • labels
  • acceptance_criteria
  • engine
  • result

PATCH /tasks/:id/status

Manual status-only override:

Terminal window
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/status

Allowed values: inbox, todo, hold, ready, done, archived

GET /projects/:id/settings

The :id parameter is the project key, not the UUID.

Terminal window
curl -H "Authorization: Bearer preq_xxxxx" \
https://your-domain.com/api/projects/PROJ/settings

Response shape:

{
"settings": {
"deploy_strategy": "feature_branch",
"deploy_default_branch": "main",
"deploy_auto_pr": "true",
"deploy_commit_on_review": "true",
"deploy_squash_merge": "true"
}
}

These endpoints are used by projects-manager.

Projects

MethodEndpointPurpose
GET/projectsList projects
POST/projectsCreate project
PATCH/projects/:idUpdate project and project settings

API Keys

MethodEndpointPurpose
GET/api-keysList API keys
POST/api-keysIssue a new API key
DELETE/api-keys/:idRevoke an API key

Todos and Labels

MethodEndpointPurpose
GET/todosList board cards
POST/todosCreate board card
PATCH/todos/:idUpdate board card
DELETE/todos/:idDelete board card
POST/todos/rebalanceRebalance sort order
POST/todos/archive-doneArchive done cards
GET/task-labelsList task labels
POST/task-labelsCreate task label
PATCH/task-labels/:idUpdate task label
DELETE/task-labels/:idDelete task label

Work Logs and Events

MethodEndpointPurpose
GET/work-logsList recent work logs
POST/work-logsCreate work log
PATCH/work-logs/:idUpdate work log
DELETE/work-logs/:idDelete work log
GET/eventsRead event outbox
POST/events/cleanupClean old events

Settings and Messaging

MethodEndpointPurpose
GET/settingsRead settings page data
POST/telegram/sendSend Telegram message
POST/telegram/testSend Telegram test message
POST/send-to-openclawLegacy 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": []
}