Skip to content

Projects API

The Projects API covers the full project lifecycle: listing and creating projects, reading a project and its details, updating fields, statuses, budgets, and colours, working with milestones and the project history feed, creating and scheduling tasks inside a project, and deleting a project with all of its related data.

Authentication: every endpoint requires an API key. See API Keys & Authentication. All examples use the Authorization: Bearer rnk_your_key header.

All requests run inside the organisation your key belongs to. Successful responses use the standard envelope described in the REST API Overview, for example { "success": true, "project": { ... } }. Validation failures return 400 with details of the invalid fields.

These values appear throughout this page:

FieldValid values
Project statusdraft, active, review_internal, client_review, done, on_hold, completed, cancelled, archived
Project stagediscovery, planning, design, development, testing, review, deployment, maintenance
Project colorguava, mandarin, matcha, acai, coffee, guava-dark, mandarin-dark, matcha-dark, acai-dark, coffee-dark
Task prioritylow, medium, high, critical
Task statuspending, scheduled, in_progress, completed, cancelled

Dates are ISO 8601 strings. IDs are UUIDs.

List the projects in your organisation, newest first, with pagination.

Any organisation member can call this. Admins and owners see every project. Other members see internal projects plus projects for the clients they are assigned to (members with no client restrictions see everything).

Query parameters

NameTypeRequiredDescription
statusstringNoFilter by project status. See the field reference above.
stagestringNoFilter by project stage. See the field reference above.
limitintegerNoPage size, 1 to 100. Defaults to 50.
offsetintegerNoNumber of projects to skip. Defaults to 0.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/projects?status=active&limit=20' \
-H 'Authorization: Bearer rnk_your_key'

Response

{
"success": true,
"projects": [
{
"id": "1f0e9a52-...",
"organizationId": "8c2d41b7-...",
"jobNumber": "RB-2026-014",
"name": "Winter Launch",
"description": "Delivery workspace for the winter campaign.",
"status": "active",
"stage": "planning",
"ownerId": "d3a6f0c1-...",
"budget": 75000,
"budgetCurrency": "AUD",
"startDate": "2026-07-01T00:00:00.000Z",
"targetCompletionDate": "2026-08-31T00:00:00.000Z",
"clientOrganizationId": "b91c77e4-...",
"color": "matcha",
"tags": [],
"createdAt": "2026-06-20T02:14:09.000Z",
"updatedAt": "2026-07-01T04:33:52.000Z"
}
],
"pagination": { "total": 42, "limit": 20, "offset": 0, "hasMore": true }
}

budget, startDate, targetCompletionDate, clientOrganizationId, color, summary, and description can be null or absent. Projects also carry other metadata fields not shown here.

Errors

  • 400 if no active organisation can be resolved for your account, or a query parameter is invalid.

Create a project directly, without the Brief Builder workflow. The project is created in draft status with you as the owner.

You need project creation access, and your organisation must have direct project creation enabled in its settings.

Request body

NameTypeRequiredDescription
namestringYesProject name. Must not be empty.
descriptionstringNoLonger description of the work.
clientOrganizationIdUUIDNoClient the project is for. Omit for an internal project.
budgetnumberNoProject budget amount.
budgetCurrencystringNoCurrency code. Defaults to your organisation’s currency, then AUD.
startDateISO 8601 dateNoPlanned start date.
targetCompletionDateISO 8601 dateNoTarget delivery date.
jobNumberstringNo1 to 100 characters. Runnit generates one if omitted.
colorstringNoProject colour key. See the field reference above. A random colour is used if omitted.

Example request

Terminal window
curl -X POST https://api.runnit.io/api/v1/projects \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{
"name": "Winter Launch",
"description": "Delivery workspace for the winter campaign.",
"clientOrganizationId": "<client-uuid>",
"budget": 75000,
"budgetCurrency": "AUD",
"startDate": "2026-07-01",
"targetCompletionDate": "2026-08-31"
}'

Response

Returns 201 with the created project:

{
"success": true,
"project": {
"id": "1f0e9a52-...",
"name": "Winter Launch",
"jobNumber": "RB-2026-014",
"status": "draft",
"budget": 75000,
"budgetCurrency": "AUD"
}
}

