
# API pentru Întrebări frecvente (FAQs)

Întrebările frecvente (FAQs) sunt intrările de tip întrebare-răspuns pe care botul tău AI le folosește atunci când răspunde clienților. Fiecare FAQ aparține contului tău și poate fi asociat uneia sau mai multor campanii, astfel încât același răspuns să poată fi refolosit oriunde este relevant. API-ul pentru FAQs îți permite să gestionezi acea bibliotecă programatic — să creezi, să actualizezi, să imporți în masă, să reordonezi și să asociezi FAQs campaniilor direct din codul tău.

Toate endpoint-urile de mai jos sunt relative la URL-ul de bază `https://api.youraiconnector.com/v1`. Fiecare cerere trebuie să fie autentificată — consultă [Acces API](../integrations/api-access.md) și [Autentificare](authentication.md). Accesul la API este o funcționalitate cu plată; fără acesta, cererile sunt respinse cu un `403`.

> **Cum folosește botul un FAQ:** Când creezi sau modifici un FAQ, platforma pregătește datele de căutare (folosite pentru a potrivi FAQ-ul cu întrebările primite) în fundal. Acest proces durează de obicei câteva secunde, după care botul începe să folosească automat intrarea respectivă.


---

## Obiectul FAQ

Fiecare FAQ returnat de API are următoarea structură:

| Câmp | Tip | Descriere |
|---|---|---|
| `id` | string | Identificatorul unic al întrebării frecvente (FAQ). |
| `question` | string | Întrebarea clientului la care răspunde această intrare. |
| `answer` | string | Răspunsul oferit de botul AI. |
| `category` | string \| null | Etichetă opțională de categorie cu format liber. |
| `tags` | string[] | Etichete opționale pentru organizarea întrebărilor frecvente. |
| `is_active` | boolean | Dacă botul are permisiunea de a utiliza această întrebare frecventă. Valoarea implicită este `true`. |
| `is_global` | boolean | Marchează întrebarea frecventă ca nefiind legată de o campanie sau un Agent specific. Aceasta nu face ca întrebarea frecventă să se aplice peste tot: o întrebare frecventă este utilizată doar de campaniile și Agenții de care este legată. Valoarea implicită este `false`. |
| `usage_count` | integer | De câte ori a fost utilizată această întrebare frecventă în răspunsurile AI. |
| `order_index` | integer | Poziția de afișare a acestei întrebări frecvente în cadrul campaniei sale. |
| `campaign_ids` | string[] | ID-urile campaniilor de care este legată această întrebare frecventă. |
| `created_at` | string \| null | Marcaj temporal ISO 8601 al momentului în care a fost creată întrebarea frecventă. |
| `updated_at` | string \| null | Marcaj temporal ISO 8601 al ultimei modificări. |

Câmpurile pe care le poți **seta** sunt: `question`, `answer`, `is_active`, `is_global`, `category`, `tags` și `order_index`. Platforma gestionează tot restul (datele de căutare, numărul de utilizări, marcajele temporale); orice alte câmpuri din corpul cererii tale sunt ignorate.

---

## Listare FAQs

`GET /faqs`

Returnează FAQs din contul tău, cele mai noi fiind primele. Opțional, poți filtra după o singură campanie sau după starea de activare.

**Parametri de interogare**

