Capture GTD exposes a RESTful API built on CQRS principles. Write operations (commands) and read operations (queries) use distinct endpoint patterns. The API is auto-generated from the domain model using OpenAPI 3.1.

Base URL

https://app.capture-gtd.com/api

All endpoints are scoped to an organization:

/api/organizations/{organizationId}/...

The organizationId is a UUID assigned to each user account.

Authentication

Capture GTD uses OAuth 2.0 with Keycloak as the identity provider. The server publishes standard discovery endpoints:

EndpointPurpose
GET /.well-known/oauth-authorization-serverOAuth 2.0 Authorization Server Metadata (RFC 8414)
GET /.well-known/oauth-protected-resourceProtected Resource Metadata (RFC 9728)

Supported grant types: authorization_code, refresh_token

Required scopes: profile, email, organization, offline_access

PKCE: Required. The server supports S256 code challenge method.

Include the access token in the Authorization header:

Authorization: Bearer <access_token>

Request and Response Conventions

  • All request and response bodies use application/json.
  • UUIDs are formatted as strings (e.g., "550e8400-e29b-41d4-a716-446655440000").
  • Timestamps use ISO 8601 format (e.g., "2026-01-15T10:30:00Z").
  • The Accept-Language header (en, de) controls error message localization.
  • Enum values use PascalCase (e.g., "Medium", "XSmall", "Critical").

Write operation responses

HTTP MethodSuccess CodeDescription
POST (create)201 CreatedReturns a Location header with the new resource URL
POST (action)202 AcceptedCommand accepted for processing
PATCH202 AcceptedPartial update accepted
DELETE204 No ContentResource deleted

Error response format

All errors return a JSON body:

{
  "message": "Task name cannot be blank",
  "details": {}
}

Common error codes

CodeMeaning
400Validation error — the request body is invalid or a business rule was violated
401Authentication required or token expired
403Insufficient permissions for the requested organization
404Resource not found
500Internal server error

Tasks

Tasks are the core resource. Each task has a kind that determines its GTD classification: Stuff, Todo, Project, Scheduled, SomedayMaybe, ReferenceFile, or WaitingFor.

Create a task (capture)

POST /api/organizations/{organizationId}/tasks

Creates a new inbox item (Stuff kind). Returns 201 with Location header.

Request body:

FieldTypeRequiredDescription
namestringyesTask title
descriptionstringnoAdditional details (defaults to "")
projectstring (UUID)noParent project ID
importancestringyesExtraLow, Low, Medium, High, or Critical

Clarify a task

POST /api/organizations/{organizationId}/tasks/{taskId}/clarify

Transitions a task from inbox to a clarified state. Returns 202.

Request body:

FieldTypeRequiredDescription
nextStateobjectyesTarget kind (see ClarifyKind below)
namestringnoUpdated name
descriptionstringnoUpdated description
importancestringnoUpdated importance
projectIdstring (UUID)noParent project to assign
contextsarray of strings (UUIDs)noContext IDs to assign
areasOfFocusarray of strings (UUIDs)noArea of focus IDs to assign

Move a task

POST /api/organizations/{organizationId}/tasks/{taskId}/move

Re-classifies an already-clarified task to a different kind. Returns 202.

Request body:

FieldTypeRequiredDescription
nextStateobjectyesTarget kind (see ClarifyKind below)

Complete a task

POST /api/organizations/{organizationId}/tasks/{taskId}/complete

Marks a task as complete. For recurring tasks, pass occurrenceDate to complete a specific occurrence. Returns 202.

Request body:

FieldTypeRequiredDescription
occurrenceDatestring (ISO 8601)noSpecific recurrence occurrence to complete

Reopen a task

POST /api/organizations/{organizationId}/tasks/{taskId}/reopen

Reopens a previously completed task. No request body. Returns 202.

Trash and restore

POST /api/organizations/{organizationId}/tasks/{taskId}/trash
POST /api/organizations/{organizationId}/tasks/{taskId}/restore

Soft-deletes or restores a task. No request body. Returns 202.

Delegate a task

POST /api/organizations/{organizationId}/tasks/{taskId}/delegate

Delegates a task to a person, converting it to WaitingFor state. Returns 202.

Request body:

FieldTypeRequiredDescription
personIdstring (UUID)yesPerson to delegate to

Delete a task

DELETE /api/organizations/{organizationId}/tasks/{taskId}

