API: Espacios de trabajo
Listar espacios de trabajo
Sección titulada «Listar espacios de trabajo»GET /api/workspacesDevuelve todos los espacios de trabajo de los que eres miembro, con tu rol en cada uno.
[ { "id": "019f7462-ac2a-73e3-ab40-be2e43f943f9", "name": null, "personal": true, "ownerFirstName": "Greta", "role": "OWNER" }, { "id": "019f7464-1617-7464-b8ef-7f34b631bdfa", "name": "Lengl Family", "personal": false, "ownerFirstName": "Greta", "role": "OWNER" }]nameesnullen los espacios de trabajo personales — los clientes muestran una etiqueta localizada a partir deownerFirstName.
Crear un espacio de trabajo compartido
Sección titulada «Crear un espacio de trabajo compartido»POST /api/workspaces{ "name": "Renovation" }Devuelve 201 con { "id": "…" }. Errores: 409 si ya posees un espacio de
trabajo con este nombre (sin distinguir mayúsculas y minúsculas), 403 si
alcanzaste tu límite de espacios de trabajo compartidos.
Eliminar un espacio de trabajo
Sección titulada «Eliminar un espacio de trabajo»DELETE /api/workspaces/{workspaceId}Solo el propietario. Devuelve 204. Elimina permanentemente todas las tareas,
listas, membresías y archivos adjuntos. Los espacios de trabajo personales no
se pueden eliminar.
Miembros
Sección titulada «Miembros»Cada espacio de trabajo tiene un límite de miembros que cuenta a todos los miembros, incluido el propietario; es un derecho del propietario del espacio de trabajo (plan por defecto: 5).
GET /api/workspaces/{workspaceId}/members[ { "userId": "019f…", "firstName": "Greta", "lastName": "Lengl", "avatarUrl": "/api/avatars/019f…?v=3", "role": "OWNER" }]Los nuevos miembros se añaden exclusivamente mediante invitaciones por correo electrónico.
Cambiar el rol de un miembro
Sección titulada «Cambiar el rol de un miembro»PUT /api/workspaces/{workspaceId}/members/{memberId}{ "role": "ADMIN" }Devuelve 204. Roles: ADMIN o MEMBER — la propiedad no es transferible
mediante este endpoint.
Quitar a un miembro
Sección titulada «Quitar a un miembro»DELETE /api/workspaces/{workspaceId}/members/{memberId}Devuelve 204. Los propietarios no pueden ser eliminados.
Abandonar un espacio de trabajo
Sección titulada «Abandonar un espacio de trabajo»POST /api/workspaces/{workspaceId}/leaveDevuelve 204. Abandona un espacio de trabajo compartido al que te uniste: las
tareas que creaste se reasignan a un «Usuario inactivo» reservado y tus
asignaciones se borran. El propietario no puede abandonarlo (400) — transfiere
antes la propiedad. Quienes no son miembros obtienen 404.
Transferir la propiedad
Sección titulada «Transferir la propiedad»POST /api/workspaces/{workspaceId}/transfer-ownership{ "newOwnerId": "019f…" }Solo el propietario. Devuelve 204: quien la recibe se convierte en propietario
y quien llama sigue como administrador; los límites de almacenamiento y de
miembros del espacio de trabajo siguen el plan del nuevo propietario desde ese
momento. Errores: 404 cuando el destinatario no es miembro, 400 para un
espacio de trabajo personal o una transferencia a ti mismo, 403 cuando el
destinatario alcanzó su límite de espacios de trabajo compartidos en propiedad,
409 cuando el destinatario ya posee un espacio de trabajo con el mismo nombre.
Invitaciones
Sección titulada «Invitaciones»Las invitaciones son personales: cada una está vinculada a una única dirección de correo electrónico, es válida durante 7 días y de un solo uso. Las invitaciones caducadas también se eliminan mediante una tarea de limpieza diaria.
Enviar invitaciones
Sección titulada «Enviar invitaciones»POST /api/workspaces/{workspaceId}/invites{ "emails": ["person@example.com", "other@example.com"] }Solo propietario/administrador, solo espacios de trabajo compartidos, como
máximo 20 direcciones por petición. Cada dirección invitada con éxito
recibe un correo con un enlace de invitación personal (token tdminv_…).
Volver a invitar a una dirección emite un enlace nuevo y anula el anterior.
La respuesta informa sobre cada dirección:
{ "results": [ { "email": "person@example.com", "outcome": "INVITED" }, { "email": "other@example.com", "outcome": "ALREADY_MEMBER" } ]}Resultados: INVITED, ALREADY_MEMBER, INVALID_ADDRESS. Errores: 400
para un lote vacío o demasiado grande, 403 para miembros sin más privilegios
o cuando el espacio de trabajo ya alcanzó su límite de miembros, 404 para
quienes no son miembros.
Previsualizar una invitación
Sección titulada «Previsualizar una invitación»GET /api/workspaces/invites/{token}Requiere autenticación, y la invitación debe estar dirigida al correo de la cuenta con la sesión iniciada. Devuelve quién te invitó:
{ "workspaceName": "Lengl Family", "personal": false, "ownerFirstName": "Greta", "ownerLastName": "Lengl", "ownerAvatarUrl": null}Los tokens desconocidos, caducados y ajenos son indistinguibles: todos 404.
Aceptar una invitación
Sección titulada «Aceptar una invitación»POST /api/workspaces/join{ "token": "tdminv_…" }{ "workspaceId": "019f…", "newlyJoined": true }newlyJoined es false cuando ya eras miembro.
Se aplica la misma regla personal: el token solo funciona para la cuenta con
la dirección de correo invitada, y se consume al tener éxito. Los tokens
desconocidos, caducados y ajenos devuelven todos 404. Devuelve 403 cuando
el espacio de trabajo alcanzó su límite de miembros — la invitación sobrevive
y se puede reintentar mientras sea válida.
Sincronización delta
Sección titulada «Sincronización delta»GET /api/workspaces/{workspaceId}/sync?since={cursor}Recupera todo lo que cambió después del cursor del cliente, para clientes
con capacidad offline: las entidades modificadas como objetos completos en
su estado actual, las eliminaciones como listas de ids y el siguiente
cursor. since=0 devuelve el espacio de trabajo completo (el espejo
inicial). Aplicar un lote es un upsert idempotente, así que repetir
consultas o solaparlas es inofensivo.
{ "cursor": 812, "tasks": [ { "id": "019f…", "title": "…", "subtasks": [], "attachments": [] } ], "deletedTaskIds": ["019f…"], "lists": [], "deletedListIds": [], "members": [], "deletedMemberIds": []}- Los objetos de tarea tienen la misma forma que
GET /api/workspaces/{id}/tasks; los cambios de subtareas y archivos adjuntos aparecen como cambios de su tarea padre. - Cuando se elimina una lista, sus tareas no se reenvían: los clientes
limpian ese
listIdlocalmente, igual que hace el servidor. - Los cambios con menos de un segundo de antigüedad ya se incluyen en el lote, pero el cursor se detiene antes de ellos — la siguiente consulta los entrega de nuevo, y el upsert idempotente absorbe la repetición. Un cliente que consulta justo después de su propia escritura siempre la ve.
Eventos de cambio (SSE)
Sección titulada «Eventos de cambio (SSE)»GET /api/workspaces/{workspaceId}/eventsUn flujo de server-sent events que avisa cuando el contenido del espacio de trabajo cambió — un timbre, no un feed de datos: vuelve a consultar lo que necesites cuando se dispare.