| Parametru | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Nu | Returnează doar FAQs asociate acestei campanii. |
| `is_active` | Nu | Returnează doar FAQs cu această stare de activare (`true` sau `false`). Acest filtru este aplicat per pagină, deci o pagină poate conține mai puține elemente decât `limit`. |
| `limit` | Nu | Numărul maxim de FAQs pe pagină. Implicit `50`, maxim `100`. |
| `cursor` | Nu | Un ID de FAQ după care să continui. Transmite valoarea `next_cursor` din pagina anterioară. |

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/faqs?campaign_id=campaign123&limit=50&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs?campaign_id=campaign123&limit=50",
  { headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
console.log(data.faqs, data.next_cursor);
```

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/faqs",
    params={"campaign_id": "campaign123", "limit": 50},
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
print(data["faqs"], data["next_cursor"])
```

**Răspuns**

```json
{
  "success": true,
  "faqs": [
    {
      "id": "aBcD1234eFgH5678",
      "question": "How long does shipping take?",
      "answer": "Standard shipping takes 3-5 business days.",
      "category": "shipping",
      "tags": ["logistics", "delivery"],
      "is_active": true,
      "is_global": false,
      "usage_count": 12,
      "order_index": 0,
      "campaign_ids": ["campaign123"],
      "created_at": "2026-01-01T12:00:00.000Z",
      "updated_at": "2026-01-02T08:30:00.000Z"
    }
  ],
  "next_cursor": "aBcD1234eFgH5678"
}
```

Când `next_cursor` este `null`, nu mai există rezultate.

---

## Obține o întrebare frecventă (FAQ)

`GET /faqs/{faqId}`

Returnează o singură întrebare frecventă (FAQ) după ID-ul acesteia.

**cURL**

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

**JavaScript**

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

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
faq = res.json()["faq"]
```

**Răspuns**

```json
{
  "success": true,
  "faq": {
    "id": "aBcD1234eFgH5678",
    "question": "How long does shipping take?",
    "answer": "Standard shipping takes 3-5 business days.",
    "category": "shipping",
    "tags": ["logistics"],
    "is_active": true,
    "is_global": false,
    "usage_count": 12,
    "order_index": 0,
    "campaign_ids": ["campaign123"],
    "created_at": "2026-01-01T12:00:00.000Z",
    "updated_at": "2026-01-02T08:30:00.000Z"
  }
}
```

---

## Creează o întrebare frecventă (FAQ)

`POST /faqs`

Creează o nouă întrebare frecventă (FAQ) și o conectează la o campanie.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania la care se conectează noua întrebare frecventă. |
| `question` | Da | Întrebarea clientului la care răspunde această intrare. |
| `answer` | Da | Răspunsul pe care botul ar trebui să îl ofere. |
| `is_active` | Nu | Dacă botul poate folosi această întrebare frecventă. Valoarea implicită este `true`. |
| `is_global` | Nu | Dacă întrebarea frecventă se aplică tuturor campaniilor. Valoarea implicită este `false`. |
| `category` | Nu | O etichetă de categorie cu format liber. |
| `tags` | Nu | O matrice de etichete. |
| `order_index` | Nu | Poziția de afișare în cadrul campaniei. Valoarea implicită este `0`. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign123",
    "question": "How long does shipping take?",
    "answer": "Standard shipping takes 3-5 business days.",
    "category": "shipping",
    "tags": ["logistics"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "campaign123",
    question: "How long does shipping take?",
    answer: "Standard shipping takes 3-5 business days.",
    category: "shipping",
    tags: ["logistics"],
  }),
});
const { faq_id } = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign123",
        "question": "How long does shipping take?",
        "answer": "Standard shipping takes 3-5 business days.",
        "category": "shipping",
        "tags": ["logistics"],
    },
)
faq_id = res.json()["faq_id"]
```

**Răspuns**

```json
{
  "success": true,
  "faq_id": "aBcD1234eFgH5678"
}
```

---

## Actualizarea unei întrebări frecvente (FAQ)

`PUT /faqs/{faqId}`

Actualizează parțial o întrebare frecventă. Doar câmpurile editabile furnizate sunt modificate; tot restul își păstrează valoarea curentă. Modificarea `question` sau `answer` reîmprospătează automat datele de căutare ale întrebării frecvente în fundal.

Dacă trimiți `question` sau `answer`, acestea trebuie să fie șiruri de caractere care nu sunt goale. Trimiterea unor câmpuri editabile nerecunoscute returnează un `400`.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "is_active": false }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678",
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ is_active: false }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"is_active": False},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "faq_id": "aBcD1234eFgH5678"
}
```

---

## Ștergerea unei întrebări frecvente (FAQ)

`DELETE /faqs/{faqId}`

Șterge permanent o întrebare frecventă. Opțional, transmite `campaign_id` ca parametru de interogare pentru a elimina, de asemenea, întrebarea frecventă din lista de întrebări frecvente a acelei campanii.

**Parametri de interogare**

| Parametru | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Nu | Elimină, de asemenea, întrebarea frecventă din lista de întrebări frecvente a acestei campanii. |

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678?campaign_id=campaign123&apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678?campaign_id=campaign123",
  { method: "DELETE", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.delete(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678",
    params={"campaign_id": "campaign123"},
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true
}
```

---

