
# API zadań

Zadania to czynności do wykonania i działania następcze przypisane do Twojego konta — opcjonalnie powiązane z kontaktem, transakcją lub kampanią. Przechodzą one przez **etapy** Twojej tablicy zadań (kolumny kanban) i mają określony **typ** oraz **priorytet**. Ten przewodnik opisuje zarządzanie nimi za pomocą API.

- **Podstawowy adres URL** — `https://api.youraiconnector.com/v1`
- **Uwierzytelnianie** — Twój klucz API (zobacz [Uwierzytelnianie](authentication.md))
- **Błędy i stronicowanie** — zobacz [Błędy i stronicowanie](errors-and-pagination.md)

Wszystkie poniższe przykłady pokazują formularz zapytania `?apiKey=` w cURL oraz nagłówek `X-API-Key` w JavaScript i Pythonie — oba działają w każdym punkcie końcowym.

---

## Obiekt zadania

```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` lub skonfigurowane typy zadań (zobacz [Lista typów zadań](#list-task-types)).
- **`priority`** — `none`, `low`, `normal`, `high` lub `urgent`.
- **`stage`** — identyfikator etapu na tablicy zadań (zobacz [Lista etapów zadań](#list-task-stages)). W przypadku pominięcia podczas tworzenia, zadanie trafia do pierwszego etapu.
- **`remind_before_minutes`** — liczba minut przed `due_date`, po której ma zostać wysłane przypomnienie. `0` oznacza czas terminu; pomiń lub wyślij `null`, aby zrezygnować z przypomnienia. Musi to być liczba całkowita od `0` do `1440` (1 dzień) — każda większa wartość zostanie odrzucona. Przypomnienie wymaga `due_date`, aby zostało uruchomione, a zmiana terminu zadania powoduje przeniesienie przypomnienia wraz z nim.

---

## Tworzenie zadania

`POST /tasks` — wymagane jest tylko `title`.

::: note
**Uwaga:** `due_date` akceptuje znacznik czasu ISO 8601, w tym godzinę. Połącz go z `remind_before_minutes`, aby przypomnienie zostało dostarczone zgodnie z ustawieniami powiadomień w sekcji **Zadania**. `contact_id`, `deal_id` oraz `campaign_id` łączą zadanie z tymi rekordami. `assigned_to` to identyfikator użytkownika członka zespołu.
:::


> **Poprawne ustawienie `assigned_to`.** Powinien to być identyfikator użytkownika właściciela konta lub aktywnego członka zespołu na tym samym koncie. Ten punkt końcowy obecnie tego nie sprawdza, więc identyfikator nieprzypisany do nikogo jest akceptowany i przechowywany dokładnie w takiej formie, w jakiej został wysłany — nadal otrzymasz `201`. Skopiuj identyfikator zamiast wpisywać go ręcznie: identyfikatory te mieszają `l` z `L` oraz literę `O` z cyfrą `0`, a jeden błędny znak wystarczy, by wystąpił problem. Aby sprawdzić, co faktycznie zostało wysłane, otwórz zadanie w panelu: pole **Osoba przypisana** (Assignee) w rekordzie zadania wyświetla surowy identyfikator, jeśli nie pasuje on do nikogo, a selektor osoby przypisanej w opcji **Edytuj zadanie** pokazuje **Nieprzypisane** (Unassigned).

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

**Odpowiedź** (`201`)

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

---

## Lista zadań

`GET /tasks` — zwraca zadania dla Twojego konta z opcjonalnymi filtrami.

**Parametry zapytania** (wszystkie opcjonalne): `stage`, `priority`, `contact_id`, `deal_id`, `assigned_to`, `due_before`, `due_after` (znaczniki czasu 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"]
```

**Odpowiedź** (`200`)

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

---

## Wyszukiwanie zadań

`POST /tasks/search` — wyszukiwanie pełnotekstowe w tytule i opisie, z tymi samymi opcjonalnymi filtrami co w przypadku listowania.

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

---

## Pobierz zadanie

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

Zadanie, które nie istnieje na Twoim koncie, zwraca `404`.

---

## Zaktualizuj zadanie

`PUT /tasks/{taskId}` — wyślij tylko te pola, które chcesz zmienić (`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."},
)
```

---

## Ukończ zadanie

`POST /tasks/{taskId}/complete` — przenosi zadanie do etapu ukończonych na Twojej tablicy. Opcjonalne pole `notes` zapisuje notatkę końcową.

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

---

## Przenoszenie i zmiana kolejności (kanban)

**Przenieś zadanie do innego etapu** — `POST /tasks/{taskId}/move` z `new_stage_id` (etap docelowy) oraz `new_position` (pozycja liczona od zera w obrębie tego etapu; wymagane, musi być liczbą całkowitą nieujemną):

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

**Zmień kolejność zadań w obrębie etapu** — `POST /tasks/reorder` z `stage_id` oraz identyfikatorami zadań w nowej kolejności:

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

---

## Zadania dla kontaktu

`GET /tasks/contact/{contactId}` — każde zadanie powiązane z jednym kontaktem.

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

---

## Konfiguracja tablicy zadań

### Wyświetl etapy zadań

`GET /tasks/stages` — kolumny Twojej tablicy w kolejności. Użyj etapu `id` jako pola `stage` podczas tworzenia lub przenoszenia zadań.

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

### Aktualizacja etapów zadań

`PUT /tasks/stages` — zastąp konfigurację etapów swojej tablicy. Wyślij pełną, uporządkowaną tablicę `stages`.

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

### Lista typów zadań

`GET /tasks/types` — typy zadań skonfigurowane na Twoim koncie (używane jako pole `type`).

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

---

## Zatwierdzanie sugestii FAQ

Gdy bot AI proponuje nowe FAQ, tworzy zadanie typu `faq_update`. `POST /tasks/{taskId}/approve-faq` zmienia tę sugestię w rzeczywiste FAQ w bazie wiedzy agenta AI, który je zgłosił, i kończy zadanie. Możesz nadpisać pytanie/odpowiedź w treści.

Dodaj `"send_follow_up": true`, aby AI wysłało również odpowiedź do powiązanego kontaktu w zadaniu natychmiast, jako naturalną wiadomość w tym czacie (to samo, co robi przełącznik **Wyślij odpowiedź do kontaktu teraz** w aplikacji). Odpowiedź jest wysyłana przez agenta AI, który obsługuje dany 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` informuje, co stało się z wiadomością: `not_requested` (flaga nieustawiona), `published` (wysłano), `queued` (bot był w trakcie odpowiadania na wiadomość do tego kontaktu, odpowiedź zostanie wysłana, gdy tylko skończy), `skipped_no_contact` (zadanie nie ma powiązanego kontaktu), `skipped_no_campaign` (żaden agent ani kampania nie mogły odpowiedzieć w imieniu tego kontaktu) lub `skipped_error`. FAQ jest tworzone w każdym przypadku.

Zobacz [API FAQ](faqs.md), aby zarządzać utworzonym FAQ.

---

## Usuwanie zadania

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

---

## Następne kroki

- [API kontaktów](contacts.md) — powiąż zadania z odpowiednim kontaktem
- [API Webhooków](webhooks.md) — otrzymuj powiadomienia o `Task Created`, `Task Updated` oraz `Task Completed`
- [Dokumentacja API](reference.md) — pełny interaktywny eksplorator punktów końcowych
