Tasks

Completing tasks by API, MCP and CLI

List assigned tasks and complete them with an outcome and field values from your own application, an AI client or a script.

Completing a task from outside the app does exactly what the outcome button does: field values are validated and saved, the completion rule is applied, and a waiting workflow resumes on the outcome's path (asynchronously, through the queue).

REST

bash
# tasks assigned to the calling user (user-context key or OAuth token)
curl -H "Authorization: Bearer $USERTASKS_API_KEY" "$USERTASKS_URL/api/v1/tasks/assigned"

# complete one
curl -X POST "$USERTASKS_URL/api/v1/tasks/<task-id>/action" \
  -H "Authorization: Bearer $USERTASKS_API_KEY" -H "Content-Type: application/json" \
  -d '{"action":"complete","outcome":"Approved","outcome_notes":"Within budget","values":{"cost_centre":"OPS","amount":12400}}'
# → { "success": true, "data": { "action": "completed", "outcome": "Approved", "workflow_resumed": true, "workflow_status": "queued", "run_id": "…" } }

action is one of accept, hold, reject, complete, escalate or redirect (with target_user_id(s) or target_email(s)). On a multi-assignee task, complete may return { "action": "waiting", "responses": 1, "needed": 2 } until the completion rule is met.

Descriptions in API responses

Task responses keep description as stored (sanitised HTML or plain text) and add description_text (plain text). If your client cannot render HTML, add ?strip_html=true to GET /tasks, /tasks/assigned or /tasks/{id}, and description comes back as plain text. MCP tasks_get takes strip_html: true. The CLI always asks for plain text; pass --html to see the stored HTML.

CLI

bash
usertasks tasks assigned
usertasks tasks complete <task-id> --outcome Approved --notes "Within budget" --set cost_centre=OPS --set amount:=12400

MCP

AI clients use tasks_list, tasks_get, tasks_respond, tasks_complete_workflow (complete with an outcome and field values), tasks_redirect and tasks_escalate. The same permissions apply: tasks.complete to act, and a user-context credential can only act on tasks that user can see.

SDK

ts
await client.POST('/tasks/{id}/action', {
  path: { id: taskId },
  body: { action: 'complete', outcome: 'Approved', values: { cost_centre: 'OPS' } },
})