## Ștergerea în masă a întrebărilor frecvente

`POST /faqs/bulk-delete`

Șterge până la 500 de întrebări frecvente într-o singură cerere. Când `campaign_id` este furnizat, întrebările frecvente șterse sunt eliminate și din lista de întrebări frecvente a acelei campanii.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `faq_ids` | Da | O matrice nevidă de ID-uri de întrebări frecvente de șters (max 500). |
| `campaign_id` | Nu | Elimină, de asemenea, întrebările frecvente șterse din lista de întrebări frecvente a acestei campanii. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/bulk-delete?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "faq_ids": ["faqId1", "faqId2"], "campaign_id": "campaign123" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/bulk-delete", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    faq_ids: ["faqId1", "faqId2"],
    campaign_id: "campaign123",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/bulk-delete",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"faq_ids": ["faqId1", "faqId2"], "campaign_id": "campaign123"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "deleted_count": 2
}
```

---

## Întrebări frecvente (FAQ) importate

`POST /faqs/import`

Importă în masă până la 500 de întrebări frecvente și le conectează pe toate la o singură campanie. Elementele a căror `question` corespunde unei întrebări frecvente existente în biblioteca ta (fără a ține cont de majuscule/minuscule) **actualizează** acea întrebare frecventă în loc să creeze un duplicat.

> **Sfat de performanță:** Potrivirea duplicatelor scanează întreaga bibliotecă de întrebări frecvente, deci bibliotecile foarte mari încetinesc importurile. Preferă importuri mai puține și mai mari în detrimentul multor importuri mici.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania la care sunt conectate toate întrebările frecvente importate. |
| `faqs` | Da | O matrice nevidă de elemente FAQ (max 500). Fiecare element trebuie să aibă un `question` și un `answer` nevid; poate include, de asemenea, `is_active`, `is_global`, `category`, `tags` și `order_index`. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/import?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign123",
    "faqs": [
      { "question": "Do you ship internationally?", "answer": "Yes, we ship to most countries worldwide." },
      { "question": "What is your return policy?", "answer": "You can return any item within 30 days." }
    ]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/import", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "campaign123",
    faqs: [
      {
        question: "Do you ship internationally?",
        answer: "Yes, we ship to most countries worldwide.",
      },
      {
        question: "What is your return policy?",
        answer: "You can return any item within 30 days.",
      },
    ],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/import",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign123",
        "faqs": [
            {"question": "Do you ship internationally?", "answer": "Yes, we ship to most countries worldwide."},
            {"question": "What is your return policy?", "answer": "You can return any item within 30 days."},
        ],
    },
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "faq_ids": ["aBcD1234eFgH5678", "iJkL9012mNoP3456"],
  "imported_count": 2
}
```

`faq_ids` sunt ID-urile întrebărilor frecvente create sau actualizate, în ordinea în care le-ați furnizat.

---

## Reordonarea întrebărilor frecvente

`POST /faqs/reorder`

Stabilește ordinea de afișare a întrebărilor frecvente dintr-o campanie. Furnizați lista **completă** a ID-urilor FAQ în ordinea dorită; poziția fiecărei întrebări frecvente este actualizată pentru a corespunde locului său în matrice.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania ale cărei întrebări frecvente (FAQ) sunt reordonate. |
| `ordered_faq_ids` | Da | O matrice nevidă cu toate ID-urile FAQ ale campaniei în ordinea de afișare dorită (maxim 500). |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/reorder?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign123",
    "ordered_faq_ids": ["faqId2", "faqId1", "faqId3"]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/reorder", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaign_id: "campaign123",
    ordered_faq_ids: ["faqId2", "faqId1", "faqId3"],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/reorder",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign123",
        "ordered_faq_ids": ["faqId2", "faqId1", "faqId3"],
    },
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true
}
```

Dacă campania sau oricare dintre ID-urile FAQ nu este găsită în contul tău, cererea returnează `404 One or more FAQs were not found`.

---

## Conectează o întrebare frecventă (FAQ) la o campanie

`POST /faqs/{faqId}/link`

Conectează o întrebare frecventă (FAQ) existentă la o campanie suplimentară. O întrebare frecventă poate fi partajată de orice număr de campanii, astfel încât același răspuns trebuie menținut o singură dată.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania la care se conectează întrebarea frecventă (FAQ). |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/link?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "campaign_id": "campaign456" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/link",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ campaign_id: "campaign456" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/link",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"campaign_id": "campaign456"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "faq_id": "aBcD1234eFgH5678",
  "campaign_id": "campaign456"
}
```

