Ir al contenido

API: Espacios de trabajo

GET /api/workspaces

Devuelve 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"
}
]
  • name es null en los espacios de trabajo personales — los clientes muestran una etiqueta localizada a partir de ownerFirstName.
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.

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.

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.

PUT /api/workspaces/{workspaceId}/members/{memberId}
{ "role": "ADMIN" }

Devuelve 204. Roles: ADMIN o MEMBER — la propiedad no es transferible mediante este endpoint.

DELETE /api/workspaces/{workspaceId}/members/{memberId}

Devuelve 204. Los propietarios no pueden ser eliminados.

POST /api/workspaces/{workspaceId}/leave

Devuelve 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.

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.

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.

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.

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.

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.

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 listId localmente, 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.
GET /api/workspaces/{workspaceId}/events

Un 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.