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.
| Operation | Request | Permission |
|---|---|---|
listTasks | GET /tasks | view_tasks |
getTask | GET /tasks/{id} | view_tasks |
createTask | POST /tasks | modify_tasks |
updateTask | PATCH /tasks/{id} | modify_tasks |
updateTaskStatus | POST /tasks/{id}/status | modify_tasks |
deleteTask | DELETE /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.
Listing tasks
Section titled “Listing tasks”GET /tasks is paginated (default limit 20, maximum 100). Rows are ordered by priority, then due date.
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:
| Filter | Notes |
|---|---|
status / statuses | triage, not_started, in_progress, paused, completed, cancelled. Repeat statuses for several values |
priority / priorities | watch, low, medium, high, urgent |
propertyId(s), assigneeUserId(s), departmentId(s) | Singular takes one ID, plural takes a repeated list |
dueDateFrom, dueDateTo | ISO 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 |
nameContains | Case-insensitive substring of the English task name. % and _ act as wildcards |
view | today, 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, reservationId | Narrow further. isIssue and isBlocking filter on false too; unassigned=false doesn’t filter |
sourceTaskId | Only 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, includeDeleted | Cancelled, 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.
Creating a task
Section titled “Creating a task”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.
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.idThe response is 201, and the new task is nested under data.task.
Field notes:
dueandisTimeAddedgo together. Sending one without the other is rejected. WithisTimeAdded: true,dueis an exact time: an ISO 8601 instant such as2026-07-05T14:00:00Z, or with an offset such as2026-07-05T16:00:00+02:00, stored as the same instant in UTC. Withfalse, send the bare day, such as2026-07-05; the task is due at the end of that day in its timezone (the property’s, else the organization’s). The201response carries that timezone asdata.task.propertyTimezone(an IANA name such asAmerica/Chicago, ornullwhen the task has no property or the property has no usable timezone), so format a date-onlyduein it rather than in your own timezone, or it can read as the next day.assigneeUserIdis a user ID, theuserIdfield fromlistTeamMembers, not the member ID. Omit it to leave the task unassigned.estTimeis in hours as a decimal:1.5means 90 minutes.- Defaults:
priorityismediumandstatusisnot_startedwhen omitted. propertyIdis required for property-limited callers. If the credential’s member is limited to specific properties, a create withoutpropertyIdis refused with403.- No templates on create. Over REST,
createTaskhas notemplateId. Sendname,departmentIdandpropertyId, then callapplyTemplateToTask(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. reservationIdmust be a stay at the task’s property. A stay at another property is rejected as not found, and a task without apropertyIdaccepts only a stay that has no property either.- Also accepted:
description,collaborators,requiredSkillId,elementInstanceId,images,isIssue,isBlocking,permissionToEnterandsourceLanguage.
Updating a task
Section titled “Updating a task”PATCH /tasks/{id} takes the fields to change inside a data object. Fields you leave out keep their current value.
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.
Changing status
Section titled “Changing status”Use POST /tasks/{id}/status to start, pause, complete, cancel or send a task back to triage:
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.
listTaskRequirementsshows 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
declarationof 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.
Deleting a task
Section titled “Deleting a task”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.