Errors

  • 400 if name is missing or a field fails validation.
  • 400 if no active organisation can be resolved for your account.
  • 403 with code DIRECT_PROJECT_CREATION_DISABLED if the organisation has not enabled direct project creation.
  • 404 if the organisation record cannot be found.

Get a single project by ID.

Any member of the project’s organisation can call this.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Example request

Terminal window
curl https://api.runnit.io/api/v1/projects/<project-id> \
-H 'Authorization: Bearer rnk_your_key'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "name": "Winter Launch", "status": "active" } }

The project object has the same shape as in the list response.

Errors

  • 404 if the project does not exist.
  • 403 if the project belongs to an organisation you are not a member of.

Get a project together with its team members, tasks, milestones, and brief in one call.

Any member of the project’s organisation can call this.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Example request

Terminal window
curl https://api.runnit.io/api/v1/projects/<project-id>/details \
-H 'Authorization: Bearer rnk_your_key'

Response

{
"success": true,
"project": { "id": "1f0e9a52-...", "name": "Winter Launch", "status": "active" },
"members": [
{
"id": "77a1c9d0-...",
"userId": "d3a6f0c1-...",
"isAdmin": true,
"roleTitle": "Creative Director",
"user": { "id": "d3a6f0c1-...", "name": "Alex Chen", "email": "alex@example.com" }
}
],
"tasks": [
{
"id": "4be2d871-...",
"name": "Draft homepage copy",
"status": "scheduled",
"priority": "high",
"assignedToId": "d3a6f0c1-...",
"estimatedHours": 6,
"plannedStartDate": "2026-07-13T00:00:00.000Z",
"plannedEndDate": "2026-07-14T00:00:00.000Z"
}
],
"milestones": [
{
"id": "0a4f6c33-...",
"name": "Client sign-off",
"type": "custom",
"targetDate": "2026-08-15T00:00:00.000Z",
"isFirm": true,
"orderIndex": 0
}
],
"brief": { "...": "..." }
}

brief is null or absent for projects created without the Brief Builder. Member, task, and milestone objects include further metadata fields.

Errors

  • 404 if the project does not exist.
  • 403 if the project belongs to an organisation you are not a member of.

Get the project’s history feed: status changes, brief edits, task activity, comments, milestone changes, and more.

Any member of the project’s organisation can call this.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Query parameters

NameTypeRequiredDescription
limitintegerNoPage size, 1 to 200. Defaults to 100.
offsetintegerNoNumber of events to skip. Defaults to 0.
qstringNoFree-text search across event titles and descriptions.
eventTypesstringNoComma-separated list of event types to include, for example task.created,task.status.updated.
categoriesstringNoComma-separated list of categories. Valid values: project, brief, task, comment, asset, team. Unknown values are ignored.
taskIdUUIDNoOnly return events linked to this task.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/projects/<project-id>/history?categories=task,comment&limit=50' \
-H 'Authorization: Bearer rnk_your_key'

Response

{
"success": true,
"events": [
{
"id": "9d21e07b-...",
"projectId": "1f0e9a52-...",
"taskId": "4be2d871-...",
"actorUserId": "d3a6f0c1-...",
"actor": { "id": "d3a6f0c1-...", "name": "Alex Chen", "email": "alex@example.com" },
"category": "task",
"eventType": "task.status.updated",
"title": "Task status updated: Draft homepage copy",
"description": "Status changed from scheduled to in_progress.",
"metadata": { "previousStatus": "scheduled", "nextStatus": "in_progress" },
"createdAt": "2026-07-06T23:41:12.000Z"
}
],
"filters": {
"eventTypes": ["task.created", "task.status.updated", "project.updated"],
"categories": ["project", "task", "comment"]
},
"pagination": { "total": 128, "limit": 50, "offset": 0, "hasMore": true }
}

taskId, actorUserId, actor, and description can be null. filters lists the event types and categories that actually appear in this project’s history, which is useful for building filter controls.

Errors

  • 404 if the project does not exist.
  • 403 if the project belongs to an organisation you are not a member of.

Update a project’s common editable fields in one call. Send only the fields you want to change.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body (all fields optional, at least one required)

