
# API de tareas

Las tareas son los pendientes y seguimientos asociados a tu cuenta, vinculados opcionalmente a un contacto, trato o campaña. Se mueven a través de las **etapas** de tu tablero de tareas (tus columnas kanban) y tienen un **tipo** y una **prioridad**. Esta guía cubre cómo gestionarlas a través de la API.

- **URL base** — `https://api.youraiconnector.com/v1`
- **Autenticación** — tu clave de API (consulta [Autenticación](authentication.md))
- **Errores y paginación** — consulta [Errores y paginación](errors-and-pagination.md)

Todos los ejemplos a continuación muestran la forma de consulta `?apiKey=` en cURL y el encabezado `X-API-Key` en JavaScript y Python; cualquiera de los dos funciona en todos los endpoints.

---

## El objeto de tarea

```json
{
  "id": "tsk_abc123",
  "title": "Call Jane about her quote",
  "description": "She asked for pricing on the annual plan.",
  "type": "to_do",
  "priority": "high",
  "stage": "stage-1",
  "due_date": "2026-06-15T09:00:00.000Z",
  "remind_before_minutes": 15,
  "contact": "contacts/uid_whatsapp_15551234567",
  "campaign": "campaigns/abc123",
  "tags": ["sales"],
  "notes": "",
  "source": "api"
}
```

- **`type`** — `to_do`, `faq_update` o sus tipos de tarea configurados (consulte [Listar tipos de tarea](#list-task-types)).
- **`priority`** — `none`, `low`, `normal`, `high` o `urgent`.
- **`stage`** — el id de una etapa en su tablero de tareas (consulte [Listar etapas de tarea](#list-task-stages)). Si se omite al crear, la tarea se coloca en su primera etapa.
- **`remind_before_minutes`** — cuántos minutos antes de `due_date` enviar un recordatorio. `0` significa en la fecha de vencimiento; omítalo o envíe `null` para no recibir recordatorios. Debe ser un número entero de `0` a `1440` (1 día); cualquier valor mayor será rechazado. El recordatorio necesita un `due_date` para activarse, y reprogramar la tarea mueve el recordatorio junto con ella.

---

## Crear una tarea

`POST /tasks` — solo se requiere `title`.

::: note
**Nota:** `due_date` acepta una marca de tiempo ISO 8601, incluida una hora del día. Combínelo con `remind_before_minutes` para que el recordatorio se entregue según su configuración de notificaciones de **Tareas**. `contact_id`, `deal_id` y `campaign_id` vinculan la tarea a esos registros. `assigned_to` es el id de usuario de un miembro del equipo.
:::


> **Configurar `assigned_to` correctamente.** Debe ser el id de usuario del propietario de la cuenta o de un miembro activo del equipo en la misma cuenta. Actualmente, este endpoint no realiza esa comprobación, por lo que se acepta y almacena un id que no pertenece a nadie tal cual lo enviaste; aun así, obtendrás un `201`. Copia el id en lugar de volver a escribirlo: estos ids mezclan `l` con `L` y la letra `O` con el dígito `0`, y basta con un carácter incorrecto. Para comprobar lo que enviaste realmente, abre la tarea en el panel de control: el campo **Asignado a** en el registro de la tarea vuelve a mostrar el id sin procesar cuando no coincide con nadie, y el selector de asignado en **Editar tarea** muestra **Sin asignar**.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Call Jane about her quote",
    "priority": "high",
    "due_date": "2026-06-15T09:00:00.000Z",
    "contact_id": "uid_whatsapp_15551234567",
    "tags": ["sales"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/tasks", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({
    title: "Call Jane about her quote",
    priority: "high",
    due_date: "2026-06-15T09:00:00.000Z",
    contact_id: "uid_whatsapp_15551234567",
    tags: ["sales"],
  }),
});
const data = await res.json();
console.log(data.task_id);
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/tasks",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "title": "Call Jane about her quote",
        "priority": "high",
        "due_date": "2026-06-15T09:00:00.000Z",
        "contact_id": "uid_whatsapp_15551234567",
        "tags": ["sales"],
    },
)
print(res.json()["task_id"])
```

**Respuesta** (`201`)

```json
{ "success": true, "task_id": "tsk_abc123", "task": { "title": "Call Jane about her quote", "...": "..." } }
```

---

## Listar tareas

`GET /tasks` — devuelve las tareas de tu cuenta, con filtros opcionales.

**Parámetros de consulta** (todos opcionales): `stage`, `priority`, `contact_id`, `deal_id`, `assigned_to`, `due_before`, `due_after` (marcas de tiempo ISO).

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/tasks?apiKey=YOUR_API_KEY&stage=stage-1&priority=high"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/tasks?stage=stage-1&priority=high", {
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const { tasks } = await res.json();
```