---

## Deconectarea unei întrebări frecvente (FAQ) de la o campanie

`POST /faqs/{faqId}/unlink`

Elimină o întrebare frecventă dintr-o campanie fără a șterge întrebarea în sine. Întrebarea frecventă rămâne în biblioteca ta și continuă să fie conectată la orice alte campanii.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania din care se elimină întrebarea frecventă. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/unlink?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "campaign_id": "campaign456" }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/unlink",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({ campaign_id: "campaign456" }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/unlink",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"campaign_id": "campaign456"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "faq_id": "aBcD1234eFgH5678",
  "campaign_id": "campaign456"
}
```

---

## Reconstruirea datelor de căutare ale unei întrebări frecvente

`POST /faqs/{faqId}/rebuild-embeddings`

Pune la coadă o reconstrucție a datelor pe care botul AI le folosește pentru a găsi această întrebare frecventă (datele sale de căutare semantică și prin cuvinte cheie). Acest lucru este util dacă o întrebare frecventă nu este preluată în răspunsuri așa cum era de așteptat. Reconstrucția rulează în fundal și se finalizează de obicei în câteva secunde; întrebarea frecventă poate fi exclusă temporar din răspunsurile AI în timp ce este reconstruită.

Acest endpoint returnează `202 Accepted` deoarece procesul continuă după ce răspunsul este trimis. `status` este întotdeauna `"processing"` — re-interogați întrebarea frecventă mai târziu dacă trebuie să confirmați finalizarea.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/rebuild-embeddings?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/rebuild-embeddings",
  { method: "POST", headers: { "X-API-Key": "YOUR_API_KEY" } }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/rebuild-embeddings",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "faq_id": "aBcD1234eFgH5678",
  "status": "processing"
}
```

---

## Gestionarea FAQ asistată de AI

Endpoint-urile de mai jos depășesc funcționalitățile CRUD simple: ele apelează aceleași instrumente de asistență AI pe care le folosește editorul de FAQ din tabloul de bord — identificarea duplicatelor, generarea de intrări dintr-un document și potrivirea FAQ-urilor cu sarcinile deschise privind lacunele de cunoștințe. Corpurile cererilor din acest set utilizează nume de câmpuri `camelCase` (`campaignId`, `taskId`, `sourceIds`...), care corespund formelor de cerere ale aplicației, în loc de `snake_case` utilizat în altă parte pe această pagină — copiați exemplele de mai jos în loc să ghiciți numele unui câmp.

### Creați o copie a unui FAQ specifică unei campanii

`POST /faqs/{faqId}/fork-for-campaign`

Creează un nou FAQ care este o copie a unuia existent, limitat la o singură campanie, și re-conectează acea campanie la noua copie în loc de cea originală. Utilizați această funcție atunci când doriți să personalizați un răspuns pentru o campanie fără a-l modifica peste tot unde este utilizat FAQ-ul original. FAQ-ul original rămâne pe loc — își pierde doar legătura cu această campanie.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaign_id` | Da | Campania la care se limitează noua copie și de la care se re-conectează FAQ-ul original. |
| `question` | Da | Întrebarea pentru noua copie specifică campaniei. |
| `answer` | Da | Răspunsul pentru noua copie specifică campaniei. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/fork-for-campaign?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaign_id": "campaign456",
    "question": "How long does shipping take to the EU?",
    "answer": "For EU orders, shipping takes 7-10 business days."
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/fork-for-campaign",
  {
    method: "POST",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      campaign_id: "campaign456",
      question: "How long does shipping take to the EU?",
      answer: "For EU orders, shipping takes 7-10 business days.",
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/aBcD1234eFgH5678/fork-for-campaign",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaign_id": "campaign456",
        "question": "How long does shipping take to the EU?",
        "answer": "For EU orders, shipping takes 7-10 business days.",
    },
)
data = res.json()
```

**Răspuns** — `201 Created`

```json
{
  "success": true,
  "faq_id": "nEwFaQiD9012mNoP",
  "campaign_id": "campaign456",
  "original_faq_id": "aBcD1234eFgH5678"
}
```

