REST API
Chats
Project channels, threads, reactions, direct messages and Chats apps.
- Chats (
/chat, one channel per project, like Slack): for the people who work on the project (admin, PO/PM, QA and dev; stakeholders don't see it, 403).GET /chat(tracker:read) lists the token's person's channels (the active projects):unreadandmentionstotals andchannels, each withproject(id,slug,name),unread(new messages in the main conversation),mentions(mentions and replies in their threads not yet read),last_message_atandurl.GET /projects/{prefix, slug or id}/chat(tracker:read) returnsproject,url,people(who can be mentioned with @Name:id,nameandme, the token's person; withaquaon in the company, aqua comes last, withappaqua; also returned with?thread_id),unread(the token's person's unread ones),last_read_at,has_moreandmessages, from the main conversation in the order they were written (without a cursor, the last 50;?before=<id>the earlier ones,?after=<id>the ones that arrived later,?limit=up to 200,?mark_read=1marks as read up to the last one returned). With?thread_id=<id>(the first message of a thread) it returnsthread(that message) andreplies(the replies, up to 500;?after=<id>only the new ones;?mark_read=1marks the thread's mentions and replies as read). Each message:id,thread_id(the thread it replies in, ornull),in_channelandthread_root(author,text: the thread reply that also went to the main conversation and the start of the message it replies to),author,app(a message written by an app, withkeyandname;nullfor a person's),author_id,author_avatar_url(the photo,nullwithout a photo),text(markdown; empty when deleted or attachment-only),attachments(the attached files, in order:id,name,type,kind(image,videoorfile),size_bytesanddownload_url; empty when deleted),at,edited_at,deleted(by,at),mine(written by the token's person),can_editandcan_delete(what they can do with the message),mentions,mentions_me,issues(the tasks cited by code that the person sees:code,title,open,url),reactions(emoji,count,mine,people),thread(in the main conversation:replies,last_reply_atandpeople, who replied;nullwithout replies) andurl.POST /projects/{ref}/chat(tracker:write) sends{"text": "..."}in the main conversation or{"text": "...", "thread_id": "<id>"}in that message's thread (with a reply's id, it goes into the same thread;"also_in_channel": truealso puts the reply in the main conversation, like "Also send to the channel" on screen;reply_to_idis the old name; up to 10,000 characters; @Name mentions someone in the channel, and whoever is in the thread gets the reply, in the Inbox, the bell and on their device) and returnsmessage(id,thread_id,urlandaqua_replying: the message called @aqua and it will reply in the thread), 201. Attachments (photos, PDF, zip, spreadsheets, logs, videos: the task attachment formats, png, jpg, jpeg, webp, gif, mp4, mov, pdf, json, txt, log, md, csv, zip): in JSON,"attachments": [{"file_name": "screenshot.png", "content_base64": "..."}]or[{"url": "https://..."}], as in comments; ormultipart/form-datawithtext,thread_id,also_in_channeland onefilesfield per file. Up to 5 per message, 15 MB each and 14 MB combined, and 60 files per hour per person; with an attachment,textcan be left out.GET /chat/attachments/{id}(tracker:read) downloads the file, with the same token (acceptsRange), for whoever reads the message's conversation. Deleting the message deletes its attachments.POST /projects/{ref}/chat/{id}/reactions(tracker:write) with{"emoji": "👍"}adds the token's person's reaction andDELETEwith the same body removes it (each person, each emoji once; up to 20 different emojis per message); returnsid,emojiandreacted.PATCH /projects/{ref}/chat/{id}(tracker:write, the author only) fixes it with{"text": "..."};DELETE /projects/{ref}/chat/{id}(tracker:write, the author or an admin) deletes it (it stays in place as deleted; the previous text goes to the company history).POST /projects/{ref}/chat/read(tracker:read) with{"message_id": "<id>"}(or{}, up to now) marks the main conversation as read and returnsunread.GET /projects/{ref}/chat/issues?q=(tracker:read) returnsissues, the tasks to cite in a message, like the list that opens when typing#in the field on screen (up to 8; only the ones the token's person sees): withoutq, by context, first the ones cited last in the conversation (reasoncited), then the open ones assigned to the token's person (mine) and the project's open ones touched last (project); with the start of a code (MOB-orMOB-12, which finds MOB-0012), it completes by code, the project's first; with words, the text and meaning search of/search(reasonnull). Each one:id,code,title,open,project(the name),reasonandurl; acodewritten in thetextbecomes a link and a card. Archived project: read-only (422 when writing). In the MCP:list_chat_channels,list_chat_messages,send_chat_message,react_to_chat_message,edit_chat_message,delete_chat_messageandsuggest_chat_issues. - Direct messages (
/chat/direct/<person id>): the private conversation between the token's person and another team member in the same company (anyone who works on one of its projects, except stakeholders, plus admins and owners). Only the two of them read it; not even the admin sees it.GET /chatalso returnsdirects(the conversations with messages, most recent first:id,person(id,name),unread,last_message_at,url) andpeople(who they can start one with:id,name,url); the top-levelunreadadds up channels and direct conversations.GET /chat/direct/{person}(tracker:read; the person by id or e-mail; opens the conversation the first time) returnsperson,url,people(empty: there are no @mentions),unread,last_read_at,has_moreandmessages, with the same parameters and fields as the project conversation, without threads.POST /chat/direct/{person}(tracker:write) sends{"text": "..."}, with attachments as in the channel (the other person gets a device notification;thread_idgives 422);PATCH/DELETE /chat/direct/{person}/{id}fixes and deletes (the author only; outside the company history),POST/DELETE /chat/direct/{person}/{id}/reactionsreacts,POST /chat/direct/{person}/readmarks as read andGET /chat/direct/{person}/issues?q=suggests tasks to cite (without a channel project: the ones cited in the conversation and the open ones assigned to the token's person). A person outside the team: 404; someone who left the team later leaves the conversation read-only (422 when writing). In the MCP, the same conversation tools withpersoninstead ofproject. - Chats apps: whoever writes in the channel without being a person (the message comes with
appandauthor_idnull; nobody edits it, the admin deletes it). The text apps write and their catalog (name,summary,descriptionand the permission descriptions) come in the reader's language: the one chosen in Your account or, on automatic, the one inAccept-Language; what people write (names, subjects, aqua's answer) stays as written. Each app has a manifest: name, what it asks for (permissions: required ones, always granted, and optional ones, which the admin picks when installing), the events it listens to and what each channel chooses. The permissions:chat:write(write in the conversation),issues:read(see the project's tasks),comments:read(see comments, for the new comment notice),meetings:create(create Google Meet meetings)chat:direct(work in direct conversations) andai:use(reply with aqua, spending the company's AI credits). The official ones:task_updates(Task updates: posts in the channel when a project task is created, changes status, changes assignee or gets a comment (the last one only withcomments:read, optional), with its card; each channel picks the events),google_meetandaqua(see below) andautomations(Automations: comes with tracker and writes when an automation rule has the "Send a channel message" action). The company installs (admins and owners only) and the project's PO/PM or an admin turns it on in each channel, or the admin turns it on in every channel at once, including channels created later. In a direct conversation, only apps withchat:directgranted, when one of the two people turns it on; either one turns it off, and the app tells the conversation who turned it on or off.GET /apps(tracker:read) returnsapps, the company catalog:key,name,summary,description,official,built_in,company_wide(on across the whole company: no install and no per-channel switch;installedis false when an admin turned it off),permissions(key,description,required: mandatory, andgranted: the company granted it),events,installed,installed_at,channels(how many channels it's on in) andall_channels(on in every channel, including new ones).POST /apps/{key}(tracker:write) installs, with{"permissions": ["chat:write", "meetings:create", "chat:direct"]}(the required ones always go in; without a body, only those);PATCH /apps/{key}with{"permissions": [...]}changes what's granted (removingchat:directturns the app off in every direct conversation);{"all_channels": true}, in thePOSTor thePATCH, turns the app on in every channel, including new ones (then the channel can't turn it off, only pick the updates), andfalsegoes back to the channels that turned it on one by one (not for personal apps);DELETE /apps/{key}uninstalls (turns it off in every channel and direct conversation; the messages stay). They returnkey,installedandpermissions(the granted ones); a permission the app doesn't ask for gives 422.GET /projects/{ref}/chat/apps(tracker:read, conversation members) returnsproject,can_manage(can turn on and off),can_installandapps(key,name,summary,built_in,company_wide,installed,enabled,all_channelsand, fortask_updates,eventsandallowed_events, the ones the permissions allow choosing).PATCH /projects/{ref}/chat/apps/{key}(tracker:write, PO/PM or admin) with{"enabled": true, "events": ["issue.created", "issue.status_changed", "issue.assigned", "comment.created"]}turns it on and picks the notices (withoutevents, it keeps what it had or the default: task created and status changed) and{"enabled": false}turns it off (withall_channels, it gives 422); an app that isn't installed gives 422. In a direct conversation:GET /chat/direct/{person}/apps(tracker:read; the person by id or e-mail) returnsperson,active,can_installandapps(key,name,summary,installed,allowed: allowed in direct conversations,enabledandenabled_by: who turned it on);PATCH /chat/direct/{person}/apps/{key}(tracker:write, either of the two people) with{"enabled": true}turns it on and{"enabled": false}turns it off. In the MCP:list_chat_apps(withproject, the channel's; withperson, the direct conversation's),install_chat_app(withpermissionsandall_channels) andset_chat_app(withprojectorperson). - Google Meet (
google_meet, official app): creates the meeting in the channel, in the caller's Google account, and posts the card with the join link. Each person connects their own Google account once, through the browser (Google's screen doesn't open through the API). In the channel, the app comes withaccount(configured,connectedandemail, the token's person's account).GET /apps/google_meet/account(tracker:read) returnsconfigured,connected,emailandconnect_url(open it in the browser, signed in to tracker);DELETE /apps/google_meet/account(tracker:write) disconnects and revokes access at Google.POST /projects/{ref}/chat/meet(tracker:write, conversation members) with{"title": "Sprint planning"}(optional) and"thread_id"(optional: creates it inside that message's thread) creates the room and returnsproject,message(id,thread_id,url) andmeeting(urlto join,code,title,starts_atandends_at), 201. To schedule, also send"starts_at"(ISO 8601 with the offset, e.g.2026-10-22T14:00:00-03:00),"duration_minutes"(15 to 480, default 30),"time_zone"(IANA, defaultAmerica/Sao_Paulo) and"guests"(up to 50 e-mails or ids of people in the conversation): tracker creates the event in the caller's Google Calendar, with the Meet room, Google sends the invite to the guests andmeetingalso hasguests(how many were invited). Scheduling requires the Google account to have allowed calendar access; whoever connected before that gets 422 with the link to connect again.GET /apps/google_meet/meetings(tracker:read) returnsmeetings, the meetings with Meet in the next 14 days of the token's person's calendar:title,url,code,starts_at,ends_atandcalendar_url. In a direct conversation,POST /chat/direct/{person}/meetwith{"title": "..."}(no thread), with the app on in the conversation. App off in the channel or conversation, or withoutchat:direct: 403; without the account connected: 422, with the link to connect. The message hascard:typemeeting,providergoogle_meet,url,code,title,started_by(the caller's name) and, when scheduled,starts_at,ends_atandevent_id(the event in the scheduler's Google Calendar), plusmeeting_responses(when scheduled:yes,maybe,no, how many replied through tracker, andmine, the token person's reply;nullotherwise). On screen, the camera button next to the field (Start now, Schedule meeting… and Upcoming meetings),/meet subjector/meet lista. In the MCP:start_meeting(withprojectorperson; withstarts_at, it schedules) andlist_meetings. - Google Calendar (
google_calendar, official app): personal. The company installs it and each person uses it with their own Google account (the same Google Meet connection, with calendar access), with no per-channel setting: in the catalog,channelsisnull. Permissions:calendar:read(required: read the calendar of whoever uses it) andcalendar:respond(optional: reply to invitations through tracker).GET /apps/google_calendar/agenda(tracker:read), with?date=YYYY-MM-DDor?days=1(from today; default today) and?time_zone=(defaultAmerica/Sao_Paulo), returnsdate,time_zone,can_respond,reminder_minutesandevents:id,title,starts_at,ends_at,all_day,meeting_url(the Meet room),calendar_urlandresponse(yes,maybe,no;pendingwith no reply;nullwhen the person organized it or isn't invited).GET /apps/google_calendar/settings(tracker:read) returnsinstalled,can_respond,account(configured,connected,emailandcalendar),connect_urlandreminder_minutes;PATCH(tracker:write) with{"reminder_minutes": 15}changes the reminder before each meeting (5, 10, 15 or 30; 0 turns it off). The reminder arrives in the bell and on the phone (notification typemeeting, "Meetings", in the preferences; no email) and opens the Meet room. Replying to the invitation (withcalendar:respond):POST /projects/{ref}/chat/{id}/responseorPOST /chat/direct/{pessoa}/{id}/responsewith{"response": "yes"}(yes,maybe,no) on the card of a meeting scheduled through tracker returnsresponses;POST /apps/google_calendar/events/{id}/responsereplies to an agenda event. The reply goes to the Google Calendar of whoever answers and Google notifies the organizer; the organizer doesn't reply (422). Without the app: 403; without the permission to reply: 403; without the account connected with calendar access: 422, with the link to connect. On screen,/agenda(or/agenda amanhã) and the agenda button next to the field show, only to whoever asked, the day's agenda, with Join, Yes/Maybe/No and the reminder; the scheduled meeting card gets Yes, Maybe and No and the count. In the MCP:get_agenda,respond_to_meeting(withmessageandprojectorperson, or withevent_id) andset_meeting_reminder. - aqua (
aqua, official app,company_wide): on in every channel of the company, with no install and no per-channel switch (PATCH /projects/{ref}/chat/apps/aquagives 422). An admin turns it off for the company withDELETE /apps/aquaand back on withPOST /apps/aqua; it also needs aqua (the AI) on in the company. When on, a message with @aqua (in the main conversation or a thread, on screen, through the API or the MCP) gets aqua's reply in that message's thread. aqua immediately writes "Consultando o projeto…" (an app message, withappaqua) and replaces the text with the answer when it's done, without marking it as edited: whoever reads through the API sees the change on the next read of the thread (GET /projects/{ref}/chat?thread_id=<id>, with the id of the calling message, or itsthread_id). It looks things up as the caller, with that person's role in the project, read-only; since the answer is for the whole channel, only the channel's project (tasks, sprints, releases, tests, hours, people and the conversation) and the company's documents count: other projects, the Inbox and direct messages stay out. Each answer counts as one AI use for the caller, with the company's credits; without credits, the answer says when they renew. The caller gets the reply notification (the Comments preference). The calling message's attachments go along with the question: aqua sees screenshots and PDFs and reads text files; for other messages she only sees the file names. The app asks forchat:write,issues:readandai:use.