Skip to main content
A task is a manual action item created when a sequence reaches a step that requires human execution — such as placing a phone call, sending a hand-crafted email, or connecting on LinkedIn. Tasks are assigned to a workspace user and appear in the Topo task queue until they are completed, skipped, or reassigned. The Tasks API lets you build custom task management workflows: sync pending tasks into your CRM or sales tooling, route tasks across your team, or track completion rates in external dashboards.
Read-only endpoints require the tasks:read scope. Mutation endpoints (skip, reopen, reassign) require tasks:write.

The task object

id
string (UUID)
required
Unique identifier for the task.
organization_id
string (UUID)
required
The workspace this task belongs to.
type
string
required
What kind of action this task represents. See Task types below.
priority
string
required
Priority bucket for this task. One of: HOT, TODAY, EXTRA. Topo sets this automatically based on engagement signals.
status
string
required
Current lifecycle state. See Task statuses below.
sequence_id
string (UUID)
required
The sequence run this task was created from.
assignee_user_id
string (UUID) | null
The workspace user the task is currently assigned to. null if the task is unassigned.
disposition
string | null
For CALL tasks only — the outcome recorded when the call was executed. One of: ANSWERED, VOICEMAIL_LEFT, NO_ANSWER. null for non-call tasks or tasks not yet completed.
reopened_at
string (ISO 8601) | null
When the task was most recently reopened, if applicable.
reopen_reason
string | null
Why the task was reopened. Currently the only possible value is REMINDER_RULE (triggered automatically by a configured reminder rule).
skipped_at
string (ISO 8601) | null
When the task was skipped, if applicable.
completed_at
string (ISO 8601) | null
When the task was completed, if applicable.
created_at
string (ISO 8601)
required
When the task was created.
updated_at
string (ISO 8601)
required
When the task was last modified.

Task types

TypeDescription
CALLPlace a phone call to the contact.
EMAIL_REPLYSend or review an email reply in an active email thread.
LINKEDIN_REPLYReply to a LinkedIn conversation with the contact.
NEW_LEAD_REVIEWReview and approve or reject a new lead before outreach begins.

Task statuses

StatusDescription
PENDINGThe task is open and waiting for action.
IN_PROGRESSThe task has been opened by an assignee and is actively being worked.
COMPLETEDThe task has been carried out and marked as done.
SKIPPEDThe task was deliberately skipped without execution.

The message object

Messages are returned by the List task messages endpoint. Each message represents a real email or LinkedIn message exchanged in the contact thread associated with the task’s sequence.
id
string (UUID)
required
Unique identifier for the message.
channel
string
required
The channel the message was sent on. One of: EMAIL, LINKEDIN, MANUAL, CALENDAR.
direction
string
required
INBOUND for messages received from the contact; OUTBOUND for messages sent by your team.
subject
string | null
The email subject line. null for non-email channels.
body
string
required
The message body text. Quoted reply history is stripped from inbound messages to give you only the new content.
sent_at
string (ISO 8601)
required
When the message was sent (outbound) or received (inbound).
sender_id
string (UUID) | null
The workspace user who sent an outbound message. null for inbound messages from the contact.

List tasks

Requires scope: tasks:read
Returns a paginated list of tasks in your workspace. Combine filters to build targeted views — for example, all pending call tasks assigned to a specific rep.
GET /v1/tasks

Query parameters

status
string
Filter by lifecycle state. One of: PENDING, IN_PROGRESS, COMPLETED, SKIPPED.
assignee_user_id
string (UUID)
Return only tasks assigned to this user.
sequence_id
string (UUID)
Return only tasks from this specific sequence run.
sequence_template_ids
string (UUID)
Filter by one or more sequence templates. Repeat the parameter to pass multiple values: ?sequence_template_ids=uuid1&sequence_template_ids=uuid2.
types
string
Filter by task type. Repeat the parameter to pass multiple values: ?types=CALL&types=EMAIL_REPLY. Valid values: CALL, EMAIL_REPLY, LINKEDIN_REPLY, NEW_LEAD_REVIEW.
priorities
string
Filter by priority bucket. Repeat the parameter to pass multiple values: ?priorities=HOT&priorities=TODAY. Valid values: HOT, TODAY, EXTRA.
created_at_after
string (ISO 8601)
Return tasks created strictly after this timestamp.
created_at_before
string (ISO 8601)
Return tasks created strictly before this timestamp.
sort_by
string
Field to sort results by. One of: created_at, updated_at. Defaults to created_at.
sort_order
string
Sort direction. asc or desc. Defaults to asc.
page
integer
Page number (1-indexed). Defaults to 1.
size
integer
Number of items per page. Between 1 and 100. Defaults to 10.

Response

items
array
Array of task objects on this page.
total_count
integer
Total number of tasks matching the query across all pages.
total_pages
integer
Total number of pages at the current size.
has_more
boolean
true if additional pages exist after the current one.

Example — list pending call tasks for a rep

curl "https://api.topo.io/v1/tasks?status=PENDING&types=CALL&assignee_user_id=019d4e5f-6a7b-8c91-0d2e-3f4a5b6c7d8e&sort_by=created_at&sort_order=asc" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx"
{
  "items": [
    {
      "id": "019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f",
      "organization_id": "018e9d8c-7b6a-7f5e-4d3c-2b1a0f9e8d7c",
      "type": "CALL",
      "priority": "HOT",
      "status": "PENDING",
      "sequence_id": "018f3c1a-4b2d-7e8f-9a0b-1c2d3e4f5a6b",
      "assignee_user_id": "019d4e5f-6a7b-8c91-0d2e-3f4a5b6c7d8e",
      "disposition": null,
      "reopened_at": null,
      "reopen_reason": null,
      "skipped_at": null,
      "completed_at": null,
      "created_at": "2025-03-13T07:00:00Z",
      "updated_at": "2025-03-13T07:00:00Z"
    }
  ],
  "total_count": 1,
  "total_pages": 1,
  "has_more": false
}

