
# Tasks API

Opgaver er de to-dos og opfølgninger, der er knyttet til din konto — eventuelt linket til en kontakt, en aftale eller en kampagne. De bevæger sig gennem **stadierne** på din opgavetavle (dine kanban-kolonner) og har en **type** og **prioritet**. Denne guide dækker håndtering af dem via API'et.

- **Base URL** — `https://api.youraiconnector.com/v1`
- **Autentificering** — din API-nøgle (se [Autentificering](authentication.md))
- **Fejl & paginering** — se [Fejl & Paginering](errors-and-pagination.md)

Alle eksempler herunder viser `?apiKey=` forespørgselsformen i cURL og `X-API-Key` headeren i JavaScript og Python — begge virker på alle slutpunkter.

---

## Opgaveobjektet

```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` eller dine konfigurerede opgavetyper (se [List task types](#list-task-types)).
- **`priority`** — `none`, `low`, `normal`, `high` eller `urgent`.
- **`stage`** — id'et for en fase på din opgavetavle (se [List task stages](#list-task-stages)). Hvis det udelades ved oprettelse, placeres opgaven i din første fase.
- **`remind_before_minutes`** — hvor mange minutter før `due_date` en påmindelse skal sendes. `0` betyder på forfaldstidspunktet; udelad det eller send `null` for ingen påmindelse. Skal være et heltal fra `0` til `1440` (1 dag) — alt derover afvises. Påmindelsen kræver en `due_date` for at blive udløst, og omlægning af opgaven flytter påmindelsen med.

---

## Opret en opgave

`POST /tasks` — kun `title` er påkrævet.

::: note
**Bemærk:** `due_date` accepterer et ISO 8601-tidsstempel, inklusive et tidspunkt på dagen. Kombiner det med `remind_before_minutes` for at få påmindelsen leveret i henhold til dine **Opgave**-notifikationsindstillinger. `contact_id`, `deal_id` og `campaign_id` linker opgaven til disse poster. `assigned_to` er et teammedlems bruger-id.
:::


> **Få `assigned_to` rigtigt.** Det skal være bruger-id'et for kontoejeren eller et aktivt teammedlem på den samme konto. Dette slutpunkt tjekker i øjeblikket ikke dette, så et id, der ikke tilhører nogen, accepteres og gemmes præcis som du sendte det — du får stadig en `201`. Kopiér id'et i stedet for at skrive det manuelt: disse id'er blander `l` med `L` og bogstavet `O` med cifferet `0`, og ét forkert tegn er nok. For at tjekke hvad du faktisk sendte, skal du åbne opgaven i dashboardet: feltet **Ansvarlig** på opgaveposten viser som standard det rå id, når det ikke matcher nogen, og vælgeren for ansvarlig i **Rediger opgave** viser **Ikke tildelt**.

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

**Svar** (`201`)

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

---

## List opgaver

`GET /tasks` — returnerer opgaverne for din konto med valgfrie filtre.

**Forespørgselsparametre** (alle valgfrie): `stage`, `priority`, `contact_id`, `deal_id`, `assigned_to`, `due_before`, `due_after` (ISO-tidsstempler).

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

**Svar** (`200`)

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

---

## Søg efter opgaver

`POST /tasks/search` — fuldtekstsøgning i titel og beskrivelse, med de samme valgfrie filtre som ved listning.

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

---

## Hent en opgave

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

En opgave, der ikke findes på din konto, returnerer `404`.

---

## Opdater en opgave

`PUT /tasks/{taskId}` — send kun de felter, du ønsker at ændre (`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."},
)
```

---

## Fuldfør en opgave

`POST /tasks/{taskId}/complete` — flytter opgaven til din tavles fuldførte stadie. Et valgfrit `notes`-felt gemmer en afsluttende note.

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

---

## Flyt & omorganiser (kanban)

**Flyt en opgave til et andet stadie** — `POST /tasks/{taskId}/move` med `new_stage_id` (destinationsstadiet) og `new_position` (den nul-baserede plads inden for det stadie; påkrævet, skal være et ikke-negativt heltal):

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

**Omorganiser opgaver inden for et stadie** — `POST /tasks/reorder` med `stage_id` og opgave-id'erne i deres nye rækkefølge:

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

---

## Opgaver for en kontakt

`GET /tasks/contact/{contactId}` — hver opgave knyttet til én kontakt.

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

---

## Konfiguration af opgavetavle

### List opgavestadier

`GET /tasks/stages` — din tavles kolonner, i rækkefølge. Brug et stadie `id` som `stage`-feltet, når du opretter eller flytter opgaver.

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

### Opdater opgavestadier

`PUT /tasks/stages` — erstat din tavles stadiekonfiguration. Send hele det sorterede `stages`-array.

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

### List opgavetyper

`GET /tasks/types` — de opgavetyper, der er konfigureret på din konto (bruges som `type`-feltet).

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

---

## Godkend et FAQ-forslag

Når AI-botten foreslår en ny FAQ, opretter den en opgave af typen `faq_update`. `POST /tasks/{taskId}/approve-faq` gør det forslag til en rigtig FAQ i vidensbasen hos den AI-agent, der rejste det, og fuldfører opgaven. Du kan overskrive spørgsmålet/svaret i brødteksten.

Tilføj `"send_follow_up": true` for også at få AI'en til at sende svaret til opgavens tilknyttede kontakt med det samme som en naturlig besked i den chat (det samme som tilvalget **Send svaret til kontakten nu** gør i appen). Svaret sendes via den AI-agent, der håndterer den kontakt.

```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` fortæller dig, hvad der skete med beskeden: `not_requested` (flag ikke sat), `published` (sendt), `queued` (botten var i gang med at svare den kontakt, svaret sendes ud, så snart den er færdig), `skipped_no_contact` (opgaven har ingen tilknyttet kontakt), `skipped_no_campaign` (ingen agent eller kampagne kunne svare for den kontakt) eller `skipped_error`. FAQ'en oprettes i alle tilfælde.

Se [FAQs API](faqs.md) for at administrere den resulterende FAQ.

---

## Slet en opgave

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

---

## Næste skridt

- [Contacts API](contacts.md) — link opgaver til den rette kontaktperson
- [Webhooks API](webhooks.md) — få besked ved `Task Created`, `Task Updated` og `Task Completed`
- [API Reference](reference.md) — den fulde interaktive slutpunkts-explorer