### Găsirea FAQ-urilor aproape duplicate

`POST /faqs/dedupe`

Pornește o sarcină de fundal care scanează biblioteca dvs. de FAQ pentru intrări aproape duplicate sau care se suprapun și le îmbină sau le elimină acolo unde există certitudine. Util după o importare în masă sau după mai multe runde de FAQ-uri generate de AI care au lăsat biblioteca cu suprapuneri. Doar o singură sarcină de deduplicare poate rula per cont la un moment dat — pornirea unei a doua sarcini în timp ce una este încă în desfășurare returnează `409`.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `sourceIds` | Nu | Matrice de ID-uri sursă ale bazei de cunoștințe pentru a limita deduplicarea. Omiteți pentru a scana întreaga bibliotecă de FAQ. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/dedupe?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{}'
```

**JavaScript**

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

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/dedupe",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={},
)
data = res.json()
```

**Răspuns** — `202 Accepted`

```json
{
  "success": true,
  "job_id": "dedupJob_aBc123"
}
```

Sarcina rulează în fundal și durează de obicei câteva minute pentru o bibliotecă mare. Nu există un endpoint de stare separat — re-interogați [`GET /faqs`](#list-faqs) după o scurtă așteptare pentru a vedea ce s-a schimbat. Când ați terminat de revizuit rezultatul, apelați endpoint-ul de respingere de mai jos pentru a-l șterge.

### Respingerea unui rezultat de verificare a duplicatelor

`POST /faqs/dedupe/dismiss`

Șterge sarcina de deduplicare finalizată, astfel încât să nu mai apară ca rezultat activ. Idempotent — sigur de apelat chiar dacă nu există nimic de respins. Returnează `409` dacă sarcina este încă `queued` sau `processing` (nu puteți respinge o execuție care nu s-a finalizat).

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/dedupe/dismiss?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/dedupe/dismiss", {
  method: "POST",
  headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/dedupe/dismiss",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

```json
{ "success": true }
```

### Generați întrebări frecvente (FAQ) din documentele încărcate

`POST /faqs/generate-from-documents`

Citește unul sau mai multe documente aflate deja în stocarea de fișiere a contului dvs. și pune AI-ul să redacteze întrebări frecvente din conținutul acestora, verificând ciornele față de biblioteca existentă, astfel încât să refolosească sau să actualizeze intrările în loc să creeze duplicate. Rezultatele **nu** sunt scrise imediat — ele sunt stocate ca un set de modificări în așteptare în cadrul campaniei pentru a fi revizuite, apoi aplicate (sau eliminate) cu [Aplică modificările FAQ revizuite](#apply-reviewed-faq-changes) de mai jos. Această acțiune consumă credite, deoarece reprezintă o etapă de generare AI pe baza textului din document.

Acest endpoint nu transportă fișierul: `storagePath` trebuie să indice un fișier aflat deja în propriul folder de încărcări (`users/{your user id}/uploads/`), respectând aceeași convenție ca la [Importă un document încărcat](knowledge-base.md#import-an-uploaded-document) din API-ul Bazei de cunoștințe.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaignId` | Da | Campania pentru care sunt propuse întrebările frecvente generate. |
| `uploadedFiles` | Da | Matrice nevidă de fișiere de citit, fiecare `{ storagePath, fileName, mimeType }`. `storagePath` trebuie să înceapă cu `users/{your user id}/uploads/`. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/generate-from-documents?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "campaign123",
    "uploadedFiles": [
      { "storagePath": "users/abc123uid/uploads/handbook.pdf", "fileName": "handbook.pdf", "mimeType": "application/pdf" }
    ]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/generate-from-documents", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaignId: "campaign123",
    uploadedFiles: [
      { storagePath: "users/abc123uid/uploads/handbook.pdf", fileName: "handbook.pdf", mimeType: "application/pdf" },
    ],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/generate-from-documents",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaignId": "campaign123",
        "uploadedFiles": [
            {"storagePath": "users/abc123uid/uploads/handbook.pdf", "fileName": "handbook.pdf", "mimeType": "application/pdf"},
        ],
    },
)
data = res.json()
```

**Răspuns** — `202 Accepted`

```json
{
  "success": true,
  "faqCount": 6,
  "reusedCount": 2,
  "modifiedCount": 1,
  "newCount": 3
}
```

`faqCount` este numărul total de modificări propuse care așteaptă revizuirea; `reusedCount`, `modifiedCount` și `newCount` descompun acest număr în întrebări frecvente care s-au potrivit cu o intrare existentă fără modificări, cele pe care AI-ul propune să le editeze și cele complet noi. Fișierele încărcate sunt șterse din stocare odată ce procesarea se termină, indiferent dacă aceasta reușește sau nu.

### Aplică modificările FAQ revizuite

`POST /faqs/apply-optimization`

Aplică (sau elimină) un set în așteptare de modificări FAQ propuse de AI — tipul produs de [Generează întrebări frecvente din documente](#generate-faqs-from-uploaded-documents) de mai sus sau de revizuirea optimizării FAQ din tabloul de bord. Alegeți exact ce modificări propuse să acceptați; orice nu menționați rămâne neatins (o modificare omisă nu este niciodată tratată ca o respingere care șterge ceva).

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `campaignId` | Unul dintre cele două | Campania ale cărei modificări FAQ în așteptare sunt aplicate. |
| `agentId` | Unul dintre cele două | Agentul AI ale cărui modificări FAQ în așteptare sunt aplicate, într-un cont nativ de agent. Furnizați exact unul dintre `campaignId` / `agentId`, niciodată ambele. |
| `acceptedChanges` | Da | Matrice a modificărilor pe care le acceptați, fiecare `{ action, faq_id?, faq_ref_path?, question?, answer?, edit_scope? }`. `action` este unul dintre `keep`, `remove`, `add_from_library`, `create_new`, `modify`. Trimiteți o matrice goală pentru a elimina setul în așteptare fără a aplica nimic. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/apply-optimization?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "campaignId": "campaign123",
    "acceptedChanges": [
      { "action": "create_new", "question": "Do you ship to the EU?", "answer": "Yes, EU shipping takes 7-10 business days." },
      { "action": "remove", "faq_ref_path": "users/abc123uid/faqs/oldFaqId" }
    ]
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/apply-optimization", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    campaignId: "campaign123",
    acceptedChanges: [
      { action: "create_new", question: "Do you ship to the EU?", answer: "Yes, EU shipping takes 7-10 business days." },
      { action: "remove", faq_ref_path: "users/abc123uid/faqs/oldFaqId" },
    ],
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/apply-optimization",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "campaignId": "campaign123",
        "acceptedChanges": [
            {"action": "create_new", "question": "Do you ship to the EU?", "answer": "Yes, EU shipping takes 7-10 business days."},
            {"action": "remove", "faq_ref_path": "users/abc123uid/faqs/oldFaqId"},
        ],
    },
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "message": "Applied 2 FAQ changes",
  "faq_count": 7
}
```

`faq_count` este numărul total de întrebări frecvente legate de campanie (sau Agent) după aplicare. Dacă nu a existat niciun set de modificări în așteptare de aplicat, răspunsul este `{ "success": true, "message": "No pending FAQ changes to apply" }`.

### Găsește întrebări frecvente similare cu o sarcină

`POST /faqs/similar-for-task`

Clasifică biblioteca dvs. de întrebări frecvente în funcție de relevanța pentru întrebarea unei sarcini de tip „knowledge-gap” — aceeași căutare din spatele selectorului „Folosește o întrebare frecventă existentă” din tabloul de bord. Doar citire. `taskId` trebuie să indice o sarcină de tip `faq_update`.

Acest endpoint răspunde întotdeauna cu `200`, chiar și în cazul unei erori așteptate, cum ar fi o sarcină necunoscută — verificați `success` în corp în loc de starea HTTP.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `taskId` | Da | Sarcina `faq_update` pentru care se caută potriviri. |
| `limit` | Nu | Numărul maxim de potriviri de returnat. Valoarea implicită este 20, limitată la 50. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/similar-for-task?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "taskId": "task789", "limit": 10 }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/similar-for-task", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ taskId: "task789", limit: 10 }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/similar-for-task",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"taskId": "task789", "limit": 10},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "data": {
    "task_id": "task789",
    "matches": [
      {
        "faq_id": "aBcD1234eFgH5678",
        "question": "How long does shipping take?",
        "answer": "Standard shipping takes 3-5 business days.",
        "category": "shipping",
        "created_at": "2026-01-01T12:00:00.000Z",
        "similarity": 0.81,
        "embedding_similarity": 0.81,
        "keyword_similarity": 0.6,
        "bm25_score": 4.2,
        "distance": 0.19
      }
    ]
  }
}
```

Potrivirile sunt sortate după `similarity` (potrivire semantică atunci când este disponibilă, suprapunere de cuvinte cheie în caz contrar), cele mai bune fiind primele. În cazul unei erori minore, formatul este `{ "success": false, "error": "...", "error_code": 404 }` — `error_code` reflectă ceea ce ar fi fost în mod normal starea HTTP.

### Rezolvarea unei sarcini cu un FAQ existent

`POST /faqs/resolve-task`

Rezolvă o sarcină de tip „lacună de cunoștințe” prin conectarea acesteia la un FAQ pe care îl aveți deja (în loc să scrieți unul nou), trimite răspunsul acelui FAQ către contactul care a declanșat lacuna și marchează sarcina ca finalizată. Utilizați acest lucru după ce [Găsirea FAQ-urilor similare cu o sarcină](#find-faqs-similar-to-a-task) identifică un FAQ existent care acoperă deja întrebarea.

La fel ca endpoint-ul de mai sus, acesta răspunde întotdeauna cu `200` — verificați `success` în corp.

**Câmpuri de solicitare**

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `taskId` | Da | Sarcina `faq_update` de rezolvat. |
| `faqId` | Da | FAQ-ul existent de conectat și trimis ca răspuns. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/faqs/resolve-task?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "taskId": "task789", "faqId": "aBcD1234eFgH5678" }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/faqs/resolve-task", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({ taskId: "task789", faqId: "aBcD1234eFgH5678" }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/faqs/resolve-task",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"taskId": "task789", "faqId": "aBcD1234eFgH5678"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "data": {
    "task_id": "task789",
    "faq_id": "aBcD1234eFgH5678",
    "follow_up_status": "published"
  }
}
```

