Everything a connected assistant can do, and the scope that gates each capability. Setup lives in Connect your AI.
| Tool | What it does | Scope(s) | |
list_boards | List the boards a team owns. Pass team_id from whoami/list_teams. | boards.read | read |
get_board | Get a single board by its opaque id (brd_…). | boards.read | read |
list_board_lists | List a board's task lists (columns). A list id (lst_…) is where you create or move tasks. | lists.read | read |
list_board_members | List a board's active members. Use a member's email wherever a person is needed: the task assignee, person custom fields, sub-task assignees and @email mentions in comments. | boards.read | read |
list_board_custom_fields | List a board's custom fields with their types and (for tag/status/select/multiselect) options {id,label} — use a field id when setting values with update_task (options by id or label). Type tasks is a sub-task list (change it with add_subtask/update_subtask/delete_subtask). Fields flagged ai: true (managed by Sortd AI) take values like any other; setting Response Status to Actioned clears the AI fields. | customfields.read | read |
list_board_templates | The available board templates — each shows the lists (columns) and custom fields it creates. Use a template's key with create_board; the 'sales' template creates a sales board (deal cards). | boards.read | read |
create_board | Create a team board — plain, or from a template (see list_board_templates): the template provisions lists, custom fields and sample tasks, and 'sales' makes it a sales board. | boards.write | write |
update_board | Rename a board. | boards.write | write |
delete_board | Soft-delete a board (recoverable). | boards.write | destructive |
create_list | Add a task list (column) to a board. | lists.write | write |
update_list | Rename a list. | lists.write | write |
reorder_list | Reposition a list (column) on its board. Pass after_list_id to place it directly after a specific list, or position "start"/"end". The response reports the position the server actually recorded. | lists.write | write |
delete_list | Soft-delete a list (recoverable). | lists.write | destructive |
create_custom_field | Create a custom field on a board — any type the app offers. Option types (select/status/tag/multiselect) take an options list. person = a board member, contact/company = a CRM record, tasks = a sub-task list, attachment = links. | customfields.write | write |
update_custom_field | Update a custom field (name, options, display_on_card). Fields flagged ai: true are managed by Sortd AI and their settings cannot be changed. | customfields.write | write |
delete_custom_field | Soft-delete a custom field on a board. Fields flagged ai: true are managed by Sortd AI and cannot be deleted. | customfields.write | destructive |
| Tool | What it does | Scope(s) | |
list_tasks | List/search tasks. Provide ONE scope: list_id, board_id, thread_id (raw Gmail hex), contact_id (con_…) or team_id (searches EVERY board you can access in the team — requires at least one filter). Optional filters (board/list/team scope): q, completed, shade, due_before, due_after, assigned_to (email/name), custom_field_id (+ custom_field_value — matched on the typed value: an option label or id, a member email, true/false, a number). Cursor-paginated. | tasks.read | read |
get_task | Get a single task by its opaque id (tsk_…): title, list, assignee, colour, status (open/completed; won/lost/abandoned on sales cards), next_step, read state, link attachments, deal/contact on sales cards, linked thread_ids, and typed custom_fields (options as {id,label}, people as {email,name}, contacts as {id,name}, numbers, true/false checkboxes, sub-task lists). | tasks.read | read |
create_task | Create a task on a list. New tasks go to the TOP by default — when adding several in sequence, pass position "bottom" (or anchor each with after_task_id) or the batch ends up in reverse order. On a Sales board the new card is a sales card (status open; set deal/contact_id with update_task). | tasks.write | write |
create_task_from_email | Turn an email thread into a task on a list — the API equivalent of dragging the email onto a board. The task title defaults to the email subject; pass title only to override it. notes and due_at work here just as they do on create_task. The thread stays linked to the task, so replies keep landing on it. Use add_thread_to_task to link further emails. Call suggest_tasks_for_email first: if the email belongs on an existing card, link it there instead of creating a duplicate. On a Sales board this creates a sales card. | tasks.write + email.metadata.read | write |
add_thread_to_task | Link another email thread to an existing task — a task can carry several. Linking a thread that is already on the task does nothing, so this is safe to repeat. | tasks.write + email.metadata.read | write |
remove_thread_from_task | Unlink an email thread from a task (undo add_thread_to_task, or fix a mis-filed email). The thread stays in the mailbox and the task stays; only the link goes. unarchive=true also moves the mail back to the inbox (needs email.metadata.write). Not-found if the thread is not on the task. | tasks.write + email.metadata.read | write |
update_task | Update a task. Set title (rename it; 1–1000 characters, cannot be cleared), next_step (the card's one-line next step; "" clears), read (mark the task read/unread), status (tasks: open|completed; sales cards: open|won|lost|abandoned), deal (sales cards: {value, source, close_date, loss_reason} — send only what changes) and contact_id (sales cards: con_… or null), notes (replaces the task note; "" clears), due_at (shared due date, null clears), planned_at (YOUR personal planned day, null clears), shade (colour name, "none" clears) and/or custom_fields (array of {field_id, value}; values are typed per property: option id or label for select/status (one) and tag/multiselect (list), board member email for person, con_/cmp_ id for contact/company, true/false for checkbox, number, YYYY-MM-DD for date, null clears; sub-tasks via add_subtask/update_subtask). | tasks.write | write |
list_task_comments | A task's comment thread, newest first — the team conversation on the task. Authors are member emails/display names. | tasks.read | read |
add_task_comment | Comment on a task — leave your reasoning where the team reads it (e.g. why you set a status or filed the email). Plain text. To @-mention a board member write @ then their email, e.g. "@sam@acme.com can you check this?" — they are notified and follow the task; a non-member address is rejected (list_board_members). Live board updates behave exactly as a UI comment. | comments.write | write |
delete_task_comment | Soft-delete a comment YOU wrote (other members’ comments cannot be deleted through the API). | comments.write | destructive |
get_task_history | A task's activity log, newest first — created, moves, status/assignee/due-date/custom-field changes. Everything you do through these tools lands here exactly as a manual change would, so the team can always see what the assistant did. | tasks.read | read |
get_task_reminder | YOUR reminder on a task (reminders are per-user — this never shows other members'). null when none is set. | tasks.read | read |
set_task_reminder | Set (or replace) YOUR personal reminder on a task — one per user per task. Delivery follows the product scheduler: notify "email" sends a reminder mail, "popup" notifies in-app (default ["email"]). | tasks.write | write |
clear_task_reminder | Remove YOUR reminder from a task. Idempotent — clearing an unset reminder is a no-op. | tasks.write | write |
assign_task | Assign a task to a board member by email, or pass an empty/omitted assignee to clear it. The email must belong to an active member of the task's board (see list_board_members). Only one assignee is supported — assigning REPLACES the current assignee, as in the app. | tasks.write | write |
complete_task | Mark a task complete (status completed; the card stays on the board — use archive_task to hide it). For sales cards use update_task status won/lost/abandoned instead. | tasks.write | write |
reopen_task | Reopen a completed task (status open). For sales cards use update_task status open. | tasks.write | write |
move_task | Move a task to a DIFFERENT list — on the same board, another board, or the user's private board (moves between teams follow the team's privacy setting, as in the app). To change a task's position within the list it is already on, use reorder_task instead. | tasks.write | write |
reorder_task | Change where a task sits WITHIN its current list — this is how you act on a prioritisation. Pass after_task_id to place it directly below a specific task, or position "top"/"bottom". To impose a whole new order, walk the list front to back and anchor each task to the one that should precede it. The response reports the position the server actually recorded. | tasks.write | write |
delete_task | Soft-delete a task (recoverable; hidden from reads). | tasks.delete | destructive |
archive_task | Archive a task — move it off the board into the board archive (the app's "Archive"). Not the same as complete_task: completing changes status, archiving hides the card. Its email threads are left in the mailbox. Restore with unarchive_task; find archived tasks with list_archived_tasks. | tasks.write | write |
unarchive_task | Restore an archived task to its board — to the list it was archived from, or to list_id (a list on the same board). No-op if the task is not archived. | tasks.write | write |
list_archived_tasks | A board's archived tasks, most recently archived first (Task objects plus archived_at). Optional q filters on the title. Cursor-paginated. | tasks.read | read |
suggest_tasks_for_email | Existing tasks an email probably belongs on (the app's "add to existing card" suggestions): matches the subject against cards, and the sender when they are outside your team. Call it BEFORE create_task_from_email so a follow-up email lands on the existing card (add_thread_to_task) instead of a duplicate. Pass thread_id, or sender and/or subject. | tasks.read | read |
merge_tasks | Merge one task into another (deduplicate): the task_id task's notes, comments and email threads move to into_task_id, then task_id is DELETED. IRREVERSIBLE for task_id — confirm with the user first. Needs tasks.delete too. | tasks.write + tasks.delete | destructive |
add_task_attachment | Attach an http(s) link to a task (shows with the card's attachments). Returns the attachment id. | tasks.write | write |
remove_task_attachment | Remove an attachment from a task (attachment id from the task's attachments). | tasks.write | write |
add_subtask | Add a sub-task to a task's "Task list" custom property (field_id from list_board_custom_fields, type tasks). Optional assignee (board member email) and position (0 = first; default last). | tasks.write + customfields.write | write |
update_subtask | Change one sub-task: rename (title), tick/untick (completed), assign/unassign (assignee email or null), or move (position). | tasks.write + customfields.write | write |
delete_subtask | Delete one sub-task from a task's Task list property. | tasks.write + customfields.write | write |
remove_task_from_list | Take a task off its board without deleting it (the app's "Remove from list"): it moves into your own private space and leaves the team's boards; its emails stay linked. Use move_task to re-file it. Prefer archive_task to tidy a board. | tasks.write | write |
| Tool | What it does | Scope(s) | |
get_mailbox | Report the owner's mailbox connection state (connected / not_connected / reauth_required). Reads no mail. | email.metadata.read | read |
list_email_labels | List the mailbox's Gmail labels (system + user) for building search queries. | email.metadata.read | read |
search_email_threads | Search the mailbox with a Gmail query. Provide at least one of q / label / category. Returns thread metadata (no bodies). Cursor-paginated. Gmail only. | email.metadata.read | read |
get_email_thread | Get an email thread by raw Gmail thread id (hex). Set include_messages=true to include message bodies (needs the email.body.read scope). | email.metadata.read | read |
list_email_drafts | List the Gmail drafts on a thread. | email.metadata.read | read |
get_new_email | New mail since YOUR last call — the server keeps the cursor per connection key, so just call it again to get what arrived in between; each call advances the cursor. Returns HEADER ENVELOPES ONLY (subject, snippet, addresses, dates, thread_id — never bodies; use get_email_thread for content), covering the mail Sortd’s pipeline processes: inbox + sent, with spam/trash, filtered categories, auto-replies and Sortd sync copies excluded. Delivery is at-least-once — dedupe on message_id. The very first call initialises the cursor and returns an empty batch. CHECK AT LEAST DAILY. A stale-but-covered cursor is served normally; only once messages may genuinely have expired does the call fail with new_mail_expired — its details include the old cursor_position and a ready-made backfill_query. RECOVER IN THIS ORDER: (1) call again with reset=true — re-baselines to now and echoes previous_cursor_position; (2) if the gap matters, backfill it with search_email_threads using that backfill_query, deduping on message_id. Reset-first turns timing seams into duplicates, never losses. Typical loop: get_new_email → classify_email → create_task_from_email / apply_email_thread_labels. | email.metadata.read | read |
set_email_thread_read_state | Mark a thread read or unread. | email.metadata.write | write |
archive_email_thread | Archive a thread (remove from Inbox). | email.metadata.write | write |
unarchive_email_thread | Unarchive a thread (return to Inbox). | email.metadata.write | write |
apply_email_thread_labels | Add and/or remove Gmail labels on a thread (raw label ids). At least one of add/remove. | email.metadata.write | write |
snooze_email_thread | Snooze a thread until a future time (ISO-8601). | email.metadata.write | write |