Skip to content
Dashboard

Tasks

A task is a unit of operational work: a clean, an inspection, a repair. This guide covers the task operations most integrations need. Every field and filter is listed on the operation’s page in the API Reference.

OperationRequestPermission
listTasksGET /tasksview_tasks
getTaskGET /tasks/{id}view_tasks
createTaskPOST /tasksmodify_tasks
updateTaskPATCH /tasks/{id}modify_tasks
updateTaskStatusPOST /tasks/{id}/statusmodify_tasks
deleteTaskDELETE /tasks/{id}delete_tasks

Paths are relative to your region’s base URL, for example https://api-us.suiteop.com/api/v1. See Authentication for permissions.

GET /tasks is paginated (default limit 20, maximum 100). Rows are ordered by priority, then due date.

Terminal window
curl "https://api-us.suiteop.com/api/v1/tasks?statuses=not_started&statuses=in_progress&dueDateFrom=2026-07-05T00:00:00.000Z&dueDateTo=2026-07-06T00:00:00.000Z&limit=50" \
-H "Authorization: Bearer sk_live_your_key_here"

Useful filters:

FilterNotes
status / statusestriage, not_started, in_progress, paused, completed, cancelled. Repeat statuses for several values
priority / prioritieswatch, low, medium, high, urgent
propertyId(s), assigneeUserId(s), departmentId(s)Singular takes one ID, plural takes a repeated list
dueDateFrom, dueDateToISO 8601 instants, e.g. 2026-07-05T00:00:00.000Z; an offset such as +02:00 is read as the same instant in UTC. dueDateFrom is inclusive, dueDateTo is exclusive
nameContainsCase-insensitive substring of the English task name. % and _ act as wildcards
viewtoday, tomorrow, week, overdue, upcoming, scheduled, unscheduled, done, triage, issues, deleted or recurring. Day windows use the organization’s timezone; triage and deleted need modify_tasks; issues means blocking tasks, not isIssue
unassigned, isIssue, isBlocking, hasReservation, reservationIdNarrow further. isIssue and isBlocking filter on false too; unassigned=false doesn’t filter
sourceTaskIdOnly the tasks reported from this task: the issues a worker raised while doing it. Add isIssue=true&includeTriage=true to include new reports still in triage
includeCancelled, includeTriage, includeDeletedCancelled, triage and deleted tasks are hidden by default. Each opt-in also needs modify_tasks

Each row carries summary fields such as id, nameText, status, priority, due, isTimeAdded, propertyId, propertyName, assigneeUserId, departmentId, departmentName, taskItemsCompleted and taskItemsTotal, plus reservationId, reservationGuestFirstName and reservationGuestLastName for a task linked to a stay. GET /tasks/{id} returns the full task, including descriptionText, costs, events and the linked reservation’s details.

GET /tasks/{id} also returns score, the inspection score stored when the task was completed: earned points out of possible, percent rounded, and failCount, the number of scored answers that failed. It is null until the task is completed, when no answer that carries points was given, and always for an organization that doesn’t have points turned on. Answers earn points from their answer list.

name (up to 255 characters, counted as Unicode code points, so most emoji count as one) and departmentId are required. Use listDepartments to find department IDs.