NameTypeRequiredDescription
namestringNoNew project name. Must not be empty.
descriptionstring or nullNoProject description. Null clears it.
summarystring or nullNoProject summary. Null clears it.
statusstringNoNew status, including archived. See the field reference above.
jobNumberstringNo1 to 100 characters.
startDateISO 8601 date or nullNoPlanned start date. Null clears it.
targetCompletionDateISO 8601 date or nullNoTarget delivery date. Null clears it.
budgetnumber or nullNoBudget amount, zero or greater. Null clears it.
budgetCurrencystringNoExactly 3 letters, for example AUD. Stored uppercase.
clientOrganizationIdUUID or nullNoClient to link. Null removes the client link.
colorstringNoProject colour key. See the field reference above.
tagsarray of stringsNoReplaces the full tag list.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id> \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{
"status": "active",
"targetCompletionDate": "2026-09-30",
"budget": 80000,
"budgetCurrency": "AUD"
}'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "status": "active", "budget": 80000 } }

Returns the full updated project. If the status changed to a completed state, Runnit also records the work in each contributor’s portfolio history.

Errors

  • 400 if no updatable fields are supplied (“No updates provided”).
  • 400 if jobNumber is supplied but empty after trimming.
  • 404 if the project does not exist.
  • 403 if you are not a member of the project’s organisation, or you are not the project owner, a project admin, or an organisation admin or owner.

Update the project’s brief content (description and summary).

Only the project owner can call this.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body

NameTypeRequiredDescription
descriptionstringNoBrief description text.
summarystringNoBrief summary text.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/brief \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "summary": "Repositioned for a spring release window." }'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "summary": "Repositioned for a spring release window." } }

Errors

  • 404 if the project does not exist.
  • 403 if you are not a member of the project’s organisation.
  • 403 if you are not the project owner (“Only project owner can update the brief”).

Update only the project’s status.

Organisation admins and owners can always call this. Other members can update the status of internal projects, projects they are a team member of, and client projects for clients they can access, unless their per-member permission to update project statuses has been switched off.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body

NameTypeRequiredDescription
statusstringYesNew status. See the field reference above.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/status \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "status": "completed" }'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "status": "completed" } }

Moving a project to a completed status also records the work in each contributor’s portfolio history.

Errors

  • 400 if status is missing or not a valid value.
  • 404 if the project does not exist.
  • 403 if you are not a member of the project’s organisation, your status permission is switched off, or the project is for a client you cannot access.

Update the project’s colour identifier.

Organisation admins and owners can always call this. Other members can update internal projects, projects they are a team member of, and client projects for clients they can access.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body

NameTypeRequiredDescription
colorstringYesColour key. See the field reference above.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/color \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "color": "guava" }'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "color": "guava" } }

Errors

  • 400 if color is not one of the valid colour keys.
  • 404 if the project does not exist.
  • 403 if you are not a member of the project’s organisation or cannot access the project’s client.

Update the project’s budget amount, currency, or both.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body (at least one field required)

NameTypeRequiredDescription
budgetnumber or nullNoBudget amount, zero or greater. Null clears the budget.
budgetCurrencystringNoExactly 3 letters. Stored uppercase.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/budget \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "budget": 90000, "budgetCurrency": "AUD" }'

Response

{ "success": true, "project": { "id": "1f0e9a52-...", "budget": 90000, "budgetCurrency": "AUD" } }

Errors

  • 400 if neither budget nor budgetCurrency is supplied (“No budget updates provided”), the budget is negative, or the currency is not 3 letters.
  • 404 if the project does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

List the project’s milestones (key dates).

Any member of the project’s organisation can call this.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Example request

Terminal window
curl https://api.runnit.io/api/v1/projects/<project-id>/milestones \
-H 'Authorization: Bearer rnk_your_key'

Response

{
"success": true,
"milestones": [
{
"id": "0a4f6c33-...",
"projectId": "1f0e9a52-...",
"name": "Client sign-off",
"type": "custom",
"targetDate": "2026-08-15T00:00:00.000Z",
"isFirm": true,
"description": "Final approval from the client team.",
"sourceKey": null,
"orderIndex": 0,
"metadata": {},
"createdAt": "2026-07-01T04:12:00.000Z",
"updatedAt": "2026-07-01T04:12:00.000Z"
}
]
}

