Skip to content

Tasks API

All task endpoints require authentication.

GET /tasks

List tasks with optional filters. Returns tasks visible to the current user (personal + household tasks based on visibility settings).

Auth required: Yes

Query parameters:

ParamTypeDescription
statusstringoverdue, this_week, upcoming, completed, all. Default: incomplete only
category_idintegerFilter by category
qstringSearch title and description (ILIKE)
shared_onlystringtrue to show only household tasks
include_archivedstringtrue to include archived tasks
user_datestringUser's local date (YYYY-MM-DD). Default: server date

Response (200):

json
{
  "tasks": [
    {
      "id": 1,
      "title": "Renew passport",
      "description": "Need photos first",
      "due_date": "2026-06-15",
      "due_time": "10:00:00",
      "completed": false,
      "overdue": false,
      "recurring": true,
      "repeat_interval_months": 120,
      "repeat_interval_days": null,
      "weekdays_only": false,
      "reminder_days": [7, 30],
      "last_completed_at": null,
      "completion_count": 0,
      "category": {
        "id": 1,
        "name": "Documents",
        "icon_key": "file-text"
      },
      "creator": { "id": 1, "name": "Jane" },
      "assigned_to": null,
      "is_mine": true,
      "archived": false,
      "archived_at": null,
      "created_at": "2026-05-26T10:00:00Z",
      "updated_at": "2026-05-26T10:00:00Z"
    }
  ],
  "meta": {
    "overdue_count": 2,
    "this_week_count": 5,
    "total_count": 12
  }
}
bash
curl "http://localhost:3000/api/v1/tasks?status=this_week&user_date=2026-05-26" \
  -H "Authorization: Bearer <token>"

POST /tasks

Create a new task.

Auth required: Yes

Request body:

json
{
  "title": "Renew passport",
  "description": "Need photos first",
  "due_date": "2026-06-15",
  "due_time": "10:00:00",
  "category_id": 1,
  "repeat_interval_months": 120,
  "repeat_interval_days": null,
  "weekdays_only": false,
  "reminder_days": [7, 30],
  "assigned_to_id": null
}

Response (201):

json
{
  "task": { ... }
}

Errors:

StatusCause
403Task limit reached (free tier, max 10)
422Validation failed, or invalid household assignment
bash
curl -X POST http://localhost:3000/api/v1/tasks \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"title":"Renew passport","due_date":"2026-06-15","category_id":1}'

GET /tasks/:id

Get a single task.

Auth required: Yes

Response (200):

json
{
  "task": { ... }
}
bash
curl http://localhost:3000/api/v1/tasks/1 \
  -H "Authorization: Bearer <token>"

PATCH /tasks/:id

Update a task. Only send the fields you want to change.

Auth required: Yes

Request body:

json
{
  "title": "Renew passport (expedited)",
  "due_date": "2026-06-01"
}

Response (200):

json
{
  "task": { ... }
}
bash
curl -X PATCH http://localhost:3000/api/v1/tasks/1 \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"due_date":"2026-06-01"}'

DELETE /tasks/:id

Delete a task permanently.

Auth required: Yes

Response: 204 No Content

bash
curl -X DELETE http://localhost:3000/api/v1/tasks/1 \
  -H "Authorization: Bearer <token>"

POST /tasks/:id/complete

Mark a task as complete. For recurring tasks, this advances the due date instead of marking it done.

Auth required: Yes

Response (200):

json
{
  "task": { ... },
  "message": "Task completed",
  "level_up": false,
  "user": {
    "total_points": 86,
    "level_number": 4,
    "level_name": "growing",
    "level_icon": "🌲",
    "points_to_next_level": 64
  }
}

When a recurring task was overdue, the response may include a reschedule suggestion:

json
{
  "reschedule_suggestion": {
    "current_interval_days": 14,
    "suggested_interval_days": 21,
    "reason": "You typically complete this every 21 days"
  }
}
bash
curl -X POST http://localhost:3000/api/v1/tasks/1/complete \
  -H "Authorization: Bearer <token>"

POST /tasks/:id/archive

Archive a task (hide from default list, can be restored).

Auth required: Yes

Response (200):

json
{
  "task": { ... },
  "message": "Task archived"
}
bash
curl -X POST http://localhost:3000/api/v1/tasks/1/archive \
  -H "Authorization: Bearer <token>"

POST /tasks/:id/unarchive

Restore an archived task.

Auth required: Yes

Response (200):

json
{
  "task": { ... },
  "message": "Task restored"
}
bash
curl -X POST http://localhost:3000/api/v1/tasks/1/unarchive \
  -H "Authorization: Bearer <token>"

GET /tasks/monthly_stats

Get completion count for a given month. Used by the calendar view.

Auth required: Yes

Query parameters:

ParamTypeDescription
monthstringFormat YYYY-MM. Default: current month

Response (200):

json
{
  "month": "2026-05",
  "completions_count": 23
}
bash
curl "http://localhost:3000/api/v1/tasks/monthly_stats?month=2026-05" \
  -H "Authorization: Bearer <token>"

PATCH /tasks/:id/reschedule

Change the recurrence interval of a recurring task.

Auth required: Yes

Request body (one of):

json
{
  "interval_days": 21
}
json
{
  "interval_months": 3
}

Response (200):

json
{
  "task": { ... }
}

Errors:

StatusCause
400Neither interval_days nor interval_months provided
422Task is not recurring
bash
curl -X PATCH http://localhost:3000/api/v1/tasks/1/reschedule \
  -H "Authorization: Bearer <token>" \
  -H "Content-Type: application/json" \
  -d '{"interval_days":21}'

Internal documentation — not for public distribution