Tareas

El recurso central de la API. Las listas omiten la descripción (payload ligero); el detalle la incluye completa.

El objeto Task

Lo devuelven todos los endpoints de tareas. assignee referencia una pertenencia al proyecto (ver Miembros); dueDate es un día civil de Madrid; parentId apunta a la tarea madre cuando es una subtarea (un solo nivel de anidación).

Objeto Task
{
  "id": "9b2f6c3a-…",
  "projectId": "1f8e4d2b-…",
  "title": "Preparar la demo",
  "status": "in_progress",
  "priority": "high",
  "parentId": null,
  "assignee": { "membershipId": "77a1…", "name": "Marta" },
  "labels": [{ "id": "c4d9…", "name": "demo", "color": "#3b82f6" }],
  "sprint": { "id": "e01b…", "name": "Sprint 12", "status": "active" },
  "dueDate": "2026-08-15",
  "completedAt": null,
  "createdAt": "2026-07-25T09:12:44.000Z",
  "updatedAt": "2026-07-25T10:03:01.000Z",
  "blocked": false
}

Estados

El flujo de trabajo es fijo — los mismos siete estados que ves en la app, en este orden. done y cancelled cuentan como finalizados: por ejemplo, al cerrar un sprint se quedan en él como historial mientras el resto se muda.

  • backlogBacklog

    Ideas y trabajo sin planificar. Es el estado por defecto al crear una tarea.

  • planningPlanificación

    En definición: el alcance o los detalles siguen abiertos.

  • todoPor hacer

    Definida y lista para empezar.

  • in_progressEn curso

    Alguien está trabajando en ella ahora mismo.

  • in_reviewEn revisión

    Terminada a falta de revisión o aprobación.

  • doneHecho

    Completada. Entrar en este estado sella completedAt; salir lo limpia.

  • cancelledCancelada

    Descartada sin completarse. Conserva su historial.

Prioridades

  • urgentUrgente

    Va antes que todo lo demás.

  • highAlta

    Importante a corto plazo.

  • mediumMedia

    El grueso del trabajo planificado.

  • lowBaja

    Cuando haya hueco.

  • noneSin prioridad

    Sin clasificar. Es el valor por defecto.

Listar tareas

GET/api/v1/tasksLectura (cualquier key)

Todas las tareas del proyecto, filtrables y paginadas por cursor. Orden estable: creación descendente.

Parámetros de query

  • statusstring (CSV)

    Filtra por estado(s): backlog, planning, todo, in_progress, in_review, done, cancelled. Ej.: status=todo,in_progress

  • prioritystring (CSV)

    urgent, high, medium, low, none

  • assigneeIdstring

    membershipId del responsable (ver Miembros)

  • sprintIdstring

    Tareas de un sprint

  • labelIdstring

    Tareas con una etiqueta

  • parentIdstring

    Subtareas de una tarea

  • qstring

    Búsqueda por título (sin distinguir mayúsculas)

  • dueAfterYYYY-MM-DD

    Vencimiento ≥ ese día (Madrid, inclusivo). Las tareas sin fecha nunca coinciden

  • dueBeforeYYYY-MM-DD

    Vencimiento ≤ ese día (Madrid, inclusivo)

  • updatedSinceISO 8601

    Solo tareas modificadas desde ese instante — ideal para sincronizaciones incrementales

  • limitinteger

    1–100, por defecto 50

  • cursorstring

    Cursor opaco de la página anterior (nextCursor)

Request
curl "https://planely.dev/api/v1/tasks?status=todo,in_progress&limit=50" \
  -H "Authorization: Bearer $PLANELY_API_KEY"
200 OK
{
  "tasks": [ { "id": "9b2f…", "title": "Preparar la demo",} ],
  "nextCursor": "MTc1MzQ0…",
  "total": 42
}

Crear una tarea

POST/api/v1/tasksPermiso: Crear tareas

Crea una tarea y devuelve el objeto completo.

