Skip to content

Scheduling API

The Scheduling API reads the schedule calendar Runnit builds from task assignments: who is booked on what, when, and for how long. It also manages organisation closure dates (public holidays and office closures), which the scheduler skips when it books work.

Authentication: every endpoint requires an API key. See API Keys & Authentication.

Get the schedule entries for one or more users. Each entry is one booked segment of a task on a user’s calendar, enriched with task, project, and assignee details. Entries for projects you cannot see are filtered out.

Any organisation member with schedule access can call this. Every requested user must share an organisation with you.

Query parameters

NameTypeRequiredDescription
userIdsstringYesComma-separated list of user IDs to fetch schedules for.

The endpoint returns each user’s full schedule; there is no date-range filter. Filter client-side if you only need a window.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/schedule?userIds=<user-uuid-1>,<user-uuid-2>' \
-H 'Authorization: Bearer rnk_your_key'

Response

A JSON array of schedule entries:

[
{
"id": "8fd2b3c4-...",
"taskId": "4be2d871-...",
"taskNumber": "TASK-014",
"projectId": "1f0e9a52-...",
"projectName": "Winter Launch",
"clientName": "Northwind",
"name": "Draft homepage copy",
"description": "First pass for internal review.",
"status": "scheduled",
"priority": "high",
"assignedToId": "d3a6f0c1-...",
"assignedTo": {
"id": "d3a6f0c1-...",
"firstName": "Alex",
"lastName": "Chen",
"displayName": "Alex Chen",
"avatarUrl": "https://...",
"currentTitle": "Creative Director"
},
"plannedStartDate": "2026-07-13T09:00:00.000Z",
"plannedEndDate": "2026-07-13T15:30:00.000Z",
"durationMinutes": 360,
"allocatedHours": 6,
"estimatedHours": 6,
"segmentIndex": 0,
"totalSegments": 1,
"isOverdue": false,
"daysOverdue": 0,
"tags": ["copy", "homepage"],
"metadata": {}
}
]

A task that spans several days appears as several entries; segmentIndex and totalSegments tell you which piece you are looking at. plannedStartDate and plannedEndDate are the segment’s start and end times, not the task’s overall dates. status is one of pending, scheduled, in_progress, completed, cancelled; priority is one of low, medium, high, critical. clientName, description, taskNumber, assignedTo, allocatedHours, estimatedHours, and tags can be null or absent.

An empty array means the requested users have no schedule entries.

Errors

  • 400 if userIds is missing, or you have no active organisation.
  • 403 if any requested user does not share an organisation with you, or none of the entries belong to projects you can see.

Get the milestones of every project that appears in the selected users’ schedules. Useful for drawing key dates alongside the schedule calendar.

Any organisation member with schedule access can call this. Every requested user must share an organisation with you.

Query parameters

NameTypeRequiredDescription
userIdsstringYesComma-separated list of user IDs.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/schedule/milestones?userIds=<user-uuid-1>,<user-uuid-2>' \
-H 'Authorization: Bearer rnk_your_key'

Response

A JSON array of milestones:

[
{
"id": "0a4f6c33-...",
"projectId": "1f0e9a52-...",
"projectName": "Winter Launch",
"name": "Client sign-off",
"type": "custom",
"targetDate": "2026-08-15",
"isFirm": true,
"description": "Final approval from the client team.",
"sourceKey": null,
"orderIndex": 0,
"metadata": {}
}
]

targetDate is a plain YYYY-MM-DD date. description and sourceKey can be null. An empty array means the selected users have no scheduled work, or their projects have no milestones.

Errors

  • 400 if userIds is missing, or you have no active organisation.
  • 403 if any requested user does not share an organisation with you.

Get a task with its project, assigned user, and subtasks in one call. This is the detail view behind a schedule entry.

Any organisation member with schedule access can call this, for tasks in projects their organisation can see.

Path parameters

NameTypeRequiredDescription
taskIdUUIDYesTask ID.

Example request

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

Response

The task object with related records attached:

{
"id": "4be2d871-...",
"projectId": "1f0e9a52-...",
"name": "Draft homepage copy",
"status": "scheduled",
"priority": "high",
"progress": 0,
"assignedToId": "d3a6f0c1-...",
"estimatedHours": 6,
"plannedStartDate": "2026-07-13T00:00:00.000Z",
"plannedEndDate": "2026-07-14T00:00:00.000Z",
"project": { "id": "1f0e9a52-...", "name": "Winter Launch", "status": "active" },
"assignedUser": { "id": "d3a6f0c1-...", "displayName": "Alex Chen", "email": "alex@example.com" },
"subtasks": []
}

assignedUser is null for unassigned tasks. The task and project include their other standard fields.

Errors

  • 404 if the task or its project does not exist.
  • 403 if the project belongs to an organisation you cannot access.

Closure dates are days the organisation does not work: public holidays and office closures. The scheduler skips them when booking task time. All closure-date endpoints operate on your own organisation.

A closure date looks like this:

{
"id": "e19c50f7-...",
"organizationId": "8c2d41b7-...",
"date": "2026-12-25",
"name": "Christmas Day",
"description": "Public holiday",
"type": "holiday",
"isRecurring": true,
"createdAt": "2026-01-05T00:00:00.000Z",
"updatedAt": "2026-01-05T00:00:00.000Z",
"createdById": "d3a6f0c1-..."
}

type is one of holiday, closure, other. description and createdById can be null.

Reading closure dates is open to any organisation member. Creating, updating, and deleting them requires permission to manage organisation settings, which organisation admins and owners have.

List your organisation’s closure dates, optionally filtered to a date range.

Any organisation member can call this.

Query parameters

NameTypeRequiredDescription
startDateISO 8601 dateNoStart of the range. Only applied when endDate is also supplied.
endDateISO 8601 dateNoEnd of the range. Only applied when startDate is also supplied.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/closure-dates?startDate=2026-12-01&endDate=2027-01-31' \
-H 'Authorization: Bearer rnk_your_key'

Response

A JSON array of closure dates in the shape shown above.

Errors

  • 404 if your account is not part of any organisation.

Check whether a specific date is a closure date for your organisation.

Any organisation member can call this.

Query parameters

NameTypeRequiredDescription
dateISO 8601 dateYesThe date to check.

Example request

Terminal window
curl 'https://api.runnit.io/api/v1/closure-dates/check?date=2026-12-25' \
-H 'Authorization: Bearer rnk_your_key'

Response

{ "isClosureDate": true }

Errors

  • 400 if date is missing or not a valid date.

Get a single closure date by ID.

Any organisation member can call this, for closure dates in their own organisation.

Path parameters

NameTypeRequiredDescription
idUUIDYesClosure date ID.

Example request

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

Response

A single closure date object in the shape shown above.

Errors

  • 404 if the closure date does not exist or belongs to a different organisation.

Create a closure date.

Requires permission to manage organisation settings (organisation admins and owners).

Request body

NameTypeRequiredDescription
dateISO 8601 dateYesThe closure date.
namestringYesLabel, for example “Christmas Day”.
descriptionstringNoExtra detail.
typestringNoholiday, closure, or other.
isRecurringbooleanNoWhether the closure repeats every year.

Example request

Terminal window
curl -X POST https://api.runnit.io/api/v1/closure-dates \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "date": "2026-12-25", "name": "Christmas Day", "type": "holiday", "isRecurring": true }'

Response

Returns 201 with the created closure date object.

Errors

  • 400 if date or name is missing, or type is invalid.
  • 403 if you cannot manage organisation settings.
  • 404 if your account is not part of any organisation.

Create several closure dates in one request, for example a full public holiday calendar.

Requires permission to manage organisation settings (organisation admins and owners).

Request body

NameTypeRequiredDescription
datesarrayYesAt least one entry.
dates[].dateISO 8601 dateYesThe closure date.
dates[].namestringYesLabel.
dates[].descriptionstringNoExtra detail.
dates[].typestringNoholiday, closure, or other.
dates[].isRecurringbooleanNoWhether the closure repeats every year.

Example request

Terminal window
curl -X POST https://api.runnit.io/api/v1/closure-dates/bulk \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{
"dates": [
{ "date": "2026-12-25", "name": "Christmas Day", "type": "holiday", "isRecurring": true },
{ "date": "2026-12-28", "name": "Boxing Day (observed)", "type": "holiday", "isRecurring": false }
]
}'

Response

Returns 201 with a JSON array of the created closure date objects.

Errors

  • 400 if dates is empty, or any entry is missing date or name.
  • 403 if you cannot manage organisation settings.

Update a closure date. Send only the fields you want to change.

Requires permission to manage organisation settings (organisation admins and owners).

Path parameters

NameTypeRequiredDescription
idUUIDYesClosure date ID.

Request body (all optional)

NameTypeRequiredDescription
dateISO 8601 dateNoNew date.
namestringNoNew label.
descriptionstringNoExtra detail.
typestringNoholiday, closure, or other.
isRecurringbooleanNoWhether the closure repeats every year.

Example request

Terminal window
curl -X PATCH https://api.runnit.io/api/v1/closure-dates/<closure-date-id> \
-H 'Authorization: Bearer rnk_your_key' \
-H 'Content-Type: application/json' \
-d '{ "isRecurring": false }'

Response

The updated closure date object.

Errors

  • 400 if a field fails validation.
  • 403 if you cannot manage organisation settings.
  • 404 if the closure date does not exist or belongs to a different organisation.

Delete a closure date.

Requires permission to manage organisation settings (organisation admins and owners).

Path parameters

NameTypeRequiredDescription
idUUIDYesClosure date ID.

Example request

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

Response

Returns 204 with no body.

Errors

  • 403 if you cannot manage organisation settings.
  • 404 if the closure date does not exist or belongs to a different organisation.

Schedules are built from task assignments. Create and reschedule tasks through the Projects API, and update task status through the Tasks API.