Get a task

Requires scope: tasks:read
Fetches a single task by its ID.
GET /v1/tasks/{id}

Path parameters

id
string (UUID)
required
The ID of the task to retrieve.

Example

curl "https://api.topo.io/v1/tasks/019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx"

List task messages

Requires scope: tasks:read
Returns the list of messages exchanged in the sequence thread associated with this task. This gives you the full conversation context — prior emails and LinkedIn messages sent and received in this contact’s sequence — so you can present it to the assignee without switching to the Topo UI.
GET /v1/tasks/{id}/messages

Path parameters

id
string (UUID)
required
The ID of the task whose thread messages you want to retrieve.

Response

Returns an array of message objects. Messages are not paginated — the full thread is returned in a single response.

Example

curl "https://api.topo.io/v1/tasks/019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f/messages" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx"
[
  {
    "id": "01af6b7c-8d9e-0f12-3a4b-5c6d7e8f9a0b",
    "channel": "EMAIL",
    "direction": "OUTBOUND",
    "subject": "Quick question about your outbound stack",
    "body": "Hi Sarah,\n\nI noticed Acme Corp recently expanded its SDR team — curious whether you're looking at tools to help them scale outreach without sacrificing personalization.\n\nWould a 15-minute call this week make sense?\n\nBest,\nJamie",
    "sent_at": "2025-03-10T09:14:00Z",
    "sender_id": "019d4e5f-6a7b-8c91-0d2e-3f4a5b6c7d8e"
  },
  {
    "id": "01b07c8d-9e0f-1a23-4b5c-6d7e8f9a0b1c",
    "channel": "EMAIL",
    "direction": "INBOUND",
    "subject": "Re: Quick question about your outbound stack",
    "body": "Hi Jamie, yes happy to chat. Let's do Thursday at 2pm EST.",
    "sent_at": "2025-03-11T14:32:00Z",
    "sender_id": null
  }
]

Skip a task

Requires scope: tasks:write
Skips an actionable task (PENDING or IN_PROGRESS), marking it as SKIPPED without recording a completion. The sequence continues to its next step. Use this when the action is no longer relevant — for example, the contact has already called you back and a follow-up call task is no longer needed.
POST /v1/tasks/{id}/skip

Path parameters

id
string (UUID)
required
The ID of the task to skip.

Example

curl -X POST "https://api.topo.io/v1/tasks/019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f/skip" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx"
{
  "id": "019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f",
  "organization_id": "018e9d8c-7b6a-7f5e-4d3c-2b1a0f9e8d7c",
  "type": "CALL",
  "priority": "HOT",
  "status": "SKIPPED",
  "sequence_id": "018f3c1a-4b2d-7e8f-9a0b-1c2d3e4f5a6b",
  "assignee_user_id": "019d4e5f-6a7b-8c91-0d2e-3f4a5b6c7d8e",
  "disposition": null,
  "reopened_at": null,
  "reopen_reason": null,
  "skipped_at": "2025-03-13T10:05:33Z",
  "completed_at": null,
  "created_at": "2025-03-13T07:00:00Z",
  "updated_at": "2025-03-13T10:05:33Z"
}

Reopen a task

Requires scope: tasks:write
Reopens a task that was previously COMPLETED or SKIPPED, returning it to PENDING so it can be actioned again. This is useful when a reminder rule fires, or when a rep needs to reattempt a call after a failed attempt.
POST /v1/tasks/{id}/reopen

Path parameters

id
string (UUID)
required
The ID of the task to reopen.

Example

curl -X POST "https://api.topo.io/v1/tasks/019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f/reopen" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx"

Reassign a task

Requires scope: tasks:write
Reassigns a task to a different workspace user. Use the scope field to reassign just this single task, or to reassign all pending tasks in the same sequence to the new user in one call — useful when a rep leaves and their workload needs to be redistributed.
PATCH /v1/tasks/{id}/assignee

Path parameters

id
string (UUID)
required
The ID of the task to reassign.

Request body

assignee_user_id
string (UUID)
required
The ID of the workspace user to assign the task to.
scope
string
Controls how many tasks are reassigned. Defaults to TASK.
  • TASK — reassign only this specific task.
  • SEQUENCE — reassign this task and all other pending tasks belonging to the same sequence run.

Example — reassign all tasks in a sequence to a new rep

curl -X PATCH "https://api.topo.io/v1/tasks/019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f/assignee" \
  -H "Authorization: Bearer topo_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "assignee_user_id": "01c1d2e3-f4a5-6b78-9c0d-e1f2a3b4c5d6",
    "scope": "SEQUENCE"
  }'
{
  "id": "019e5f6a-7b8c-9d01-2e3f-4a5b6c7d8e9f",
  "organization_id": "018e9d8c-7b6a-7f5e-4d3c-2b1a0f9e8d7c",
  "type": "CALL",
  "priority": "HOT",
  "status": "PENDING",
  "sequence_id": "018f3c1a-4b2d-7e8f-9a0b-1c2d3e4f5a6b",
  "assignee_user_id": "01c1d2e3-f4a5-6b78-9c0d-e1f2a3b4c5d6",
  "disposition": null,
  "reopened_at": null,
  "reopen_reason": null,
  "skipped_at": null,
  "completed_at": null,
  "created_at": "2025-03-13T07:00:00Z",
  "updated_at": "2025-03-13T11:20:00Z"
}
When scope is SEQUENCE, only tasks in PENDING or IN_PROGRESS status are reassigned. Already-completed and skipped tasks are not affected.