Base URL: http://localhost:3000/api (development)
Método de Autenticación: Session-based (cookies)
Framework: Nitro (Nuxt Server)
Validación: Zod (tipos TypeScript)
- Crear Workspace
- Obtener Workspace
- Actualizar Workspace
- Eliminar Workspace
- Renombrar Workspace
- Archivar Workspace
- Reordenar Workspaces
- Obtener Workspaces del Usuario
- Listar Usuarios en Workspace
- Cambiar Permisos de Usuario
- Eliminar Usuario del Workspace
- Eliminar todos los Quicklinks del Workspace
- Eliminar todas las Tareas del Workspace
✅ Tareas
- Crear Tarea
- Obtener Mis Tareas
- Obtener Tareas del Workspace
- Actualizar Tarea
- Eliminar Tarea
- Eliminar Tareas en Lote
- Reordenar Tareas
- Obtener Tareas de una Sección
- Vincular Quicklink a Tarea
- Obtener Quicklinks de una Tarea
- Desvinicular Quicklink de Tarea
- Crear Sección de Tareas
- Obtener Secciones de Tareas
- Actualizar Sección de Tareas
- Renombrar Sección de Tareas
- Eliminar Sección de Tareas
- Reordenar Secciones de Tareas
- Crear Quicklink
- Obtener Quicklinks del Workspace
- Actualizar Quicklink
- Eliminar Quicklink
- Eliminar Quicklinks en Lote
- Reordenar Quicklinks
- Obtener Favicon
- Obtener Meta de URL
- Crear Sección de Quicklinks
- Obtener Secciones de Quicklinks
- Actualizar Sección de Quicklinks
- Renombrar Sección de Quicklinks
- Eliminar Sección de Quicklinks
- Reordenar Secciones de Quicklinks
- Obtener Quicklinks de una Sección
👤 Usuarios
ℹ️ Información
POST /auth/login
Descripción: Autentica un usuario y crea una sesión
Autenticación: No requerida
Body:
{
"email": "user@example.com",
"password": "password123"
}Respuesta Exitosa (200):
{
"user": {
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"color": "#FF5733"
},
"loggedInAt": "2024-01-06T10:30:00.000Z"
}Errores:
400: Missing required fields401: Invalid credentials
Código Ejemplo:
const login = async (email: string, password: string) => {
return await $fetch('/api/auth/login', {
method: 'POST',
body: { email, password }
})
}POST /auth/signup
Descripción: Registra un nuevo usuario y lo autentica
Autenticación: No requerida
Body:
{
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"password": "password123"
}Respuesta Exitosa (200):
{
"user": {
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"color": null
}
}Errores:
400: Missing required fields409: Email already exists
Código Ejemplo:
const signup = async (firstName: string, lastName: string, email: string, password: string) => {
return await $fetch('/api/auth/signup', {
method: 'POST',
body: { firstName, lastName, email, password }
})
}POST /auth/logout
Descripción: Cierra la sesión del usuario
Autenticación: Requerida
Body: Vacío
Respuesta Exitosa (200):
{
"status": "ok"
}Errores:
401: Unauthorized500: Could not log out
Código Ejemplo:
const logout = async () => {
return await $fetch('/api/auth/logout', { method: 'POST' })
}GET /auth/session
Descripción: Obtiene la sesión actual del usuario
Autenticación: Requerida
Respuesta Exitosa (200):
{
"user": {
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "user@example.com",
"color": "#FF5733"
},
"loggedInAt": "2024-01-06T10:30:00.000Z"
}Errores:
401: Unauthorized
Código Ejemplo:
const getSession = async () => {
return await $fetch('/api/auth/session')
}POST /workspaces
Descripción: Crea un nuevo workspace
Autenticación: Requerida
Body:
{
"name": "Mi Workspace",
"ownerId": 1,
"color": "oklch(52.61% 0.201 25.13)"
}Respuesta Exitosa (200):
{
"id": 1,
"name": "Mi Workspace",
"ownerId": 1,
"color": "oklch(52.61% 0.201 25.13)",
"description": null,
"createdAt": "2024-01-06T10:30:00.000Z",
"updatedAt": "2024-01-06T10:30:00.000Z",
"isDeleted": false
}Errores:
400: Workspace name is required500: Failed to insert workspace
Notas:
- Crea automáticamente relación user_workspace con permiso "owner"
- Asigna orden automáticamente
GET /workspaces/:workspaceId
Descripción: Obtiene los detalles de un workspace
Autenticación: Requerida (debe tener acceso)
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
{
"id": 1,
"name": "Mi Workspace",
"ownerId": 1,
"color": "oklch(52.61% 0.201 25.13)",
"description": "Descripción del workspace",
"createdAt": "2024-01-06T10:30:00.000Z",
"updatedAt": "2024-01-06T10:30:00.000Z",
"isDeleted": false
}Errores:
403: Forbidden (sin acceso)404: Workspace not found
PUT /workspaces/:workspaceId
Descripción: Actualiza los detalles del workspace
Autenticación: Requerida (solo owner/admin)
Parámetros:
workspaceId(number) - ID del workspace
Body:
{
"name": "Nuevo Nombre",
"description": "Nueva descripción",
"color": "#FF5733"
}Respuesta Exitosa (200):
{
"id": 1,
"name": "Nuevo Nombre",
"description": "Nueva descripción",
"color": "#FF5733",
...
}Errores:
400: Missing required fields403: Forbidden404: Workspace not found
DELETE /workspaces/:workspaceId
Descripción: Elimina (soft delete) un workspace
Autenticación: Requerida (solo owner)
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
{
"success": true
}Errores:
403: Forbidden (no es owner)404: Workspace not found
PATCH /workspaces/rename
Descripción: Renombra un workspace
Autenticación: Requerida
Body:
{
"id": 1,
"name": "Nuevo Nombre"
}Respuesta Exitosa (200):
{
"success": true
}Errores:
400: ID and name are required500: Failed to rename workspace
PATCH /workspaces/archive
Descripción: Archiva un workspace
Autenticación: Requerida
Body:
{
"id": 1,
"isArchived": true
}Respuesta Exitosa (200):
{
"success": true
}PATCH /workspaces/reorder
Descripción: Cambia el orden de los workspaces
Autenticación: Requerida
Body:
{
"workspaceId": 1,
"newOrder": 2
}Respuesta Exitosa (200):
{
"success": true
}GET /workspaces/user/:userId
Descripción: Obtiene todos los workspaces de un usuario
Autenticación: Requerida
Parámetros:
userId(number) - ID del usuario
Respuesta Exitosa (200):
[
{
"id": 1,
"name": "Workspace 1",
"ownerId": 1,
"color": "#FF5733",
...
},
{
"id": 2,
"name": "Workspace 2",
"ownerId": 2,
...
}
]GET /workspaces/:workspaceId/users
Descripción: Lista todos los usuarios en un workspace
Autenticación: Requerida (debe tener acceso)
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
[
{
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"color": "#FF5733",
"permission": "owner"
},
{
"id": 2,
"firstName": "Jane",
"lastName": "Smith",
"email": "jane@example.com",
"color": "#33FF57",
"permission": "member"
}
]PUT /workspaces/:workspaceId/users/permission
Descripción: Cambia los permisos de un usuario en el workspace
Autenticación: Requerida (solo owner)
Parámetros:
workspaceId(number) - ID del workspace
Body:
{
"userId": 2,
"permission": "admin"
}Permisos válidos: owner, admin, member
Respuesta Exitosa (200):
{
"success": true
}Errores:
403: Forbidden (no es owner)400: Invalid permission
DELETE /workspaces/:workspaceId/users
Descripción: Elimina un usuario del workspace
Autenticación: Requerida
Parámetros:
workspaceId(number) - ID del workspace
Query:
userId(number) - ID del usuario a eliminar
Respuesta Exitosa (200):
{
"success": true
}Errores:
403: Forbidden404: User not in workspace
DELETE /workspaces/:workspaceId/quicklinks
Descripción: Soft-delete todos los quicklinks en un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
{
"success": true
}DELETE /workspaces/:workspaceId/tasks
Descripción: Soft-delete todas las tareas en un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
{
"success": true
}POST /workspaces/invitations
Descripción: Envía una invitación a un usuario para unirse al workspace
Autenticación: Requerida (solo owner/admin)
Body:
{
"workspaceId": 1,
"email": "newuser@example.com"
}Respuesta Exitosa (200):
{
"success": true,
"token": "inv_abc123def456"
}Errores:
400: Email is required403: Forbidden409: User already invited
GET /workspaces/invitations/:workspaceId
Descripción: Lista las invitaciones pendientes en un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
[
{
"id": 1,
"workspaceId": 1,
"email": "invited@example.com",
"token": "inv_abc123",
"status": "pending",
"expiresAt": "2024-01-13T10:30:00.000Z",
"createdAt": "2024-01-06T10:30:00.000Z"
}
]POST /workspaces/invitations/join
Descripción: Acepta una invitación y se une al workspace
Autenticación: No requerida (usa token)
Body:
{
"token": "inv_abc123def456"
}Respuesta Exitosa (200):
{
"success": true,
"workspaceId": 1,
"workspace": {
"id": 1,
"name": "Workspace Name",
...
}
}Errores:
400: Token is required401: Invalid or expired token409: User already member
DELETE /workspaces/invitations
Descripción: Rechaza una invitación
Autenticación: No requerida (usa token)
Query:
token(string) - Token de invitación
Respuesta Exitosa (200):
{
"success": true
}POST /tasks
Descripción: Crea una nueva tarea
Autenticación: Requerida
Body:
{
"name": "Mi Tarea",
"description": "Descripción de la tarea",
"workspaceId": 1,
"taskSectionId": 5,
"userId": 1,
"deadlineDate": "2024-01-15T00:00:00Z",
"estimatedTime": 25,
"isDone": false,
"order": 0
}Respuesta Exitosa (200):
{
"id": 1,
"name": "Mi Tarea",
"description": "Descripción de la tarea",
"workspaceId": 1,
"taskSectionId": 5,
"userId": 1,
"deadlineDate": "2024-01-15T00:00:00Z",
"estimatedTime": 25,
"isDone": false,
"order": 0,
"createdAt": "2024-01-06T10:30:00.000Z",
"updatedAt": "2024-01-06T10:30:00.000Z",
"isDeleted": false
}Errores:
400: Name is required / workspaceId is required403: Forbidden (sin acceso al workspace)
GET /tasks
Descripción: Obtiene todas las tareas del usuario autenticado
Autenticación: Requerida
Query (opcional):
isDone(boolean) - Filtrar por completadas
Respuesta Exitosa (200):
[
{
"id": 1,
"name": "Mi Tarea",
"description": "Descripción",
"workspaceId": 1,
"taskSectionId": 5,
"userId": 1,
"deadlineDate": "2024-01-15T00:00:00Z",
"estimatedTime": 25,
"isDone": false,
"workspaceName": "Workspace 1",
...
}
]Notas:
- Retorna solo tareas no eliminadas
- Ordena por isDone y luego por orden
GET /workspaces/:workspaceId/tasks
Descripción: Obtiene todas las tareas de un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number) - ID del workspace
Respuesta Exitosa (200):
[
{
"id": 1,
"name": "Tarea 1",
"workspaceId": 1,
"taskSectionId": 5,
...
}
]PUT /tasks
Descripción: Actualiza una tarea existente
Autenticación: Requerida
Body:
{
"id": 1,
"name": "Nombre actualizado",
"description": "Nueva descripción",
"isDone": true,
"deadlineDate": "2024-01-20T00:00:00Z",
"estimatedTime": 30
}Respuesta Exitosa (200):
{
"id": 1,
"name": "Nombre actualizado",
...
}Errores:
400: ID is required404: Task not found
DELETE /tasks
Descripción: Soft-delete una tarea
Autenticación: Requerida
Query:
id(number) - ID de la tarea
Respuesta Exitosa (200):
{
"success": true
}DELETE /tasks/batch
Descripción: Soft-delete múltiples tareas
Autenticación: Requerida
Body:
{
"ids": [1, 2, 3]
}Respuesta Exitosa (200):
{
"success": true,
"deletedCount": 3
}PATCH /tasks/reorder
Descripción: Cambia el orden de las tareas
Autenticación: Requerida
Body:
{
"taskId": 1,
"newSectionId": 5,
"newIndex": 2
}Respuesta Exitosa (200):
{
"success": true
}GET /workspaces/:workspaceId/task-sections/:sectionId/tasks
Descripción: Obtiene todas las tareas en una sección
Autenticación: Requerida
Parámetros:
workspaceId(number)sectionId(number)
Respuesta Exitosa (200):
[
{
"id": 1,
"name": "Tarea en Sección",
"taskSectionId": 5,
...
}
]POST /tasks/:taskId/quicklinks
Descripción: Vincula un quicklink existente a una tarea
Autenticación: Requerida
Parámetros:
taskId(number)
Body:
{
"quicklinkId": 3,
"workspaceId": 1
}Respuesta Exitosa (200):
{
"success": true
}Errores:
400: quicklinkId is required404: Task not found400: Invalid quicklink (not in same workspace)
GET /tasks/:taskId/quicklinks
Descripción: Obtiene todos los quicklinks vinculados a una tarea
Autenticación: Requerida
Parámetros:
taskId(number)
Respuesta Exitosa (200):
[
{
"id": 3,
"name": "Google",
"url": "https://google.com",
"faviconUrl": "https://google.com/favicon.ico",
"workspaceId": 1,
"quicklinkSectionId": null
}
]DELETE /tasks/:taskId/quicklinks/:quicklinkId
Descripción: Desvincula un quicklink de una tarea
Autenticación: Requerida
Parámetros:
taskId(number)quicklinkId(number)
Respuesta Exitosa (200):
{
"success": true
}POST /task-sections
Descripción: Crea una nueva sección de tareas
Autenticación: Requerida
Body:
{
"name": "Mi Sección",
"workspaceId": 1,
"order": 0
}Respuesta Exitosa (200):
{
"id": 5,
"name": "Mi Sección",
"workspaceId": 1,
"order": 0,
...
}GET /workspaces/:workspaceId/task-sections
Descripción: Obtiene todas las secciones de tareas en un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number)
Respuesta Exitosa (200):
[
{
"id": 5,
"name": "Sección 1",
"workspaceId": 1,
"order": 0,
...
},
{
"id": 6,
"name": "Sección 2",
"workspaceId": 1,
"order": 1,
...
}
]PUT /task-sections
Descripción: Actualiza una sección de tareas
Autenticación: Requerida
Body:
{
"id": 5,
"name": "Nombre Actualizado",
"workspaceId": 1
}Respuesta Exitosa (200):
{
"id": 5,
"name": "Nombre Actualizado",
...
}PATCH /task-sections/rename
Descripción: Renombra una sección de tareas
Autenticación: Requerida
Body:
{
"id": 5,
"name": "Nuevo Nombre"
}Respuesta Exitosa (200):
{
"success": true
}DELETE /task-sections
Descripción: Soft-delete una sección de tareas
Autenticación: Requerida
Query:
id(number) - ID de la sección
Respuesta Exitosa (200):
{
"success": true
}PATCH /task-sections/reorder
Descripción: Cambia el orden de las secciones
Autenticación: Requerida
Body:
{
"sectionId": 5,
"newOrder": 2
}Respuesta Exitosa (200):
{
"success": true
}POST /quicklinks
Descripción: Crea un nuevo quicklink
Autenticación: Requerida
Body:
{
"name": "Google",
"url": "https://google.com",
"faviconUrl": "https://google.com/favicon.ico",
"description": "Search engine",
"workspaceId": 1,
"quicklinkSectionId": 10,
"order": 0
}Respuesta Exitosa (200):
{
"id": 3,
"name": "Google",
"url": "https://google.com",
"faviconUrl": "https://google.com/favicon.ico",
"description": "Search engine",
"workspaceId": 1,
"quicklinkSectionId": 10,
"order": 0,
...
}Errores:
400: Name is required / workspaceId is required
GET /workspaces/:workspaceId/quicklinks
Descripción: Obtiene todos los quicklinks en un workspace
Autenticación: Requerida
Parámetros:
workspaceId(number)
Respuesta Exitosa (200):
[
{
"id": 3,
"name": "Google",
"url": "https://google.com",
...
}
]PUT /quicklinks
Descripción: Actualiza un quicklink
Autenticación: Requerida
Body:
{
"id": 3,
"name": "Google Search",
"url": "https://google.com",
"faviconUrl": "...",
"description": "Updated description"
}Respuesta Exitosa (200):
{
"id": 3,
"name": "Google Search",
...
}DELETE /quicklinks
Descripción: Soft-delete un quicklink
Autenticación: Requerida
Query:
id(number) - ID del quicklink
Respuesta Exitosa (200):
{
"success": true
}DELETE /quicklinks/batch
Descripción: Soft-delete múltiples quicklinks
Autenticación: Requerida
Body:
{
"ids": [3, 4, 5]
}Respuesta Exitosa (200):
{
"success": true,
"deletedCount": 3
}PATCH /quicklinks/reorder
Descripción: Cambia el orden de los quicklinks
Autenticación: Requerida
Body:
{
"quicklinkId": 3,
"newSectionId": 10,
"newIndex": 2
}Respuesta Exitosa (200):
{
"success": true
}GET /quicklinks/favicon
Descripción: Obtiene el favicon de un dominio
Autenticación: No requerida
Query:
domain(string) - Dominio (ej: "google.com")
Respuesta Exitosa (200):
https://google.com/favicon.ico
Nota: Retorna la URL del favicon
GET /quicklinks/meta
Descripción: Obtiene metadatos (título, descripción) de una URL
Autenticación: No requerida
Query:
url(string) - URL completa
Respuesta Exitosa (200):
{
"title": "Google Search",
"description": "The most powerful search engine"
}POST /quicklink-sections
Descripción: Crea una nueva sección de quicklinks
Autenticación: Requerida
Body:
{
"name": "Mi Sección",
"workspaceId": 1,
"order": 0
}Respuesta Exitosa (200):
{
"id": 10,
"name": "Mi Sección",
"workspaceId": 1,
"order": 0,
...
}GET /workspaces/:workspaceId/quicklink-sections
Descripción: Obtiene todas las secciones de quicklinks
Autenticación: Requerida
Parámetros:
workspaceId(number)
Respuesta Exitosa (200):
[
{
"id": 10,
"name": "Sección 1",
"workspaceId": 1,
"order": 0,
...
}
]PUT /quicklink-sections
Descripción: Actualiza una sección de quicklinks
Autenticación: Requerida
Body:
{
"id": 10,
"name": "Nombre Actualizado",
"workspaceId": 1
}Respuesta Exitosa (200):
{
"id": 10,
"name": "Nombre Actualizado",
...
}PATCH /quicklink-sections/rename
Descripción: Renombra una sección de quicklinks
Autenticación: Requerida
Body:
{
"id": 10,
"name": "Nuevo Nombre"
}Respuesta Exitosa (200):
{
"success": true
}DELETE /quicklink-sections
Descripción: Soft-delete una sección de quicklinks
Autenticación: Requerida
Query:
id(number) - ID de la sección
Respuesta Exitosa (200):
{
"success": true
}PATCH /quicklink-sections/reorder
Descripción: Cambia el orden de las secciones
Autenticación: Requerida
Body:
{
"sectionId": 10,
"newOrder": 2
}Respuesta Exitosa (200):
{
"success": true
}GET /workspaces/:workspaceId/quicklink-sections/:sectionId/quicklinks
Descripción: Obtiene todos los quicklinks en una sección
Autenticación: Requerida
Parámetros:
workspaceId(number)sectionId(number)
Respuesta Exitosa (200):
[
{
"id": 3,
"name": "Google",
"url": "https://google.com",
"quicklinkSectionId": 10,
...
}
]GET /users/:id
Descripción: Obtiene información del usuario
Autenticación: Requerida
Parámetros:
id(number) - ID del usuario
Respuesta Exitosa (200):
{
"id": 1,
"firstName": "John",
"lastName": "Doe",
"email": "john@example.com",
"color": "#FF5733",
"createdAt": "2024-01-06T10:30:00.000Z",
...
}PUT /users/:id
Descripción: Actualiza información del usuario
Autenticación: Requerida (solo el usuario)
Parámetros:
id(number)
Body:
{
"firstName": "John Updated",
"lastName": "Doe",
"color": "#33FF57"
}Respuesta Exitosa (200):
{
"id": 1,
"firstName": "John Updated",
...
}Errores:
403: Forbidden (intentando actualizar otro usuario)
PUT /users/:id/change-password
Descripción: Cambia la contraseña del usuario
Autenticación: Requerida
Parámetros:
id(number)
Body:
{
"currentPassword": "old_password",
"newPassword": "new_password"
}Respuesta Exitosa (200):
{
"success": true
}Errores:
400: Current password is incorrect403: Forbidden
GET /version
Descripción: Obtiene la versión de la aplicación
Autenticación: No requerida
Respuesta Exitosa (200):
{
"version": "0.7.5"
}- ✅ Todas las operaciones validan
workspaceId - ✅ Permisos verificados mediante
validateWorkspaceAccess() - ✅ Contraseñas hasheadas con bcrypt
- ✅ Sessions manejadas con cookies HTTP-only
- ✅ Registros no se eliminan, se marcan como
isDeleted: true - ✅ Las queries siempre filtran registros eliminados
- ✅ Permite recuperación de datos
const { data: session } = useAuth()const response = await $fetch('/api/endpoint', {
method: 'POST',
body: { ... }
})try {
await $fetch(...)
} catch (error) {
console.error(error)
setError(error.data?.statusMessage || 'Error')
}Última actualización: 6 de enero de 2026