API REST
Chats
Los canales de los proyectos, los hilos, las reacciones, los mensajes directos y las apps de los Chats.
- Chats (
/chat, un canal por proyecto, como en Slack): de quien trabaja en el proyecto (admin, PO/PM, QA y dev; el stakeholder no lo ve, 403).GET /chat(tracker:read) lista los canales de la persona del token (los proyectos activos):unreadymentionssumados ychannels, cada uno conproject(id,slug,name),unread(mensajes nuevos en la conversación principal),mentions(menciones y respuestas en sus hilos todavía no leídas),last_message_atyurl.GET /projects/{prefijo, slug o id}/chat(tracker:read) traeproject,url,people(a quién se puede mencionar con @Nombre:id,nameyme, la persona del token; conaquaactivada en la empresa, aqua viene al final, conappaqua; viene también con?thread_id),unread(las no leídas de la persona del token),last_read_at,has_moreymessages, de la conversación principal en el orden en que se escribieron (sin cursor, las últimas 50;?before=<id>las anteriores,?after=<id>las que llegaron después,?limit=hasta 200,?mark_read=1marca como leída hasta la última devuelta). Con?thread_id=<id>(el primer mensaje de un hilo) traethread(ese mensaje) yreplies(las respuestas, hasta 500;?after=<id>solo las nuevas;?mark_read=1marca como leídas las menciones y respuestas del hilo). Cada mensaje:id,thread_id(el hilo en el que es respuesta, onull),in_channelythread_root(author,text: la respuesta del hilo que también fue a la conversación principal y el comienzo del mensaje al que responde),author,app(el mensaje escrito por una app, conkeyyname;nullen el de una persona),author_id,author_avatar_url(la foto,nullsin foto),text(markdown; vacío en el eliminado y en el que es solo adjunto),attachments(los archivos adjuntos, en orden:id,name,type,kind(image,videoofile),size_bytesydownload_url; vacío en el eliminado),at,edited_at,deleted(by,at),mine(escrito por la persona del token),can_editycan_delete(lo que puede hacer con el mensaje),mentions,mentions_me,issues(las tareas citadas por el código que la persona ve:code,title,open,url),reactions(emoji,count,mine,people),thread(en la conversación principal:replies,last_reply_atypeople, quién respondió;nullsin respuestas) yurl.POST /projects/{ref}/chat(tracker:write) envía{"text": "..."}en la conversación principal o{"text": "...", "thread_id": "<id>"}en el hilo de ese mensaje (con el id de una respuesta, entra en el mismo hilo;"also_in_channel": truetambién pone la respuesta en la conversación principal, como el "También enviar al canal" de la pantalla;reply_to_ides el nombre anterior; hasta 10.000 caracteres; @Nombre menciona a alguien del canal, y quien está en el hilo recibe la respuesta, en la Bandeja de entrada, en la campana y en el dispositivo) y devuelvemessage(id,thread_id,urlyaqua_replying: el mensaje llamó a @aqua y va a responder en el hilo), 201. Adjuntos (fotos, PDF, zip, planillas, logs, videos: los formatos de los adjuntos de tareas, png, jpg, jpeg, webp, gif, mp4, mov, pdf, json, txt, log, md, csv, zip): en JSON,"attachments": [{"file_name": "captura.png", "content_base64": "..."}]o[{"url": "https://..."}], como en los comentarios; omultipart/form-datacontext,thread_id,also_in_channely un campofilespor archivo. Hasta 5 por mensaje, 15 MB cada uno y 14 MB en total, y 60 archivos por hora por persona; con adjunto,textpuede faltar.GET /chat/attachments/{id}(tracker:read) descarga el archivo, con el mismo token (aceptaRange), para quien lee la conversación del mensaje. Eliminar el mensaje borra sus adjuntos.POST /projects/{ref}/chat/{id}/reactions(tracker:write) con{"emoji": "👍"}marca la reacción de la persona del token yDELETEcon el mismo cuerpo la quita (cada persona, cada emoji una vez; hasta 20 emojis distintos por mensaje); devuelveid,emojiyreacted.PATCH /projects/{ref}/chat/{id}(tracker:write, solo quien lo escribió) lo corrige con{"text": "..."};DELETE /projects/{ref}/chat/{id}(tracker:write, quien lo escribió o un admin) lo elimina (queda en su lugar como eliminado; el texto anterior va al historial de la empresa).POST /projects/{ref}/chat/read(tracker:read) con{"message_id": "<id>"}(o{}, hasta ahora) marca la conversación principal como leída y devuelveunread.GET /projects/{ref}/chat/issues?q=(tracker:read) traeissues, las tareas para citar en un mensaje, como la lista que se abre al escribir#en el campo de la pantalla (hasta 8; solo las que ve la persona del token): sinq, por contexto, primero las citadas por última vez en la conversación (reasoncited), después las abiertas con la persona del token (mine) y las abiertas del proyecto movidas por última vez (project); con el comienzo de un código (MOB-oMOB-12, que encuentra MOB-0012), completa por el código, primero las del proyecto; con palabras, la búsqueda por texto y significado de/search(reasonnull). Cada una:id,code,title,open,project(el nombre),reasonyurl; elcodeescrito en eltextse vuelve enlace y tarjeta. Proyecto archivado: solo lectura (422 al escribir). En el MCP:list_chat_channels,list_chat_messages,send_chat_message,react_to_chat_message,edit_chat_message,delete_chat_messageysuggest_chat_issues. - Mensajes directos (
/chat/direct/<id de la persona>): la conversación privada entre la persona del token y otra persona del equipo de la misma empresa (quien trabaja en algún proyecto de ella, menos el stakeholder, y los admins y dueños). Solo las dos la leen; ni el admin la ve.GET /chattambién traedirects(las conversaciones con mensajes, la más reciente primero:id,person(id,name),unread,last_message_at,url) ypeople(con quién puede abrir una:id,name,url); elunreadde arriba suma los canales y las conversaciones directas.GET /chat/direct/{persona}(tracker:read; la persona por id o correo; abre la conversación la primera vez) traeperson,url,people(vacío: no hay @menciones),unread,last_read_at,has_moreymessages, con los mismos parámetros y campos de la conversación del proyecto, sin hilos.POST /chat/direct/{persona}(tracker:write) envía{"text": "..."}, con adjuntos como en el canal (la otra persona recibe el aviso en el dispositivo;thread_idda 422);PATCH/DELETE /chat/direct/{persona}/{id}corrige y elimina (solo quien lo escribió; fuera del historial de la empresa),POST/DELETE /chat/direct/{persona}/{id}/reactionsreacciona,POST /chat/direct/{persona}/readmarca como leída yGET /chat/direct/{persona}/issues?q=sugiere las tareas para citar (sin proyecto del canal: las citadas en la conversación y las abiertas con la persona del token). Una persona fuera del equipo: 404; quien salió del equipo después deja la conversación solo para lectura (422 al escribir). En el MCP, las mismas tools de la conversación conpersonen lugar deproject. - Apps de los Chats: quien escribe en el canal sin ser una persona (el mensaje viene con
appyauthor_idnull; nadie lo corrige, el admin lo elimina). El texto que escriben las apps y su catálogo (name,summary,descriptiony la descripción de los permisos) vienen en el idioma de quien lee: el elegido en Tu cuenta o, en automático, el deAccept-Language; lo que escriben las personas (nombres, asuntos, la respuesta de aqua) queda como se escribió. Cada app tiene un manifiesto: nombre, lo que pide (permissions: obligatorias, que entran siempre, y opcionales, que el admin elige al instalar), los eventos que escucha y lo que elige cada canal. Los permisos:chat:write(escribir en la conversación),issues:read(ver las tareas del proyecto),comments:read(ver los comentarios, para el aviso de comentario nuevo),meetings:create(crear reuniones en Google Meet)chat:direct(funcionar en las conversaciones directas) yai:use(responder con aqua, gastando los créditos de IA de la empresa). Las oficiales:task_updates(Avisos de tareas: publica en el canal cuando una tarea del proyecto se crea, cambia de estado, cambia de responsable o recibe un comentario (este solo concomments:read, opcional), con su tarjeta; cada canal elige los eventos),google_meetyaqua(ver abajo) yautomations(Automatizaciones: viene con tracker y escribe cuando una regla de automatización tiene la acción "Enviar mensaje en el canal"). La empresa instala (solo admins y dueños) y el PO/PM del proyecto o un admin la activa en cada canal, o el admin la activa en todos los canales de una vez, incluso en los que se creen después. En la conversación directa, solo las apps conchat:directconcedido, cuando una de las dos personas la activa; cualquiera la desactiva, y la app cuenta en la conversación quién la activó o desactivó.GET /apps(tracker:read) traeapps, el catálogo de la empresa:key,name,summary,description,official,built_in,company_wide(viene activada en toda la empresa: sin instalar ni activar por canal;installedes false cuando un admin la desactivó),permissions(key,description,required: obligatoria, ygranted: la empresa la concedió),events,installed,installed_at,channels(en cuántos canales está activada) yall_channels(activada en todos los canales, incluso en los nuevos).POST /apps/{key}(tracker:write) la instala, con{"permissions": ["chat:write", "meetings:create", "chat:direct"]}(las obligatorias entran siempre; sin cuerpo, solo ellas);PATCH /apps/{key}con{"permissions": [...]}cambia lo concedido (quitarchat:directdesactiva la app en todas las conversaciones directas);{"all_channels": true}, en elPOSTo en elPATCH, activa la app en todos los canales, incluso en los nuevos (entonces el canal no la desactiva, solo elige los avisos), yfalsevuelve a los canales que la activaron uno por uno (no vale para las personales);DELETE /apps/{key}la desinstala (la desactiva en todos los canales y conversaciones directas; los mensajes quedan). Devuelvenkey,installedypermissions(las concedidas); un permiso que la app no pide da 422.GET /projects/{ref}/chat/apps(tracker:read, quien participa en la conversación) traeproject,can_manage(puede activar y desactivar),can_installyapps(key,name,summary,built_in,company_wide,installed,enabled,all_channelsy, entask_updates,eventsyallowed_events, los que los permisos dejan elegir).PATCH /projects/{ref}/chat/apps/{key}(tracker:write, PO/PM o admin) con{"enabled": true, "events": ["issue.created", "issue.status_changed", "issue.assigned", "comment.created"]}la activa y elige los avisos (sinevents, queda lo que había o lo de por defecto: tarea creada y estado cambiado) y{"enabled": false}la desactiva (conall_channels, da 422); una app no instalada da 422. En la conversación directa:GET /chat/direct/{persona}/apps(tracker:read; la persona por id o correo) traeperson,active,can_installyapps(key,name,summary,installed,allowed: liberada en las conversaciones directas,enabledyenabled_by: quién la activó);PATCH /chat/direct/{persona}/apps/{key}(tracker:write, cualquiera de las dos personas) con{"enabled": true}la activa y{"enabled": false}la desactiva. En el MCP:list_chat_apps(conproject, las del canal; conperson, las de la conversación directa),install_chat_app(conpermissionsyall_channels) yset_chat_app(conprojectoperson). - Google Meet (
google_meet, app oficial): crea la reunión en el canal, en la cuenta de Google de quien la llama, y publica la tarjeta con el enlace para entrar. Cada persona conecta su propia cuenta de Google una vez, por el navegador (la pantalla de Google no se abre por la API). En el canal, la app viene conaccount(configured,connectedyemail, la cuenta de la persona del token).GET /apps/google_meet/account(tracker:read) traeconfigured,connected,emailyconnect_url(ábrelo en el navegador, con sesión iniciada en tracker);DELETE /apps/google_meet/account(tracker:write) desconecta y quita el acceso en Google.POST /projects/{ref}/chat/meet(tracker:write, quien participa en la conversación) con{"title": "Planificación del sprint"}(opcional) y"thread_id"(opcional: la crea dentro del hilo de ese mensaje) crea la sala y devuelveproject,message(id,thread_id,url) ymeeting(urlpara entrar,code,title,starts_atyends_at), 201. Para agendar, manda también"starts_at"(ISO 8601 con la zona horaria, ej.:2026-10-22T14:00:00-03:00),"duration_minutes"(15 a 480, por defecto 30),"time_zone"(IANA, por defectoAmerica/Sao_Paulo) y"guests"(hasta 50 correos o ids de personas de la conversación): tracker crea el evento en el Google Calendar de quien llama, con la sala de Meet, Google envía la invitación a los invitados ymeetingtrae tambiénguests(cuántos fueron invitados). Agendar pide que la cuenta de Google haya permitido el acceso al calendario; quien conectó antes de eso recibe 422 con el enlace para conectar de nuevo.GET /apps/google_meet/meetings(tracker:read) traemeetings, las reuniones con Meet de los próximos 14 días del calendario de la persona del token:title,url,code,starts_at,ends_atycalendar_url. En la conversación directa,POST /chat/direct/{persona}/meetcon{"title": "..."}(sin hilo), con la app activada en la conversación. App desactivada en el canal o en la conversación, o sinchat:direct: 403; sin la cuenta conectada: 422, con el enlace para conectar. El mensaje traecard:typemeeting,providergoogle_meet,url,code,title,started_by(el nombre de quien llamó) y, en la agendada,starts_at,ends_atyevent_id(el evento en el Google Calendar de quien la agendó), ymeeting_responses(en la agendada:yes,maybe,no, cuántos respondieron desde tracker, ymine, la respuesta de la persona del token;nullen las demás). En la pantalla, el botón de la cámara al lado del campo (Empezar ahora, Agendar reunión… y Próximas reuniones),/meet asuntoo/meet lista. En el MCP:start_meeting(conprojectoperson; constarts_at, agenda) ylist_meetings. - Google Calendar (
google_calendar, app oficial): personal. La empresa la instala y cada persona la usa con su propia cuenta de Google (la misma conexión de Google Meet, con acceso a la agenda), sin activarla por canal: en el catálogo,channelsvienenull. Permisos:calendar:read(obligatorio: leer la agenda de quien la usa) ycalendar:respond(opcional: responder a las invitaciones desde tracker).GET /apps/google_calendar/agenda(tracker:read), con?date=AAAA-MM-DDo?days=1(desde hoy; por defecto hoy) y?time_zone=(por defectoAmerica/Sao_Paulo), devuelvedate,time_zone,can_respond,reminder_minutesyevents:id,title,starts_at,ends_at,all_day,meeting_url(la sala de Meet),calendar_urlyresponse(yes,maybe,no;pendingsin respuesta;nullcuando la persona la organizó o no está invitada).GET /apps/google_calendar/settings(tracker:read) devuelveinstalled,can_respond,account(configured,connected,emailycalendar),connect_urlyreminder_minutes;PATCH(tracker:write) con{"reminder_minutes": 15}cambia el aviso antes de cada reunión (5, 10, 15 o 30; 0 lo desactiva). El aviso llega a la campana y al celular (el tipo de notificaciónmeeting, "Reuniones", en las preferencias; sin correo) y abre la sala de Meet. Responder a la invitación (concalendar:respond):POST /projects/{ref}/chat/{id}/responseoPOST /chat/direct/{pessoa}/{id}/responsecon{"response": "yes"}(yes,maybe,no) en la tarjeta de una reunión agendada desde tracker devuelveresponses;POST /apps/google_calendar/events/{id}/responseresponde a un evento de la agenda. La respuesta va al Google Calendar de quien responde y Google avisa a quien la organizó; quien la organizó no responde (422). Sin la app: 403; sin el permiso de responder: 403; sin la cuenta conectada con acceso a la agenda: 422, con el enlace para conectar. En la pantalla,/agenda(o/agenda amanhã) y el botón de la agenda al lado del campo muestran, solo a quien lo pidió, la agenda del día, con Entrar, Sí/Tal vez/No y el aviso; la tarjeta de la reunión agendada gana Sí, Tal vez y No y el conteo. En el MCP:get_agenda,respond_to_meeting(conmessageyprojectoperson, o conevent_id) yset_meeting_reminder. - aqua (
aqua, app oficial,company_wide): viene activada en todos los canales de la empresa, sin instalar ni activar canal por canal (PATCH /projects/{ref}/chat/apps/aquada 422). Un admin la desactiva en la empresa conDELETE /apps/aquay la vuelve a activar conPOST /apps/aqua; también necesita aqua (la IA) activada en la empresa. Activada, un mensaje con @aqua (en la conversación principal o en un hilo, por la pantalla, por la API o por el MCP) recibe la respuesta de aqua en el hilo de ese mensaje. aqua escribe en el momento "Consultando o projeto…" (un mensaje de la app, conappaqua) y cambia el texto por la respuesta cuando termina, sin marcarlo como editado: quien lee por la API ve el cambio en la próxima lectura del hilo (GET /projects/{ref}/chat?thread_id=<id>, con el id del mensaje que la llamó, o suthread_id). Consulta como quien la llamó, con el perfil de esa persona en el proyecto, solo para leer; como la respuesta es para todo el canal, solo entran el proyecto del canal (tareas, sprints, releases, pruebas, horas, personas y la conversación) y los documentos de la empresa: los demás proyectos, la Bandeja de entrada y los mensajes directos quedan fuera. Cada respuesta cuenta como un uso de IA de quien la llamó, con los créditos de la empresa; sin créditos, la respuesta dice cuándo se renuevan. Quien la llamó recibe el aviso de la respuesta (la preferencia Comentarios). Los adjuntos del mensaje que la llamó van junto con la pregunta: aqua ve las capturas y los PDF y lee los textos; de los otros mensajes solo ve el nombre. La app pidechat:write,issues:readyai:use.