Tasks API
The Tasks API works with individual tasks: your personal task overview, reading and updating a task, changing its status (including completion with actual hours), comments, and deletion.
Tasks are created inside a project through
POST /api/v1/projects/:id/tasks,
not through this API. Project-level scheduling operations (dates, estimates,
per-day allocations, and assignees with conflict checks) also live on the
Projects API.
Authentication: every endpoint requires an API key. See API Keys & Authentication.
Requests run in your organisation, and every response uses the standard
{ "success": true, ... } envelope.
The task object
Section titled “The task object”Task endpoints return a task with usage metadata:
{ "id": "4be2d871-...", "name": "Draft homepage copy", "description": "First pass for internal review.", "status": "in_progress", "priority": "high", "projectId": "1f0e9a52-...", "projectName": "Winter Launch", "clientName": "Northwind", "estimatedHours": 6, "actualHours": 5.5, "trackedHours": 4.25, "progress": 60, "plannedStartDate": "2026-07-13T00:00:00.000Z", "plannedEndDate": "2026-07-14T00:00:00.000Z", "actualStartDate": "2026-07-13T01:12:44.000Z", "actualEndDate": null, "completionNotes": null, "commentCount": 3, "tags": ["copy", "homepage"], "metadata": {}, "dueCategory": "today", "dueInDays": 1, "createdAt": "2026-07-10T00:05:31.000Z", "updatedAt": "2026-07-13T02:41:12.000Z"}statusis one ofpending,scheduled,in_progress,completed,cancelled.priorityis one oflow,medium,high,critical.dueCategoryis one ofoverdue,today,upcoming,unscheduled, computed from the planned dates. Completed tasks reportupcoming.dueInDaysis the number of days until the planned end date (negative when overdue), or null when the task has no planned end date.trackedHoursis the total of the task’s time entries.actualHoursis the figure recorded when the task was completed.description,clientName,estimatedHours,actualHours, the date fields,completionNotes, andtagscan be null or absent.
GET /api/v1/tasks/my
Section titled “GET /api/v1/tasks/my”Get an overview of the tasks assigned to you: a summary of counts and hours, plus the full task list grouped for due-date display. Cancelled tasks are excluded.
Any organisation member can call this. It only ever returns your own tasks.
Example request
curl https://api.runnit.io/api/v1/tasks/my \ -H 'Authorization: Bearer rnk_your_key'Response
{ "success": true, "data": { "summary": { "total": 12, "overdue": 1, "dueToday": 2, "upcoming": 6, "completed": 3, "inProgress": 2, "scheduledHours": 64.5, "trackedHours": 38.25 }, "tasks": [ { "id": "4be2d871-...", "name": "Draft homepage copy", "dueCategory": "today" } ] }}tasks contains full task objects as described above, ordered by due date
with completed tasks last. The overdue, dueToday, and upcoming counts
only include tasks that are not completed.
Errors
400if no active organisation can be resolved for your account.
GET /api/v1/tasks/:taskId
Section titled “GET /api/v1/tasks/:taskId”Get one of your assigned tasks by ID.
Any organisation member can call this, but it only resolves tasks assigned to
you. A task assigned to someone else (or to nobody) returns 404.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. Must be assigned to you. |
Example request
curl https://api.runnit.io/api/v1/tasks/<task-id> \ -H 'Authorization: Bearer rnk_your_key'Response
{ "success": true, "task": { "id": "4be2d871-...", "name": "Draft homepage copy", "status": "in_progress" } }Errors
404if the task does not exist, is deleted, is in another organisation, or is not assigned to you.
PATCH /api/v1/tasks/:taskId
Section titled “PATCH /api/v1/tasks/:taskId”Update a task’s fields. Send only the fields you want to change.
The task’s assignee or the project owner can call this.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. |
Request body (all optional)
| Name | Type | Required | Description |
|---|---|---|---|
| name | string | No | New name. Must not be empty. |
| description | string | No | Task description. |
| priority | string | No | low, medium, high, or critical. |
| progress | integer | No | 0 to 100. |
| estimatedHours | number | No | 0 to 1000. |
| plannedStartDate | ISO 8601 date | No | Planned start. |
| plannedEndDate | ISO 8601 date | No | Planned end. |
| tags | array of strings | No | Replaces the full tag list. |
| assignedToId | string or null | No | New assignee’s user ID. Null unassigns the task. |
Example request
curl -X PATCH https://api.runnit.io/api/v1/tasks/<task-id> \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "priority": "critical", "progress": 75 }'Response
{ "success": true, "task": { "id": "4be2d871-...", "priority": "critical", "progress": 75 } }Errors
400if a field fails validation (empty name, progress outside 0 to 100, estimated hours outside 0 to 1000, invalid priority or date).404if the task does not exist, is deleted, or is in another organisation.403if you are neither the task’s assignee nor the project owner.
PATCH /api/v1/tasks/:taskId/status
Section titled “PATCH /api/v1/tasks/:taskId/status”Change a task’s status. Completing a task can also record the actual hours spent and a completion note.
Only the task’s assignee can call this, even for project owners and organisation admins. (Owners and admins can change assignees through the Projects API.)
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. Must be assigned to you. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| status | string | Yes | One of pending, scheduled, in_progress, completed, cancelled. |
| actualHours | number | No | 0 to 1000. Recorded with completion. |
| completionNotes | string | No | Up to 2000 characters. |
Completing a task sets its progress to 100 and records the work in your
portfolio history. If you supply actualHours with completion, Runnit also
creates (or updates) a draft time entry for those hours against the task.
Example request
curl -X PATCH https://api.runnit.io/api/v1/tasks/<task-id>/status \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "status": "completed", "actualHours": 5.5, "completionNotes": "Copy approved by the internal review." }'Response
{ "success": true, "task": { "id": "4be2d871-...", "status": "completed", "progress": 100, "actualHours": 5.5 } }Errors
400ifstatusis missing or invalid,actualHoursis out of range, orcompletionNotesexceeds 2000 characters.404if the task does not exist, is deleted, or is in another organisation.403if you are not the task’s assignee (“You are not authorized to update this task”).
GET /api/v1/tasks/:taskId/comments
Section titled “GET /api/v1/tasks/:taskId/comments”List a task’s comments, including who wrote each one.
Any organisation member can call this for tasks in their organisation.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. |
Example request
curl https://api.runnit.io/api/v1/tasks/<task-id>/comments \ -H 'Authorization: Bearer rnk_your_key'Response
{ "success": true, "comments": [ { "id": "b7e13f90-...", "taskId": "4be2d871-...", "userId": "d3a6f0c1-...", "commentText": "First draft is up for review.", "metadata": {}, "createdAt": "2026-07-13T02:41:12.000Z", "updatedAt": "2026-07-13T02:41:12.000Z", "user": { "id": "d3a6f0c1-...", "name": "Alex Chen", "email": "alex@example.com" } } ]}metadata and the user’s avatarUrl can be absent.
Errors
404if the task does not exist, is deleted, or is in another organisation.
POST /api/v1/tasks/:taskId/comments
Section titled “POST /api/v1/tasks/:taskId/comments”Add a comment to a task.
Any organisation member can call this for tasks in their organisation.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. |
Request body
| Name | Type | Required | Description |
|---|---|---|---|
| commentText | string | Yes | Comment body. Must not be empty. |
| metadata | object | No | Free-form metadata stored with the comment. |
Example request
curl -X POST https://api.runnit.io/api/v1/tasks/<task-id>/comments \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "commentText": "First draft is up for review." }'Response
Returns 201 with the task’s full comment list, including the new comment,
in the same shape as the list endpoint above.
Errors
400ifcommentTextis missing or empty, or no active organisation can be resolved for your account.404if the task does not exist, is deleted, or is in another organisation.
DELETE /api/v1/tasks/:taskId
Section titled “DELETE /api/v1/tasks/:taskId”Delete a task.
The task’s assignee or the project owner can call this.
Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
| taskId | UUID | Yes | Task ID. |
Example request
curl -X DELETE https://api.runnit.io/api/v1/tasks/<task-id> \ -H 'Authorization: Bearer rnk_your_key'Response
{ "success": true, "message": "Task deleted successfully" }Errors
404if the task does not exist, is already deleted, or is in another organisation.403if you are neither the task’s assignee nor the project owner (“Only the task assignee or project owner can delete tasks”).
Common workflows
Section titled “Common workflows”A typical task lifecycle, end to end. Replace the placeholders with real IDs.
- Create the task in its project (tasks always belong to a project):
curl -X POST https://api.runnit.io/api/v1/projects/<project-id>/tasks \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "name": "Draft homepage copy", "priority": "high", "estimatedHours": 6 }'- Assign it (use the assignee options endpoint to find valid assignees first):
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/tasks/<task-id>/assignee \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "assignedToId": "<user-uuid>" }'- Move its dates when the plan changes (this rebuilds the working-day schedule):
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/tasks/<task-id>/dates \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "plannedStartDate": "2026-07-20" }'- Mark it complete with actual hours (as the assignee):
curl -X PATCH https://api.runnit.io/api/v1/tasks/<task-id>/status \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "status": "completed", "actualHours": 5.5 }'- Comment on the outcome:
curl -X POST https://api.runnit.io/api/v1/tasks/<task-id>/comments \ -H 'Authorization: Bearer rnk_your_key' \ -H 'Content-Type: application/json' \ -d '{ "commentText": "Done. Final copy is in the shared collection." }'Next steps
Section titled “Next steps”Create and schedule tasks through the Projects API, or read team schedules through the Scheduling API.