Cuerpo (JSON)

  • titlestringobligatorio

    1–200 caracteres

  • descriptionstring | null

    Markdown, hasta 10 000 caracteres

  • statusstring

    Por defecto backlog

  • prioritystring

    Por defecto none

  • assigneeIdstring | null

    membershipId del proyecto

  • labelIdsstring[]

    Ids de etiquetas del proyecto

  • parentIdstring | null

    Tarea raíz del proyecto: un solo nivel de subtareas

  • sprintIdstring | null

    Sprint no cerrado del proyecto

  • dueDateYYYY-MM-DD | null

    Día civil de Madrid

  • Los cuerpos son estrictos: un campo desconocido (p. ej. una errata) responde 400 en vez de ignorarse.
  • Ids de otro proyecto (assigneeId, labelIds, sprintId, parentId) responden 404 — sin excepciones.
Request
curl -X POST https://planely.dev/api/v1/tasks \
  -H "Authorization: Bearer $PLANELY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Preparar la demo",
    "priority": "high",
    "dueDate": "2026-08-15"
  }'
201 Created
{ "task": {
    "id": "9b2f6c3a-…",
    "projectId": "1f8e4d2b-…",
    "title": "Preparar la demo",
    "status": "in_progress",
    "priority": "high",
    "parentId": null,
    "assignee": { "membershipId": "77a1…", "name": "Marta" },
    "labels": [{ "id": "c4d9…", "name": "demo", "color": "#3b82f6" }],
    "sprint": { "id": "e01b…", "name": "Sprint 12", "status": "active" },
    "dueDate": "2026-08-15",
    "completedAt": null,
    "createdAt": "2026-07-25T09:12:44.000Z",
    "updatedAt": "2026-07-25T10:03:01.000Z",
    "blocked": false
  } }

Obtener una tarea

GET/api/v1/tasks/{taskId}Lectura (cualquier key)

El detalle completo: incluye la descripción markdown y el objeto dependencies con las dos direcciones del grafo.

Request
curl https://planely.dev/api/v1/tasks/9b2f6c3a-… \
  -H "Authorization: Bearer $PLANELY_API_KEY"
200 OK
{
  "task": {,
    "description": "## Contexto\n…",
    "blocked": true,
    "dependencies": {
      "blockedBy": [
        { "id": "1a2b…", "title": "Diseñar el esquema", "status": "in_progress" }
      ],
      "blocks": [
        { "id": "3c4d…", "title": "Publicar la nota de versión", "status": "todo" }
      ]
    }
  }
}

Actualizar una tarea

PATCH/api/v1/tasks/{taskId}Permiso: Editar tareas

Actualización parcial con el contrato del producto: un campo ausente no se toca; null explícito limpia el campo (donde aplica).

Cuerpo (JSON)

  • titlestring
  • descriptionstring | null
  • statusstring

    Pasar a done sella completedAt; salir de done lo limpia

  • prioritystring
  • assigneeIdstring | null
  • labelIdsstring[]

    Reemplaza el conjunto completo de etiquetas

  • sprintIdstring | null
  • dueDateYYYY-MM-DD | null
  • El cuerpo no puede estar vacío (400).
  • Cada cambio real queda en el historial de la tarea como «nombre-de-la-key (API)».
Request
curl -X PATCH https://planely.dev/api/v1/tasks/9b2f6c3a-… \
  -H "Authorization: Bearer $PLANELY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "status": "done", "dueDate": null }'
200 OK
{ "task": {, "status": "done", "completedAt": "2026-07-25T…" } }

Eliminar una tarea

DELETE/api/v1/tasks/{taskId}Permiso: Eliminar tareas

Manda la tarea a la papelera del proyecto, con sus subtareas. No se destruye nada: desde ahí se puede restaurar o eliminar definitivamente (ver Papelera).

  • Deja de aparecer en GET /tasks y responde 404 en el detalle, pero sigue existiendo: comentarios, adjuntos e historial se conservan intactos.
  • Para destruirla de verdad hace falta una segunda llamada: DELETE /api/v1/trash/{taskId}.
Request
curl -X DELETE https://planely.dev/api/v1/tasks/9b2f6c3a-… \
  -H "Authorization: Bearer $PLANELY_API_KEY"
204 No Content
(sin cuerpo)