
# API delle attività

Le attività sono le cose da fare e i follow-up collegati al tuo account, facoltativamente associati a un contatto, una trattativa o una campagna. Si spostano attraverso le **fasi** della tua bacheca delle attività (le tue colonne kanban) e hanno un **tipo** e una **priorità**. Questa guida illustra come gestirle tramite l'API.

- **URL di base** — `https://api.youraiconnector.com/v1`
- **Autenticazione** — la tua chiave API (vedi [Autenticazione](authentication.md))
- **Errori e paginazione** — vedi [Errori e paginazione](errors-and-pagination.md)

Tutti gli esempi seguenti mostrano il formato di query `?apiKey=` in cURL e l'intestazione `X-API-Key` in JavaScript e Python; entrambi funzionano su ogni endpoint.

---

## L'oggetto attività

```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 i tipi di attività configurati (vedi [Elenca tipi di attività](#list-task-types)).
- **`priority`** — `none`, `low`, `normal`, `high` o `urgent`.
- **`stage`** — l'id di una fase sulla tua bacheca attività (vedi [Elenca fasi attività](#list-task-stages)). Se omesso durante la creazione, l'attività viene inserita nella prima fase.
- **`remind_before_minutes`** — quanti minuti prima di `due_date` inviare un promemoria. `0` indica l'orario di scadenza; omettilo o invia `null` per nessun promemoria. Deve essere un numero intero da `0` a `1440` (1 giorno) — qualsiasi valore superiore verrà rifiutato. Il promemoria necessita di un `due_date` per essere attivato e la riprogrammazione dell'attività sposta il promemoria di conseguenza.

---

## Crea un'attività

`POST /tasks` — solo `title` è obbligatorio.

::: note
**Nota:** `due_date` accetta un timestamp ISO 8601, inclusa l'ora del giorno. Abbinalo a `remind_before_minutes` per ricevere il promemoria in base alle impostazioni di notifica delle **Attività**. `contact_id`, `deal_id` e `campaign_id` collegano l'attività a quei record. `assigned_to` è l'id utente di un membro del team.
:::


> **Configurare correttamente `assigned_to`.** Deve essere l'id utente del proprietario dell'account o di un membro attivo del team sullo stesso account. Attualmente questo endpoint non esegue questa verifica, quindi un id che non appartiene a nessuno viene accettato e memorizzato esattamente come inviato: riceverai comunque un `201`. Copia l'id invece di riscriverlo: questi id mescolano `l` con `L` e la lettera `O` con la cifra `0`, e basta un solo carattere errato. Per verificare cosa hai effettivamente inviato, apri l'attività nella dashboard: il campo **Assegnatario** nel record dell'attività mostrerà l'id non elaborato quando non corrisponde a nessuno, e il selettore dell'assegnatario in **Modifica attività** mostrerà **Non assegnato**.

**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"])
```

**Risposta** (`201`)

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

---

## Elenca attività

`GET /tasks` — restituisce le attività per il tuo account, con filtri opzionali.

**Parametri di query** (tutti facoltativi): `stage`, `priority`, `contact_id`, `deal_id`, `assigned_to`, `due_before`, `due_after` (timestamp 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"]
```

**Risposta** (`200`)

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

---

## Ricerca attività

`POST /tasks/search` — corrispondenza full-text su titolo e descrizione, con gli stessi filtri facoltativi dell'elenco.

```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"},
)
```

---

## Ottieni un'attività

`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"})
```

Un'attività che non esiste nel tuo account restituisce `404`.

---

## Aggiorna un'attività

`PUT /tasks/{taskId}` — invia solo i campi che desideri modificare (`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."},
)
```

---

## Completa un'attività

`POST /tasks/{taskId}/complete` — sposta l'attività nella fase di completamento della tua bacheca. Un campo facoltativo `notes` registra una nota di chiusura.

```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."},
)
```

---

## Sposta e riordina (kanban)

**Sposta un'attività in un'altra fase** — `POST /tasks/{taskId}/move` con `new_stage_id` (la fase di destinazione) e `new_position` (la posizione basata su zero all'interno di tale fase; obbligatorio, deve essere un numero intero non 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 }'
```

**Riordina le attività all'interno di una fase** — `POST /tasks/reorder` con `stage_id` e gli ID delle attività nel loro nuovo ordine:

```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"]},
)
```

---

## Attività per un contatto

`GET /tasks/contact/{contactId}` — ogni attività collegata a un contatto.

```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"})
```

---

## Configurazione della bacheca delle attività

### Elenca le fasi delle attività

`GET /tasks/stages` — le colonne della tua bacheca, in ordine. Usa un `id` di fase come campo `stage` durante la creazione o lo spostamento delle attività.

```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 }] }
```

### Aggiorna le fasi delle attività

`PUT /tasks/stages` — sostituisci la configurazione delle fasi della tua bacheca. Invia l'array `stages` completo e ordinato.

```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 }
  ] }'
```

### Elenca i tipi di attività

`GET /tasks/types` — i tipi di attività configurati sul tuo account (usati come campo `type`).

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

---

## Approva un suggerimento per le FAQ

Quando il bot AI propone una nuova FAQ, crea un'attività di tipo `faq_update`. `POST /tasks/{taskId}/approve-faq` trasforma tale suggerimento in una FAQ reale nella knowledge base dell'agente AI che l'ha generata e completa l'attività. È possibile sovrascrivere la domanda/risposta nel corpo del testo.

Aggiungi `"send_follow_up": true` per fare in modo che l'AI invii immediatamente la risposta al contatto collegato all'attività, come un messaggio naturale in quella chat (la stessa operazione eseguita dall'interruttore **Invia subito la risposta al contatto** nell'app). La risposta viene inviata tramite l'agente AI che gestisce quel contatto.

```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` ti indica cosa è successo al messaggio: `not_requested` (flag non impostato), `published` (inviato), `queued` (il bot stava rispondendo a quel contatto, la risposta verrà inviata non appena avrà finito), `skipped_no_contact` (l'attività non ha un contatto collegato), `skipped_no_campaign` (nessun agente o campagna ha potuto rispondere per quel contatto) o `skipped_error`. La FAQ viene creata in ogni caso.

Consulta l'[API delle FAQ](faqs.md) per gestire la FAQ risultante.

---

## Elimina un'attività

`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"})
```

---

## Passaggi successivi

- [API Contatti](contacts.md) — collega le attività al contatto corretto
- [API Webhook](webhooks.md) — ricevi notifiche su `Task Created`, `Task Updated` e `Task Completed`
- [Riferimento API](reference.md) — l'esploratore interattivo completo degli endpoint