`follow_up_status` vă spune ce s-a întâmplat cu urmărirea contactului: `published` (trimis imediat), `queued` (AI-ul era deja în mijlocul unui răspuns către acel contact, deci va fi trimis ulterior), `skipped_no_contact` (sarcina nu are niciun contact asociat) sau `skipped_no_campaign` (nu există nicio campanie prin care să fie trimis).

---

## Erori API pentru întrebări frecvente (FAQ)

Endpoint-urile FAQ returnează plicul de eroare standard:

```json
{
  "success": false,
  "error": "FAQ not found"
}
```

| Stare | Când se întâmplă pe un endpoint FAQ |
|---|---|
| `400` | Un câmp obligatoriu lipsește sau este invalid (de exemplu, un `question` gol, un `campaign_id` lipsă sau mai mult de 500 de elemente într-o solicitare în masă). |
| `404` | FAQ-ul sau campania nu a fost găsită — fie nu există, fie aparține unui alt cont. |
| `409` | `POST /faqs/dedupe` a fost apelat în timp ce o sarcină de deduplicare este deja `queued`/`processing`, sau `POST /faqs/dedupe/dismiss` a fost apelat în timp ce sarcina nu s-a finalizat încă. |

Codurile partajate pe care orice endpoint le poate returna — `401`, `403` (planul dvs. nu include acces API), `429` (limită de rată) și `500` — sunt listate cu îndrumări pentru reîncercare în [Erori și Paginare](errors-and-pagination.md).

`POST /faqs/similar-for-task` și `POST /faqs/resolve-task` sunt cele două excepții de pe această pagină: ele răspund cu `200` chiar și pentru o eroare așteptată (sarcină necunoscută, tip de sarcină greșit) și plasează starea reală în `error_code` din corp în schimb — consultați fiecare endpoint de mai sus.

---

## Legate

- [API Campanii](campaigns.md) — campaniile la care sunt legate FAQ-urile dumneavoastră.
- [API Bază de cunoștințe](knowledge-base.md) — importați automat site-uri web și documente în FAQ-uri și grupați FAQ-urile în grupuri de cunoștințe reutilizabile.
- [Acces API](../integrations/api-access.md) — generați cheia API.
- [Autentificare](authentication.md) — toate modalitățile de a transmite cheia dumneavoastră.