Terminal window
curl -X POST https://api-us.suiteop.com/api/v1/tasks \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Idempotency-Key: 550e8400-e29b-41d4-a716-446655440000" \
-H "Content-Type: application/json" \
-d '{
"name": "Deep clean unit 4B",
"departmentId": "0b6f2c1e-…",
"propertyId": "9a3d7e40-…",
"priority": "high",
"due": "2026-07-05T14:00:00Z",
"isTimeAdded": true,
"estTime": 1.5
}'
const res = await fetch('https://api-us.suiteop.com/api/v1/tasks', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.SUITEOP_API_KEY}`,
'Content-Type': 'application/json',
'Idempotency-Key': crypto.randomUUID(),
},
body: JSON.stringify({
name: 'Deep clean unit 4B',
departmentId: '0b6f2c1e-…',
propertyId: '9a3d7e40-…',
priority: 'high',
}),
})
const { data } = await res.json()
const taskId = data.task.id

The response is 201, and the new task is nested under data.task.

Field notes:

  • due and isTimeAdded go together. Sending one without the other is rejected. With isTimeAdded: true, due is an exact time: an ISO 8601 instant such as 2026-07-05T14:00:00Z, or with an offset such as 2026-07-05T16:00:00+02:00, stored as the same instant in UTC. With false, send the bare day, such as 2026-07-05; the task is due at the end of that day in its timezone (the property’s, else the organization’s). The 201 response carries that timezone as data.task.propertyTimezone (an IANA name such as America/Chicago, or null when the task has no property or the property has no usable timezone), so format a date-only due in it rather than in your own timezone, or it can read as the next day.
  • assigneeUserId is a user ID, the userId field from listTeamMembers, not the member ID. Omit it to leave the task unassigned.
  • estTime is in hours as a decimal: 1.5 means 90 minutes.
  • Defaults: priority is medium and status is not_started when omitted.
  • propertyId is required for property-limited callers. If the credential’s member is limited to specific properties, a create without propertyId is refused with 403.
  • No templates on create. Over REST, createTask has no templateId. Send name, departmentId and propertyId, then call applyTemplateToTask (POST /task-template-applications). It copies the template’s requirements only; the template’s name, department and estimate aren’t applied. See Task templates for building templates and applying them.
  • reservationId must be a stay at the task’s property. A stay at another property is rejected as not found, and a task without a propertyId accepts only a stay that has no property either.
  • Also accepted: description, collaborators, requiredSkillId, elementInstanceId, images, isIssue, isBlocking, permissionToEnter and sourceLanguage.

PATCH /tasks/{id} takes the fields to change inside a data object. Fields you leave out keep their current value.

Terminal window
curl -X PATCH https://api-us.suiteop.com/api/v1/tasks/7d0e… \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"data": {"priority": "urgent", "assigneeUserId": "5c2b…"}}'

Use this to assign, reschedule or edit a task. Don’t create a new task to reassign an existing one; that makes a duplicate.

A reservationId you send is checked against the property the task ends up on after the update: a stay at another property is rejected as not found, and a task with no property accepts only a stay with none. If you move a task to another property without sending reservationId, the task keeps its stay only when the stay is at the new property; otherwise it is unlinked from the stay.

To share a task, set data.publicEnabled to true. That opens its public links and revives unexpired ones. An execute token is minted only if none is stored, so to get a new one, set data.publicEditToken to null first. View links don’t change.

Use POST /tasks/{id}/status to start, pause, complete, cancel or send a task back to triage:

Terminal window
curl -X POST https://api-us.suiteop.com/api/v1/tasks/7d0e…/status \
-H "Authorization: Bearer sk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{"status": "in_progress"}'

Completing a task is gated:

  • Every requirement must be satisfied. listTaskRequirements shows what is still outstanding, and photo requirements are owed once per matching element. Listing, adding and rewording a task’s requirements is covered in Task requirements.
  • A task in a cleans or inspections department that has a property needs a declaration of the property status that results:
{
"status": "completed",
"declaration": { "kind": "declare", "column": "cleaning", "toValue": "clean" }
}

column is cleaning (values clean, dirty, unknown) or inspection (values such as inspected or failed_inspection). Send { "kind": "skip" } to leave the property status unchanged.

This operation acts with manager authority, so it can complete a task assigned to someone else. updateTask can also change data.status, but runs the completion gates as the assignee, so prefer updateTaskStatus for status changes.

DELETE /tasks/{id} needs delete_tasks and is a soft delete: the task drops out of listTasks but is kept, and can be listed again with includeDeleted=true (which needs modify_tasks). To stop work while keeping the task visible to the team, set its status to cancelled instead.