Permanently deletes a task. Returns 204.

Uncomplete a recurrence

POST /api/organizations/{organizationId}/tasks/{taskId}/uncomplete-recurrence

Reverses a specific recurrence completion. Returns 202.

Request body:

FieldTypeRequiredDescription
occurrenceDatestring (ISO 8601)yesThe occurrence to uncomplete

Update task properties (PATCH)

PATCH /api/organizations/{organizationId}/tasks/{taskId}

Applies a partial update using RFC 6902 JSON Patch format. Returns 202.

Each patch operation specifies op, path, and value:

{ "op": "replace", "path": "/name", "value": "Updated task name" }

Supported patch operations:

PathValue TypeDescription
/namestringTask title
/descriptionstringTask description
/importancestringExtraLow through Critical
/effortstringXSmall, Small, Medium, Large, XLarge
/deadlineobjectDeadline change (see below)
/scheduleobjectSchedule for scheduled tasks
/outcomestringProject outcome statement
/projectstring (UUID) or nullParent project
/waitingForPersonstring (UUID)Delegated person
/contextsuses add/remove opsAdd or remove a context by ID
/areasOfFocususes add/remove opsAdd or remove an area of focus by ID
/dependenciesuses add/remove opsAdd or remove a dependency by ID
/projectToGoaluses add/remove opsLink or unlink project from a goal

Query tasks

GET /api/organizations/{organizationId}/tasks?query={queryName}

Returns an array of TaskView objects. The query parameter selects the list.

Available queries:

QueryParametersDescription
inboxAll unclarified stuff
nextTasksActionable next actions sorted by impact score
engagedTaskscontext?, project?Filtered next actions for the engage view
projectsActive (incomplete, non-trashed) projects
allProjectsAll projects including completed
scheduledAll scheduled items
scheduledBeforedateScheduled items before a given date
somedayMaybeSomeday/maybe items
referenceFilesReference material
waitingForDelegated items
completedTasksAll completed tasks
trashedTrashed tasks
inProjectprojectIdTasks belonging to a project
subProjectsprojectIdSub-projects of a project
blockedTasksInProjectprojectIdTasks blocked by unresolved dependencies
projectsWithoutNextActionsProjects that have no actionable next steps
staleProjectsactivityThresholdProjects with no activity since threshold
tasksDueOnOrBeforedateTasks with deadlines on or before a date
tasksScheduledBetweenstartInclusive, endExclusiveScheduled in a date range
tasksCompletedBetweenstartInclusive, endExclusiveCompleted in a date range
doneOnDatedateTasks completed on a specific date
allTasksEvery task regardless of state
getRecurringTasksAll recurring tasks

Get a single task

GET /api/organizations/{organizationId}/tasks/{taskId}

Returns a single TaskView object or 404.

Get dependency graph

GET /api/organizations/{organizationId}/tasks/{taskId}/dependency-graph

Returns a DependencyGraphView containing all tasks in the dependency chain, their edges, and the root task ID.


Contexts

Contexts represent where or with whom you can act (e.g., @computer, @errands, @office).

EndpointMethodDescription
/api/organizations/{organizationId}/contextsPOSTCreate a context (name required)
/api/organizations/{organizationId}/contexts/{contextId}DELETEDelete a context
/api/organizations/{organizationId}/contexts/{contextId}PATCHUpdate context name (RFC 6902)
/api/organizations/{organizationId}/contextsGETList all contexts
/api/organizations/{organizationId}/contexts/{contextId}GETGet a single context

Areas of Focus

Areas of focus represent life domains to maintain (e.g., Health, Career, Finances).

EndpointMethodDescription
/api/organizations/{organizationId}/area-of-focusesPOSTCreate an area of focus (name required)
/api/organizations/{organizationId}/area-of-focuses/{areaOfFocusId}DELETEDelete an area of focus
/api/organizations/{organizationId}/area-of-focuses/{areaOfFocusId}PATCHUpdate name (RFC 6902)
/api/organizations/{organizationId}/area-of-focusesGETList all areas of focus
/api/organizations/{organizationId}/area-of-focuses/{areaOfFocusId}GETGet a single area of focus

People

People represent contacts for task delegation (WaitingFor).

