Skip to main content

About

A task is one actionable line item — a follow-up call, a document to chase, a step in an onboarding SOP. It has a title, an optional description, a due date, and assignees, and it gets checked off when the work is done. Two things a task is not:
  • A calendar event. Something with a start time and attendees is an appointment — see the Appointments API.
  • A background job. The async jobs that ops like addContactTags return a bulkTaskId for live under the Bulk Tasks API, and are unrelated to the CRM tasks on this page.
Tasks anchor either to a contact (the usual case — follow-ups on a person) or directly to a deal (pipeline work that belongs to the deal itself, with no contact involved). Which one it is determines how you complete it, so the distinction matters — see the callout below. All operations go through the developer API gateway — one endpoint, called by operationId. If you haven’t set up a key yet, start with the Developer API Overview.

Operations

Reading tasks (READ scope)

What listMyTasks returns depends on the key’s roleA MEMBER or ISA key always sees only the key owner’s own tasks, whatever filters you pass. A team-admin key with no participants filter gets the org’s feed narrowed to contacts the key owner can access — tasks on contacts visible only to teammates are silently omitted, so don’t treat that default as a complete org backlog. To read a specific teammate’s queue, pass their userIds in participants (from listTeammates, same-org only).

Writing tasks (WRITE scope)

A task with no participants is invisibleparticipants (teammate userIds — from getMyProfile for the key owner, or listTeammates for a colleague) is what puts a task in someone’s queue. Create a task without them and it is unassigned: it exists, but it will never appear in anyone’s listMyTasks. This is the most common way a scripted checklist silently goes missing.
Which complete operation to uselistMyTasks tells you: if a task comes back with contact: null, there is no contactId to pass and completeTask cannot touch it — use completeTaskById. If it has a contact, use completeTask, which records the completion on that contact’s timeline as well. completeTaskById refuses a task that has a contact, so an error there means you want the other operation.
Due dates are a local day, not an instanttimezone (PST, MST, CST, EST, …) is the zone the due date’s day is read in, and it decides which TODAY / OVERDUE bucket the task lands in. Send the user’s own zone, and for a day-level request (“follow up Friday”) pick an end-of-business time in that zone rather than a bare midnight.
No bulk create, and no re-anchoringThere is no multi-task call: a checklist is built by calling createTaskOnContact once per step, in order, with staggered due dates. The response echoes the contact’s full task list every time, so the last call confirms the whole set landed.A task also cannot be moved to a different contact. contactId on updateTask identifies the task’s existing contact — any other contact is rejected. Delete-and-recreate is not equivalent: a fresh task loses the original’s completedAt history, created date, and notification links.
Organization guardEvery id you pass is org-guarded before the operation runs: taskId (via its linked contact, or via an in-org participant for a contact-less task), contactId, dealId/dealIds, and participants user ids. The write operations additionally bind the pair — a foreign task id can never be completed or edited under a contact you do own, and vice versa. See Authorization for the model.

Example

List everything overdue, then complete one of them:
Full variable schemas, response shapes, and worked examples for every operation are available from the discovery endpoint.