**Python**

```python
res = requests.get(
    "https://api.youraiconnector.com/v1/tasks",
    headers={"X-API-Key": "YOUR_API_KEY"},
    params={"stage": "stage-1", "priority": "high"},
)
tasks = res.json()["tasks"]
```

**Respuesta** (`200`)

```json
{ "success": true, "tasks": [{ "id": "tsk_abc123", "title": "Call Jane about her quote", "...": "..." }] }
```

---

## Buscar tareas

`POST /tasks/search` — coincidencia de texto completo en el título y la descripción, con los mismos filtros opcionales que el listado.

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks/search?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "query": "quote", "priority": "high" }'
```

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/tasks/search", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ query: "quote", priority: "high" }),
});
```

```python
res = requests.post(
    "https://api.youraiconnector.com/v1/tasks/search",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"query": "quote", "priority": "high"},
)
```

---

## Obtener una tarea

`GET /tasks/{taskId}`

```bash
curl "https://api.youraiconnector.com/v1/tasks/tsk_abc123?apiKey=YOUR_API_KEY"
```

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/tasks/tsk_abc123", { headers: { "X-API-Key": "YOUR_API_KEY" } });
```

```python
res = requests.get("https://api.youraiconnector.com/v1/tasks/tsk_abc123", headers={"X-API-Key": "YOUR_API_KEY"})
```

Una tarea que no existe en su cuenta devuelve `404`.

---

## Actualizar una tarea

`PUT /tasks/{taskId}` — envíe solo los campos que desea cambiar (`title`, `description`, `type`, `priority`, `stage`, `due_date`, `remind_before_minutes`, `contact_id`, `deal_id`, `assigned_to`, `tags`, `notes`).

```bash
curl -X PUT "https://api.youraiconnector.com/v1/tasks/tsk_abc123?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "priority": "urgent", "notes": "Left a voicemail." }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/tasks/tsk_abc123", {
  method: "PUT",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ priority: "urgent", notes: "Left a voicemail." }),
});
```

```python
requests.put(
    "https://api.youraiconnector.com/v1/tasks/tsk_abc123",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"priority": "urgent", "notes": "Left a voicemail."},
)
```

---

## Completar una tarea

`POST /tasks/{taskId}/complete` — mueve la tarea a la etapa de completadas de su tablero. Un campo opcional `notes` registra una nota de cierre.

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks/tsk_abc123/complete?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "notes": "Closed — customer signed up." }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/tasks/tsk_abc123/complete", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ notes: "Closed — customer signed up." }),
});
```

```python
requests.post(
    "https://api.youraiconnector.com/v1/tasks/tsk_abc123/complete",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"notes": "Closed — customer signed up."},
)
```

---

## Mover y reordenar (kanban)

**Mover una tarea a otra etapa** — `POST /tasks/{taskId}/move` con `new_stage_id` (la etapa de destino) y `new_position` (la posición basada en cero dentro de esa etapa; obligatorio, debe ser un número entero no negativo):

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks/tsk_abc123/move?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "new_stage_id": "stage-2", "new_position": 0 }'
```

**Reordenar tareas dentro de una etapa** — `POST /tasks/reorder` con `stage_id` y los identificadores de las tareas en su nuevo orden:

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks/reorder?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "stage_id": "stage-1", "ordered_task_ids": ["tsk_3", "tsk_1", "tsk_2"] }'
```

```javascript
await fetch("https://api.youraiconnector.com/v1/tasks/reorder", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY", "Content-Type": "application/json" },
  body: JSON.stringify({ stage_id: "stage-1", ordered_task_ids: ["tsk_3", "tsk_1", "tsk_2"] }),
});
```

```python
requests.post(
    "https://api.youraiconnector.com/v1/tasks/reorder",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"stage_id": "stage-1", "ordered_task_ids": ["tsk_3", "tsk_1", "tsk_2"]},
)
```