EndpointMethodDescription
/api/organizations/{organizationId}/personsPOSTCreate a person (name required, email optional)
/api/organizations/{organizationId}/persons/{personId}DELETEDelete a person
/api/organizations/{organizationId}/persons/{personId}PATCHUpdate name/email (RFC 6902)
/api/organizations/{organizationId}/personsGETList all people
/api/organizations/{organizationId}/persons/{personId}GETGet a single person

Goals (Horizon 3)

Goals represent 1-2 year objectives. Projects can be linked to goals.

EndpointMethodDescription
/api/organizations/{organizationId}/goalsPOSTCreate a goal (name required, description optional)
/api/organizations/{organizationId}/goals/{goalId}DELETEDelete a goal
/api/organizations/{organizationId}/goals/{goalId}PATCHUpdate name/description (RFC 6902)
/api/organizations/{organizationId}/goals/{goalId}/completePOSTMark goal complete
/api/organizations/{organizationId}/goals/{goalId}/reopenPOSTReopen a completed goal
/api/organizations/{organizationId}/goalsGETList all goals
/api/organizations/{organizationId}/goals/{goalId}GETGet a single goal

Visions (Horizon 4)

Visions represent 3-5 year life direction.

EndpointMethodDescription
/api/organizations/{organizationId}/visionsPOSTCreate a vision (name required, description optional)
/api/organizations/{organizationId}/visions/{visionId}DELETEDelete a vision
/api/organizations/{organizationId}/visions/{visionId}PATCHUpdate name/description (RFC 6902)
/api/organizations/{organizationId}/visions/{visionId}/completePOSTMark vision complete
/api/organizations/{organizationId}/visions/{visionId}/reopenPOSTReopen a completed vision
/api/organizations/{organizationId}/visionsGETList all visions
/api/organizations/{organizationId}/visions/{visionId}GETGet a single vision

Purpose and Principles (Horizon 5)

The purpose statement and core principles that guide all decisions.

EndpointMethodBodyDescription
/api/organizations/{organizationId}/purpose-and-principleses/{id}PATCH{"op":"replace","path":"/purposeStatement","value":"..."}Set or clear the purpose statement
/api/organizations/{organizationId}/purpose-and-principleses/{id}PATCH{"op":"add","path":"/principles","value":"..."}Add a principle
/api/organizations/{organizationId}/purpose-and-principleses/{id}PATCH{"op":"remove","path":"/principles","value":"..."}Remove a principle
/api/organizations/{organizationId}/purpose-and-principlesesGETGet purpose and principles

Review Analytics

Specialized read-only endpoints for review screens.

EndpointParametersReturns
GET .../reviews/has-stuck-projects{ "hasStuckProjects": boolean }
GET .../reviews/project-progress/{projectId}ProjectProgressDto with completed/incomplete counts
GET .../reviews/analytics/completed-by-contextstartInclusive, endExclusiveCounts of completed tasks by context
GET .../reviews/analytics/completed-by-areastartInclusive, endExclusiveCounts of completed tasks by area of focus
GET .../reviews/analytics/incomplete-by-contextCounts of incomplete tasks by context
GET .../reviews/analytics/incomplete-by-areaCounts of incomplete tasks by area of focus
GET .../reviews/analytics/all-completed-by-contextAll-time completed counts by context
GET .../reviews/analytics/all-completed-by-areaAll-time completed counts by area of focus

All review endpoints are prefixed with /api/organizations/{organizationId}/reviews.


Habits and Recurring Task Analytics

EndpointReturns
GET .../habits-overviewsOverall completion rate, streaks, and per-task analytics
GET .../heatmap-daysDaily completion heatmap data
GET .../trend-data-pointsCompletion rate trends over time
GET .../recurring-task-analyticsesDetailed analytics per recurring task

ClarifyKind Object

The nextState field in clarify and move operations uses a discriminated union with a type field:

TypeAdditional Fields
Stuff(none)
ReferenceFile(none)
SomedayMaybeeffort, dependsOn (array of UUIDs)
Scheduledeffort, schedule ({ "type": "Once", "scheduleDate": "..." } or { "type": "RecurrenceRule", "rrule": "..." })
Projectoutcome, effort, dependsOn, deadline?, goalId?
Todoeffort, dependsOn, deadline?
WaitingForpersonId, effort, dependsOn, deadline?

Deadline variants: { "type": "Once", "due": "2026-03-01T00:00:00Z" } or { "type": "RecurrenceRule", "rrule": "FREQ=WEEKLY;BYDAY=MO" }.

Effort values: XSmall, Small, Medium, Large, XLarge.