description and sourceKey can be null or absent.

Errors

  • 404 if the project does not exist.
  • 403 if you are not a member of the project’s organisation.

Create a milestone on the project.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body

NameTypeRequiredDescription
namestringYesMilestone name. Must not be empty.
targetDatestringYesDate in YYYY-MM-DD format.
typestringNoMilestone type label. Defaults to custom.
isFirmbooleanNoWhether the date is firm. Defaults to true.
descriptionstringNoOptional detail.
sourceKeystring or nullNoOptional key linking the milestone to its source.
orderIndexintegerNoSort position, zero or greater. Defaults to 0.
metadataobjectNoFree-form metadata.

Example request

Terminal window
curl -X POST https://api.runnit.io/api/v1/projects/<project-id>/milestones \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "name": "Client sign-off", "targetDate": "2026-08-15", "isFirm": true }'

Response

Returns 201 with the created milestone:

{ "success": true, "milestone": { "id": "0a4f6c33-...", "name": "Client sign-off", "targetDate": "2026-08-15T00:00:00.000Z" } }

Errors

  • 400 if name is missing, targetDate is missing or not in YYYY-MM-DD format, or the date is invalid.
  • 404 if the project does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

PATCH /api/v1/projects/:id/milestones/:milestoneId

Section titled “PATCH /api/v1/projects/:id/milestones/:milestoneId”

Update a milestone. Send only the fields you want to change.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
milestoneIdUUIDYesMilestone ID. Must belong to the project.

Request body (all optional)

NameTypeRequiredDescription
namestringNoNew name. Must not be empty.
targetDatestringNoDate in YYYY-MM-DD format.
typestringNoMilestone type label.
isFirmbooleanNoWhether the date is firm.
descriptionstring or nullNoDetail text. Null or empty clears it.
sourceKeystring or nullNoSource key. Null clears it.
orderIndexintegerNoSort position, zero or greater.
metadataobjectNoReplaces the metadata object.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/milestones/<milestone-id> \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "targetDate": "2026-08-22" }'

Response

{ "success": true, "milestone": { "id": "0a4f6c33-...", "targetDate": "2026-08-22T00:00:00.000Z" } }

Errors

  • 400 if targetDate is not a valid YYYY-MM-DD date.
  • 404 if the project or milestone does not exist, or the milestone belongs to a different project.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

DELETE /api/v1/projects/:id/milestones/:milestoneId

Section titled “DELETE /api/v1/projects/:id/milestones/:milestoneId”

Delete a milestone from the project.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
milestoneIdUUIDYesMilestone ID. Must belong to the project.

Example request

Terminal window
curl -X DELETE https://api.runnit.io/api/v1/projects/<project-id>/milestones/<milestone-id> \
-H 'Authorization: Bearer rnk_your_key'

Response

{ "success": true }

Errors

  • 404 if the project or milestone does not exist, or the milestone belongs to a different project.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

Create a task in the project and build its schedule. The task is created with status scheduled and its working-day schedule is calculated from the start date and estimate.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Request body

NameTypeRequiredDescription
namestringYesTask name. Must not be empty.
descriptionstringNoTask description.
prioritystringNolow, medium, high, or critical. Defaults to medium.
assignedToIdUUID or nullNoUser to assign. Must be an active organisation member who is allowed to work on the project’s client.
plannedStartDateISO 8601 dateNoSchedule start. Defaults to the project’s start date, then today.
estimatedHoursnumberNoGreater than 0 and less than 1000. Defaults to 7.5 (one working day).

Example request

Terminal window
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",
"description": "First pass for internal review.",
"priority": "high",
"assignedToId": "<user-uuid>",
"plannedStartDate": "2026-07-13",
"estimatedHours": 6
}'

Response

Returns 201 with the created task, its schedule segments, and any clashes with the assignee’s existing schedule:

{
"success": true,
"task": {
"id": "4be2d871-...",
"name": "Draft homepage copy",
"status": "scheduled",
"priority": "high",
"assignedToId": "d3a6f0c1-...",
"estimatedHours": 6,
"plannedStartDate": "2026-07-13T00:00:00.000Z",
"plannedEndDate": "2026-07-13T23:59:59.000Z"
},
"scheduleSegments": [
{
"startTime": "2026-07-13T09:00:00.000Z",
"endTime": "2026-07-13T15:30:00.000Z",
"hours": 6,
"isOverdue": false,
"daysOverdue": 0
}
],
"scheduleConflicts": [
{
"taskId": "77c0d1aa-...",
"startTime": "2026-07-13T09:00:00.000Z",
"endTime": "2026-07-13T12:00:00.000Z",
"durationMinutes": 180
}
]
}

scheduleConflicts is empty when the task has no assignee or the assignee is free. Conflicts are informational only; the task is still created.

Errors

  • 400 if name is missing, estimatedHours is out of range, or plannedStartDate is invalid.
  • 400 if the assignee is not an active member of the organisation, or is not allowed to work on the project’s client.
  • 404 if the project or the assigned user does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

PATCH /api/v1/projects/:id/tasks/:taskId/dates

Section titled “PATCH /api/v1/projects/:id/tasks/:taskId/dates”

Move a task to a new start date and rebuild its schedule. The end date is recalculated from the task’s estimated hours across working days.

Requires the project owner, a project admin, or an organisation manager, admin, or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
taskIdUUIDYesTask ID.

Request body

NameTypeRequiredDescription
plannedStartDateISO 8601 dateYesNew schedule start.
plannedEndDateISO 8601 dateNoAccepted but not used; the end date is always recalculated from the estimate.
allowWeekendsbooleanNoAllow scheduling on weekends. Defaults to false.

If the task has no usable estimate, Runnit derives one from its existing schedule entries, then from its current planned date span, and finally falls back to 7.5 hours (one working day).

Example request

Terminal window
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", "allowWeekends": false }'

Response

{
"success": true,
"task": { "id": "4be2d871-...", "plannedStartDate": "2026-07-20T00:00:00.000Z", "plannedEndDate": "2026-07-21T00:00:00.000Z" },
"scheduleSegments": [
{ "startTime": "2026-07-20T09:00:00.000Z", "endTime": "2026-07-20T17:00:00.000Z", "hours": 7.5, "isOverdue": false, "daysOverdue": 0 }
]
}

Errors

  • 400 if plannedStartDate is missing or invalid.
  • 400 if the schedule cannot be rebuilt for the requested dates.
  • 404 if the project or task does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation manager, admin, or owner.

PATCH /api/v1/projects/:id/tasks/:taskId/estimate

Section titled “PATCH /api/v1/projects/:id/tasks/:taskId/estimate”

Change a task’s estimated hours and rebuild its schedule from its current start date.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
taskIdUUIDYesTask ID.

Request body

NameTypeRequiredDescription
estimatedHoursnumberYesGreater than 0 and less than 1000.

The schedule keeps the task’s existing start date. If the task has no planned start, Runnit uses the earliest existing schedule entry, then the project’s start date, then today.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/tasks/<task-id>/estimate \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "estimatedHours": 12 }'

Response

{
"success": true,
"task": { "id": "4be2d871-...", "estimatedHours": 12 },
"scheduleSegments": [
{ "startTime": "2026-07-13T09:00:00.000Z", "endTime": "2026-07-13T17:00:00.000Z", "hours": 7.5, "isOverdue": false, "daysOverdue": 0 },
{ "startTime": "2026-07-14T09:00:00.000Z", "endTime": "2026-07-14T13:30:00.000Z", "hours": 4.5, "isOverdue": false, "daysOverdue": 0 }
]
}

Errors

  • 400 if estimatedHours is missing or out of range.
  • 400 if the schedule cannot be rebuilt.
  • 404 if the project or task does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

PATCH /api/v1/projects/:id/tasks/:taskId/allocations

Section titled “PATCH /api/v1/projects/:id/tasks/:taskId/allocations”

Set an explicit per-day hour breakdown for a task (manual schedule mode). This replaces the task’s automatic schedule with the exact days and hours you supply.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
taskIdUUIDYesTask ID. Must belong to the project.

Request body