---

## Tareas para un contacto

`GET /tasks/contact/{contactId}` — cada tarea vinculada a un contacto.

```bash
curl "https://api.youraiconnector.com/v1/tasks/contact/uid_whatsapp_15551234567?apiKey=YOUR_API_KEY"
```

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/tasks/contact/uid_whatsapp_15551234567", { headers: { "X-API-Key": "YOUR_API_KEY" } });
```

```python
res = requests.get("https://api.youraiconnector.com/v1/tasks/contact/uid_whatsapp_15551234567", headers={"X-API-Key": "YOUR_API_KEY"})
```

---

## Configuración del tablero de tareas

### Listar etapas de tareas

`GET /tasks/stages` — las columnas de su tablero, en orden. Utilice un `id` de etapa como campo `stage` al crear o mover tareas.

```bash
curl "https://api.youraiconnector.com/v1/tasks/stages?apiKey=YOUR_API_KEY"
```

```json
{ "success": true, "stages": [{ "id": "stage-1", "name": "To Do", "is_completed_stage": false }, { "id": "stage-done", "name": "Done", "is_completed_stage": true }] }
```

### Actualizar etapas de tareas

`PUT /tasks/stages` — reemplace la configuración de etapas de su tablero. Envíe la matriz `stages` ordenada completa.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/tasks/stages?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "stages": [
    { "id": "stage-1", "name": "To Do", "is_completed_stage": false },
    { "id": "stage-2", "name": "In Progress", "is_completed_stage": false },
    { "id": "stage-done", "name": "Done", "is_completed_stage": true }
  ] }'
```

### Listar tipos de tareas

`GET /tasks/types` — los tipos de tareas configurados en su cuenta (utilizados como campo `type`).

```bash
curl "https://api.youraiconnector.com/v1/tasks/types?apiKey=YOUR_API_KEY"
```

---

## Aprobar una sugerencia de preguntas frecuentes

Cuando el bot de IA propone una nueva pregunta frecuente, crea una tarea de tipo `faq_update`. `POST /tasks/{taskId}/approve-faq` convierte esa sugerencia en una pregunta frecuente real en la base de conocimientos del agente de IA que la generó y completa la tarea. Puedes sobrescribir la pregunta/respuesta en el cuerpo.

Añade `"send_follow_up": true` para que la IA también envíe la respuesta al contacto vinculado a la tarea de inmediato, como un mensaje natural en ese chat (lo mismo que hace el interruptor **Enviar la respuesta al contacto ahora** en la aplicación). La respuesta se envía a través del agente de IA que gestiona ese contacto.

```bash
curl -X POST "https://api.youraiconnector.com/v1/tasks/tsk_faq99/approve-faq?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "question": "Do you offer refunds?", "answer": "Yes, within 30 days.", "send_follow_up": true }'
```

```json
{ "success": true, "faq_id": "faq_xyz", "task_id": "tsk_faq99", "follow_up_status": "published" }
```

`follow_up_status` le indica qué sucedió con el mensaje: `not_requested` (indicador no establecido), `published` (enviado), `queued` (el bot estaba respondiendo a ese contacto, la respuesta se envía tan pronto como termine), `skipped_no_contact` (la tarea no tiene un contacto vinculado), `skipped_no_campaign` (ningún agente o campaña pudo responder por ese contacto) o `skipped_error`. La FAQ se crea en todos los casos.

Consulte la [API de preguntas frecuentes](faqs.md) para gestionar la pregunta frecuente resultante.

---

## Eliminar una tarea

`DELETE /tasks/{taskId}`

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/tasks/tsk_abc123?apiKey=YOUR_API_KEY"
```

```javascript
await fetch("https://api.youraiconnector.com/v1/tasks/tsk_abc123", { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } });
```

```python
requests.delete("https://api.youraiconnector.com/v1/tasks/tsk_abc123", headers={"X-API-Key": "YOUR_API_KEY"})
```

---

## Próximos pasos

- [API de contactos](contacts.md) — vincule tareas al contacto correcto
- [API de webhooks](webhooks.md) — reciba notificaciones sobre `Task Created`, `Task Updated` y `Task Completed`
- [Referencia de la API](reference.md) — el explorador interactivo completo de endpoints
