
# Tehtävien API

Tehtävät ovat tiliisi liitettyjä toimenpiteitä ja seurantoja – ne voidaan valinnaisesti linkittää yhteystietoon, kauppaan tai kampanjaan. Ne liikkuvat tehtävätaulusi **vaiheiden** (kanban-sarakkeiden) läpi, ja niillä on **tyyppi** ja **prioriteetti**. Tämä opas kattaa niiden hallinnan API:n kautta.

- **Perus-URL** — `https://api.youraiconnector.com/v1`
- **Todennus** — API-avaimesi (katso [Todennus](authentication.md))
- **Virheet ja sivutus** — katso [Virheet ja sivutus](errors-and-pagination.md)

Kaikki alla olevat esimerkit näyttävät `?apiKey=`-kyselymuodon cURL-muodossa ja `X-API-Key`-otsikon JavaScriptissä ja Pythonissa – kumpi tahansa toimii jokaisessa päätepisteessä.

---

## Tehtäväobjekti

```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` tai määrittämäsi tehtävätyypit (katso [Listaa tehtävätyypit](#list-task-types)).
- **`priority`** — `none`, `low`, `normal`, `high` tai `urgent`.
- **`stage`** — tehtävätaulusi vaiheen tunniste (katso [Listaa tehtävävaiheet](#list-task-stages)). Jos jätät tämän pois luonnin yhteydessä, tehtävä sijoitetaan ensimmäiseen vaiheeseen.
- **`remind_before_minutes`** — kuinka monta minuuttia ennen `due_date` muistutus lähetetään. `0` tarkoittaa eräpäivän hetkeä; jätä pois tai lähetä `null`, jos et halua muistutusta. Arvon on oltava kokonaisluku väliltä `0` – `1440` (1 päivä) — tätä suuremmat arvot hylätään. Muistutus vaatii `due_date`-toiminnon lauetakseen, ja tehtävän uudelleenajastaminen siirtää muistutusta tehtävän mukana.

---

## Luo tehtävä

`POST /tasks` — vain `title` on pakollinen.

::: note
**Huomautus:** `due_date` hyväksyy ISO 8601 -aikaleiman, joka sisältää kellonajan. Yhdistä se `remind_before_minutes`-kohtaan, jotta muistutus toimitetaan **Tehtävät**-ilmoitusasetustesi mukaisesti. `contact_id`, `deal_id` ja `campaign_id` linkittävät tehtävän kyseisiin tietueisiin. `assigned_to` on tiimin jäsenen käyttäjätunnus.
:::


> **`assigned_to` oikein.** Sen tulee olla tilin omistajan tai saman tilin aktiivisen tiimin jäsenen käyttäjätunnus. Tämä päätepiste ei tällä hetkellä tarkista tätä, joten kenenkään tunnusta ei hyväksytä ja tallennetaan täsmälleen sellaisena kuin lähetit sen — saat silti vastauksen `201`. Kopioi tunnus sen sijaan, että kirjoittaisit sen uudelleen: nämä tunnukset sekoittavat `l` ja `L` sekä kirjaimen `O` ja numeron `0`, ja yksi väärä merkki riittää. Voit tarkistaa, mitä todellisuudessa lähetit, avaamalla tehtävän hallintapaneelista: tehtävätietueen **Vastuuhenkilö**-kenttä näyttää raa'an tunnuksen, jos se ei vastaa ketään, ja **Muokkaa tehtävää** -näkymän vastuuhenkilön valitsin näyttää tilan **Ei vastuuhenkilöä**.

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

**Vastaus** (`201`)

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

---

## Listaa tehtävät

`GET /tasks` — palauttaa tilisi tehtävät valinnaisilla suodattimilla.

**Kyselyparametrit** (kaikki valinnaisia): `stage`, `priority`, `contact_id`, `deal_id`, `assigned_to`, `due_before`, `due_after` (ISO-aikaleimat).

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

**Vastaus** (`200`)

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

---

## Etsi tehtäviä

`POST /tasks/search` — kokotekstihaku otsikosta ja kuvauksesta, samoilla valinnaisilla suodattimilla kuin listauksessa.

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

---

## Hae tehtävä

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

Tehtävä, jota ei ole tililläsi, palauttaa `404`.

---

## Päivitä tehtävä

`PUT /tasks/{taskId}` — lähetä vain ne kentät, joita haluat muuttaa (`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."},
)
```

---

## Merkitse tehtävä valmiiksi

`POST /tasks/{taskId}/complete` — siirtää tehtävän taulusi valmiiden vaiheeseen. Valinnainen `notes`-kenttä tallentaa loppukommentin.

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

---

## Siirrä ja järjestä uudelleen (kanban)

**Siirrä tehtävä toiseen vaiheeseen** — `POST /tasks/{taskId}/move` parametreilla `new_stage_id` (kohdevaihe) ja `new_position` (nollasta alkava paikka kyseisessä vaiheessa; pakollinen, on oltava ei-negatiivinen kokonaisluku):

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

**Järjestä tehtävät uudelleen vaiheen sisällä** — `POST /tasks/reorder` parametreilla `stage_id` ja tehtävien tunnisteet uudessa järjestyksessä:

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

---

## Yhteyshenkilön tehtävät

`GET /tasks/contact/{contactId}` — jokainen tehtävä on linkitetty yhteen yhteyshenkilöön.

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

---

## Tehtävätaulun määritykset

### Listaa tehtävävaiheet

`GET /tasks/stages` — taulusi sarakkeet järjestyksessä. Käytä vaiheen `id` tunnusta `stage`-kenttänä, kun luot tai siirrät tehtäviä.

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

### Päivitä tehtävävaiheet

`PUT /tasks/stages` — korvaa taulusi vaihemääritykset. Lähetä koko järjestetty `stages`-taulukko.

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

### Listaa tehtävätyypit

`GET /tasks/types` — tilillesi määritetyt tehtävätyypit (käytetään `type`-kentässä).

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

---

## Hyväksy FAQ-ehdotus

Kun tekoälybotti ehdottaa uutta FAQ-kysymystä, se luo tyypin `faq_update` tehtävän. `POST /tasks/{taskId}/approve-faq` muuttaa ehdotuksen varsinaiseksi FAQ-kysymykseksi sen tekoälyagentin tietokannassa, joka sen teki, ja merkitsee tehtävän suoritetuksi. Voit muokata kysymystä/vastausta tekstiosassa.

Lisää `"send_follow_up": true`, jotta tekoäly lähettää vastauksen myös suoraan tehtävään linkitetylle yhteyshenkilölle luonnollisena viestinä kyseisessä keskustelussa (sama toiminto kuin sovelluksen **Lähetä vastaus yhteyshenkilölle nyt** -valitsin). Vastaus lähetetään kyseistä yhteyshenkilöä käsittelevän tekoälyagentin kautta.

```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` kertoo, mitä viestille tapahtui: `not_requested` (lippua ei asetettu), `published` (lähetetty), `queued` (botti oli parhaillaan vastaamassa kyseiselle yhteyshenkilölle, vastaus lähetetään heti kun se valmistuu), `skipped_no_contact` (tehtävään ei ole linkitetty yhteyshenkilöä), `skipped_no_campaign` (yksikään agentti tai kampanja ei voinut vastata kyseiselle yhteyshenkilölle) tai `skipped_error`. UKK-kysymys luodaan kaikissa tapauksissa.

Katso [FAQs API](faqs.md) hallinnoidaksesi luotua FAQ-kysymystä.

---

## Poista tehtävä

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

---

## Seuraavat vaiheet

- [Contacts API](contacts.md) — yhdistä tehtävät oikeaan yhteystietoon
- [Webhooks API](webhooks.md) — vastaanota ilmoituksia kohteista `Task Created`, `Task Updated` ja `Task Completed`
- [API-viite](reference.md) — täydellinen interaktiivinen päätepisteiden selain