NameTypeRequiredDescription
allocationsarrayYesAt least one entry.
allocations[].dateISO 8601 dateYesThe day to allocate hours to.
allocations[].hoursnumberYesGreater than 0 and less than 24.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/projects/<project-id>/tasks/<task-id>/allocations \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{
"allocations": [
{ "date": "2026-07-13", "hours": 4 },
{ "date": "2026-07-15", "hours": 3.5 }
]
}'

Response

{
"success": true,
"task": { "id": "4be2d871-...", "estimatedHours": 7.5 },
"scheduleSegments": [
{ "startTime": "2026-07-13T09:00:00.000Z", "endTime": "2026-07-13T13:00:00.000Z", "hours": 4, "isOverdue": false, "daysOverdue": 0 },
{ "startTime": "2026-07-15T09:00:00.000Z", "endTime": "2026-07-15T12:30:00.000Z", "hours": 3.5, "isOverdue": false, "daysOverdue": 0 }
]
}

Errors

  • 400 if allocations is empty, a date is invalid, or hours are out of range.
  • 400 if the manual schedule cannot be applied.
  • 404 if the project or task does not exist, or the task belongs to a different project.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

PATCH /api/v1/projects/:id/tasks/:taskId/assignee

Section titled “PATCH /api/v1/projects/:id/tasks/:taskId/assignee”

Assign a task to a user, or unassign it. The task’s schedule entries move to the new assignee.

Requires the project owner, a project admin, or an organisation manager, admin, or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.
taskIdUUIDYesTask ID. Must belong to the project.

Request body

NameTypeRequiredDescription
assignedToIdUUID or nullNoUser to assign. Null (or omitted) removes the assignment. Must be an active organisation member who is allowed to work on the project’s client.

Example request

Terminal window
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>" }'

Response

{
"success": true,
"task": {
"id": "4be2d871-...",
"name": "Draft homepage copy",
"assignedToId": "d3a6f0c1-...",
"assignee": { "id": "d3a6f0c1-...", "name": "Alex Chen", "email": "alex@example.com" }
},
"scheduleConflicts": []
}

scheduleConflicts lists the new assignee’s overlapping schedule entries in the task’s window, in the same shape as the task creation endpoint. It is informational only; the assignment still happens.

Errors

  • 400 if assignedToId is not a UUID.
  • 400 if the assignee is not an active member of the organisation, or is not allowed to work on the project’s client.
  • 404 if the project, task, or assigned user does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation manager, admin, or owner.

List the users who can be assigned to tasks in this project. For client projects with team restrictions, only users allowed to work on that client are returned; otherwise all active organisation members are returned. Users already on the project team are flagged and sorted first.

Requires the project owner, a project admin, or an organisation admin or owner.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Example request

Terminal window
curl https://api.runnit.io/api/v1/projects/<project-id>/assignee-options \
-H 'Authorization: Bearer rnk_your_key'

Response

{
"success": true,
"hasClientRestrictions": false,
"options": [
{
"id": "d3a6f0c1-...",
"name": "Alex Chen",
"email": "alex@example.com",
"avatarUrl": "https://...",
"roleTitle": "Creative Director",
"inProjectTeam": true
}
]
}

avatarUrl and roleTitle can be absent.

Errors

  • 404 if the project does not exist.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

Delete a project and everything attached to it.

Requires the project owner, a project admin, or an organisation admin or owner.

Deleting a project removes, in one operation:

  • the project itself;
  • all of its tasks;
  • all schedule entries for those tasks;
  • all project team memberships;
  • the asset collections linked to the project; and
  • every asset in those collections, including stored files and file versions.

Path parameters

NameTypeRequiredDescription
idUUIDYesProject ID.

Example request

Terminal window
curl -X DELETE https://api.runnit.io/api/v1/projects/<project-id> \
-H 'Authorization: Bearer rnk_your_key'

Response

Returns a summary of what was removed:

{
"success": true,
"projectId": "1f0e9a52-...",
"tasksSoftDeleted": 14,
"scheduleEntriesDeleted": 31,
"membersRemoved": 5,
"collectionsDeleted": 2,
"assetsDeleted": 27
}

Errors

  • 404 if the project does not exist or was already deleted.
  • 403 if you are not the project owner, a project admin, or an organisation admin or owner.

Work with individual tasks through the Tasks API, or group projects with the Master Projects API.