API REFERENCE
Update Project Task
On this page
/api/projects/{projectId}/tasks/{taskId}Update a task. Send only the fields that change.
Completion is toggled with the completed boolean rather than by writing a timestamp: the server stamps completed_at and records completed_by from the authenticated account, so it is never ambiguous who closed an item. Any collaborator may toggle any task, including the client.
Authentication
x-api-key in header
bearerAuth bearer
Request
curl --request PATCH \
--url 'https://api.recoupable.dev/api/projects/YOUR_PROJECT_ID/tasks/YOUR_TASK_ID' \
--header 'x-api-key: YOUR_API_KEY' \
--header 'Content-Type: application/json' \
--data '{
"completed": true
}'Replace the YOUR_ placeholders with your values. Required query parameters are included; optional parameters are listed below.
Parameters
Path parameters
projectIdstringrequiredThe project's UUID.
taskIdstringrequiredThe task's UUID.
Request body required
The fields to change.
application/json
titlestringminLength: 1
descriptionstringnullabledue_datestringnullableformat: date
assignee_account_idstringnullableformat: uuid
completedbooleantrue stamps completed_at with the current time and completed_by with the authenticated account. false clears both. This is the only way to change completion; completed_at is not writable directly.
Mark complete
{
"completed": true
}Reopen
{
"completed": false
}Change the due date
{
"due_date": "2026-09-19"
}Responses
200Task updated.+
application/json
statusstringrequiredtaskobjectrequiredProperties for task
idstringrequiredformat: uuid
project_idstringrequiredformat: uuid
titlestringrequireddescriptionstringnullabledue_datestringnullableA calendar date with no time of day, e.g. 2026-09-12.
format: date
assignee_account_idstringnullableWho the task is waiting on. A client renders its "needs you" treatment when this matches the viewing account.
format: uuid
completed_atstringnullableNull means the task is not complete. There is no separate boolean.
format: date-time
completed_bystringnullableformat: uuid
comment_countintegerNumber of comments on this task. Present on the project read so a list can render a count without a call per task.
format: int32
created_atstringrequiredAlso the sort key: tasks come back oldest first.
format: date-time
updated_atstringformat: date-time
400Bad request — invalid path parameter or request body.+
application/json
statusstring · enumrequiredAlways "error" for error responses.
Values: "error"
errorstringrequiredHuman-readable error message.
messagestringCarries the message in place of error when the failure comes from the authentication layer, so a 401 raised while verifying the credential reads message and every other error reads error.
401Unauthorized — missing or invalid credentials.+
application/json
statusstring · enumrequiredAlways "error" for error responses.
Values: "error"
errorstringrequiredHuman-readable error message.
messagestringCarries the message in place of error when the failure comes from the authentication layer, so a 401 raised while verifying the credential reads message and every other error reads error.
404Not found — either no project or task with this id exists, or the authenticated account is not a collaborator on it. The two cases are deliberately indistinguishable so the response cannot be used to discover which project ids are real.+
application/json
statusstring · enumrequiredAlways "error" for error responses.
Values: "error"
errorstringrequiredHuman-readable error message.
messagestringCarries the message in place of error when the failure comes from the authentication layer, so a 401 raised while verifying the credential reads message and every other error reads error.
500Internal server error.+
application/json
statusstring · enumrequiredAlways "error" for error responses.
Values: "error"
errorstringrequiredHuman-readable error message.
messagestringCarries the message in place of error when the failure comes from the authentication layer, so a 401 raised while verifying the credential reads message and every other error reads error.
Full specification
Download the OpenAPI file for complete schemas, constraints, and examples.
Download projects.jsonView operation source
{
"summary": "Update project task",
"description": "Update a task. Send only the fields that change.\n\nCompletion is toggled with the `completed` boolean rather than by writing a timestamp: the server stamps `completed_at` and records `completed_by` from the authenticated account, so it is never ambiguous who closed an item. Any collaborator may toggle any task, including the client.",
"security": [
{
"apiKeyAuth": []
},
{
"bearerAuth": []
}
],
"parameters": [
{
"name": "projectId",
"in": "path",
"required": true,
"description": "The project's UUID.",
"schema": {
"type": "string",
"format": "uuid"
}
},
{
"name": "taskId",
"in": "path",
"required": true,
"description": "The task's UUID.",
"schema": {
"type": "string",
"format": "uuid"
}
}
],
"requestBody": {
"description": "The fields to change.",
"required": true,
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/UpdateProjectTaskRequest"
},
"examples": {
"markComplete": {
"summary": "Mark complete",
"value": {
"completed": true
}
},
"markIncomplete": {
"summary": "Reopen",
"value": {
"completed": false
}
},
"reschedule": {
"summary": "Change the due date",
"value": {
"due_date": "2026-09-19"
}
}
}
}
}
},
"responses": {
"200": {
"description": "Task updated.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/ProjectTaskMutationResponse"
}
}
}
},
"400": {
"description": "Bad request — invalid path parameter or request body.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"401": {
"description": "Unauthorized — missing or invalid credentials.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"404": {
"description": "Not found — either no project or task with this id exists, or the authenticated account is not a collaborator on it. The two cases are deliberately indistinguishable so the response cannot be used to discover which project ids are real.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
},
"500": {
"description": "Internal server error.",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/Error"
}
}
}
}
}
}