
# API-ul Webhooks

Webhooks permit platformei să notifice celelalte sisteme ale tale în momentul în care se întâmplă ceva — un contact nou, un răspuns, o programare efectuată și multe altele. Acest API gestionează **abonamentele** propriu-zise: ce URL-uri primesc ce evenimente. Pentru detalii despre cum să primești și să verifici payload-urile pe care le primește endpoint-ul tău, consultă [Webhooks](../integrations/webhooks.md).

Toate căile de mai jos sunt relative la URL-ul de bază al API-ului:

```
https://api.youraiconnector.com/v1
```

Fiecare cerere trebuie autentificată. Consultați [Autentificare](authentication.md) pentru cele patru metode acceptate. Exemplele de aici utilizează antetul `X-API-Key` (și o formă de parametru de interogare pentru cURL).

::: note
**Notă:** Webhook-urile trebuie să fie activate pentru contul tău. Dacă nu sunt, aceste endpoint-uri returnează un `403`.
:::


---

## Cum sunt adresate abonamentele

Fiecare abonament are un `id` și un `name` opțional. Oricare dintre acestea poate fi utilizat ca `{webhookId}` în cale pentru actualizare, ștergere, testare, stare de sănătate și reactivare.

> **Preferă numele.** ID-urile abonamentelor sunt poziționale, deci se pot schimba după ce un alt abonament este șters. Dacă setezi un `name` stabil atunci când creezi un abonament, adresează-l prin nume pentru a evita surprizele.

---

## Listarea abonamentelor

`GET /webhooks`

**cURL**

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

**JavaScript**

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

**Python**

```python
import requests

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

**Răspuns**

```json
{
  "success": true,
  "webhooks": [
    {
      "id": "0",
      "name": "Order updates hook",
      "url": "https://hooks.example.com/incoming",
      "subscribed_to": ["Contact Created", "Replies"],
      "subscribed_to_tags": [],
      "created_at": "2026-06-09T12:00:00.000Z",
      "signing_enabled": true,
      "signing_secret_created_at": "2026-07-15T09:30:00.000Z",
      "retries_enabled": true,
      "enabled": true,
      "apply_to_sub_accounts": false
    }
  ]
}
```

`signing_enabled` și `retries_enabled` sunt opțiuni activate per abonament, ambele fiind dezactivate implicit până când le activați. Consultați [Payload-uri semnate](#signed-payloads) și [Reîncercări](#retries).

`apply_to_sub_accounts` este opțiunea de moștenire a agenției — consultați [Un abonament pentru toate conturile clienților](#one-subscription-for-all-client-accounts-agencies). Dezactivată implicit și inertă în conturile care nu au conturi de clienți.

`enabled` este comutatorul pornit/oprit al abonamentului — consultați [Dezactivarea unui abonament](#switching-a-subscription-off). Abonamentele dezactivate sunt în continuare listate aici.

Secretul de semnare în sine nu este inclus niciodată aici — citiți-l din [`GET /webhooks/{id}/signing-secret`](#read-the-signing-secret).

---

## Listarea tipurilor de evenimente la care te poți abona

Returnează șirurile exacte pe care le poți utiliza în `subscribed_to`. Folosește acest lucru pentru a descoperi numele valide ale evenimentelor în loc să le introduci hard-coded.

`GET /webhooks/events`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/webhooks/events" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

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

**Python**

```python
import requests

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

**Răspuns**

Răspunsul este `{"success": true, "events": [...]}`, unde `events` conține în prezent 22 de șiruri exacte: Contact Created, Human Alerted, Appointment Booked, Replies, Reads, Deliveries, Credits Spent, Credits Recharged, Low Credit Balance, Contact Paused, Contact Do Not Disturb, Contact Unarchived, New Message, Contact Resumed, Chat Concluded, Task Created, Task Updated, Task Completed, Daily Summary Created, Channel Connected, Broadcast Started și Broadcast Completed (Channel Connected este acceptat în `subscribed_to`, dar nimic nu îl emite în prezent, așa că nu vă bazați pe el).

Pentru semnificația fiecărui eveniment și codul `event` pe care îl trimite în payload, consultați [Cele 22 de evenimente Webhook](../integrations/webhooks.md#the-22-webhook-events). Acest endpoint reprezintă lista autoritară în orice moment — citiți-o în timp real în loc să codați numele în mod fix.

---

## Crearea unui abonament

`POST /webhooks`

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `url` | Da | URL HTTPS care va primi payload-urile evenimentelor prin `POST`. Trebuie să fie accesibil public. |
| `subscribed_to` | Da | O matrice nevidă de nume de evenimente (consultați `/webhooks/events`). |
| `name` | Nu | Un nume de afișare. Poate fi folosit ulterior și ca `{webhookId}`. Implicit este un nume cu marcaj temporal. |
| `subscribed_to_tags` | Nu | ID-uri de etichete care restrâng etichetele ce produc o notificare de rezumat al conversației. Nu limitează evenimentele abonamentului la acele etichete — pentru a primi o solicitare atunci când este aplicată o anumită etichetă, setați un URL webhook pe acea etichetă în fila **Etichete** a agentului (sau campaniei). |
| `retries_enabled` | Nu | Boolean, implicit `false`. Optați pentru [reîncercări](#retries) ale livrărilor eșuate. |
| `generate_signing_secret` | Nu | Boolean, implicit `false`. Generați un [secret de semnare](#signed-payloads) HMAC împreună cu abonamentul. Secretul este returnat o singură dată, ca un `signing_secret` de nivel superior în răspuns. |
| `enabled` | Nu | Boolean, implicit `true`. Treceți `false` pentru a crea abonamentul în stare dezactivată. Consultați [Dezactivarea unui abonament](#switching-a-subscription-off). |
| `apply_to_sub_accounts` | Nu | Boolean, implicit `false`. Într-un cont de agenție, `true` face ca acest abonament să primească și evenimente din fiecare cont de client — consultați [Un abonament pentru toate conturile clienților](#one-subscription-for-all-client-accounts-agencies). |

> **Reguli URL:** URL-ul trebuie să utilizeze `https://` și să fie accesibil public. Adresele `http://` simple, `localhost`, adresele de rețea privată și adresele interne ale platformei sunt respinse cu un `400`.

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "name": "Order updates hook"
  }'
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks", {
  method: "POST",
  headers: {
    "X-API-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    url: "https://hooks.example.com/incoming",
    subscribed_to: ["Contact Created", "Replies"],
    name: "Order updates hook",
  }),
});
const data = await res.json();
```

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/incoming",
        "subscribed_to": ["Contact Created", "Replies"],
        "name": "Order updates hook",
    },
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "1",
  "webhook": {
    "id": "1",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/incoming",
    "subscribed_to": ["Contact Created", "Replies"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

---

## Actualizarea unui abonament

Furnizați cel puțin unul dintre `url`, `subscribed_to`, `name`, `subscribed_to_tags`, `retries_enabled`, `enabled` sau `apply_to_sub_accounts`. Câmpurile omise își păstrează valorile curente. `subscribed_to` și `subscribed_to_tags` sunt înlocuiri, nu îmbinări.

`PUT /webhooks/{webhookId}`

> Actualizarea unui abonament nu afectează niciodată secretul său de semnare — gestionați acest lucru prin [rutele pentru secretul de semnare](#signed-payloads).

> Când URL-ul se modifică, livrarea pentru noul URL este reactivată automat, oferind unui punct final care a eșuat anterior un nou început.

**cURL**

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/Order%20updates%20hook" \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"]
  }'
```

**JavaScript**

```javascript
const res = await fetch(
  `https://api.youraiconnector.com/v1/webhooks/${encodeURIComponent("Order updates hook")}`,
  {
    method: "PUT",
    headers: {
      "X-API-Key": "YOUR_API_KEY",
      "Content-Type": "application/json",
    },
    body: JSON.stringify({
      url: "https://hooks.example.com/v2/incoming",
      subscribed_to: ["Replies", "Chat Concluded"],
    }),
  }
);
const data = await res.json();
```

**Python**

```python
import requests

res = requests.put(
    "https://api.youraiconnector.com/v1/webhooks/Order updates hook",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={
        "url": "https://hooks.example.com/v2/incoming",
        "subscribed_to": ["Replies", "Chat Concluded"],
    },
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0",
  "webhook": {
    "id": "0",
    "name": "Order updates hook",
    "url": "https://hooks.example.com/v2/incoming",
    "subscribed_to": ["Replies", "Chat Concluded"],
    "subscribed_to_tags": [],
    "created_at": "2026-06-09T12:00:00.000Z"
  }
}
```

Un ID sau nume necunoscut returnează `404` cu `{ "success": false, "error": "Webhook not found" }`.

---

## Ștergerea unui abonament

Elimină abonamentul astfel încât URL-ul său să nu mai primească sarcini utile. Contoarele sale de sănătate a livrării sunt resetate, deci re-adăugarea aceluiași URL ulterior începe cu o înregistrare curată.

`DELETE /webhooks/{webhookId}`

**cURL**

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0", {
  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/webhooks/0",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

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

---

## Trimiterea unei sarcini utile de test

Trimite o sarcină utilă (payload) eșantion către URL-ul abonamentului, astfel încât să puteți verifica receptorul capăt-la-capăt. Opțional, transmiteți un `event` pentru a controla ce tip de eveniment simulează eșantionul. Livrările de test nu afectează niciodată contoarele de sănătate ale abonamentului.

`POST /webhooks/{webhookId}/test`

Răspunsul returnează întotdeauna `200` și raportează rezultatul cu un indicator `delivered` — un test eșuat **nu** returnează o stare de eroare. Când `delivered` este `false`, răspunsul include detaliile eșecului.

| Câmp | Obligatoriu | Descriere |
|---|---|---|
| `event` | Nu | Tipul de eveniment de simulat (trebuie să fie unul dintre `/webhooks/events`). Implicit este un eveniment de livrare. |

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/test?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "event": "Contact Created" }'
```

**JavaScript**

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

**Python**

```python
import requests

res = requests.post(
    "https://api.youraiconnector.com/v1/webhooks/0/test",
    headers={"X-API-Key": "YOUR_API_KEY"},
    json={"event": "Contact Created"},
)
data = res.json()
```

**Răspuns** (livrat)

```json
{
  "success": true,
  "webhook_id": "0",
  "delivered": true
}
```

**Răspuns** (eșuat)

```json
{
  "success": true,
  "webhook_id": "0",
  "delivered": false,
  "failure_type": "permanent",
  "status_code": 404,
  "error_message": "Request failed with status code 404"
}
```

`failure_type` este unul dintre `permanent`, `temporary`, `timeout`, `network` sau `unknown`.

---

## Verifică starea livrării

Returnează înregistrarea stării livrării pentru URL-ul abonamentului: câte livrări au reușit și câte au eșuat, dacă livrarea este momentan suspendată după eșecuri repetate și detaliile celui mai recent eșec. Returnează `"health": null` atunci când nu a fost încercată nicio livrare încă.

`GET /webhooks/{webhookId}/health`

**cURL**

```bash
curl "https://api.youraiconnector.com/v1/webhooks/0/health" \
  -H "X-API-Key: YOUR_API_KEY"
```

**JavaScript**

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

**Python**

```python
import requests

res = requests.get(
    "https://api.youraiconnector.com/v1/webhooks/0/health",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0",
  "url": "https://hooks.example.com/incoming",
  "health": {
    "consecutive_failures": 0,
    "total_failures": 2,
    "total_successes": 120,
    "is_disabled": false,
    "disabled_at": null,
    "disabled_reason": null,
    "last_failure": null,
    "last_success_at": "2026-06-09T12:00:00.000Z",
    "created_at": "2026-05-01T08:00:00.000Z",
    "updated_at": "2026-06-09T12:00:00.000Z"
  }
}
```

Când `is_disabled` este `true`, livrarea către URL a fost suspendată automat după eșecuri repetate. Remediază receptorul, apoi reactivează-l (mai jos).

---

## Reactivează livrarea

Reia livrarea pentru un webhook al cărui URL a fost suspendat automat după eșecuri repetate. Aceasta resetează indicatorul de suspendare și contoarele de eșecuri, dar **nu** încearcă o livrare — folosește punctul final de testare ulterior pentru a confirma că receptorul tău este din nou funcțional.

`POST /webhooks/{webhookId}/reenable`

**cURL**

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/reenable?apiKey=YOUR_API_KEY"
```

**JavaScript**

```javascript
const res = await fetch("https://api.youraiconnector.com/v1/webhooks/0/reenable", {
  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/webhooks/0/reenable",
    headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0"
}
```

---

## Dezactivarea unui abonament

`enabled` este propriul comutator pornit/oprit al abonamentului. Dezactivarea acestuia oprește livrările, păstrând în același timp intacte URL-ul, lista de evenimente și secretul de semnare.

```bash
# Off
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": false}'

# Back on
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"enabled": true}'
```

- **Absența înseamnă pornit.** Un abonament creat înainte de existența acestui câmp nu are nicio valoare `enabled` stocată și livrează normal. `GET /webhooks` raportează întotdeauna un boolean concret.
- Abonamentele dezactivate sunt **încă listate** de `GET /webhooks` — așa le găsiți pentru a le reactiva.
- O [reîncercare](#retries) pusă în coadă înainte de dezactivare nu se reia: reîncercarea recitește abonamentul în momentul trimiterii și renunță dacă acesta este dezactivat.
- Nimic din ceea ce a fost suprimat în timpul dezactivării nu este redat atunci când îl reactivați.

> Distinct de dezactivarea automată după eșecuri repetate, care este raportată de [`GET /webhooks/{id}/health`](#check-delivery-health) ca `is_disabled` și ștearsă cu [`POST /webhooks/{id}/reenable`](#re-enable-delivery). `enabled` este comutatorul contului; `is_disabled` este al nostru. Niciunul nu îl anulează pe celălalt — un abonament trebuie să fie atât activat, cât și să nu fie dezactivat automat pentru a livra.

---

## Un abonament pentru toate conturile clienților (agenții)

Într-un cont de agenție, setați `apply_to_sub_accounts: true` pe un abonament (la momentul creării sau prin `PUT`) și acesta va primi și evenimentele care au loc în fiecare dintre conturile clienților agenției — un singur endpoint acoperă întreaga agenție, în loc să recreați abonamentul pe fiecare cont de client.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"apply_to_sub_accounts": true}'
```

Cum funcționează:

- **Blocul `user` diferențiază conturile.** Blocul `user` al fiecărui payload identifică contul pe care a avut loc efectiv evenimentul, astfel încât receptorul dvs. să poată direcționa per client.
- **Setările proprii ale abonamentului agenției se aplică peste tot.** Lista sa de evenimente, [secretul de semnare](#signed-payloads) și opțiunea de [reîncercare](#retries) sunt utilizate și pentru livrările moștenite.
- **Abonamentul propriu al unui cont de client la același URL are prioritate.** Dacă un cont de client are propriul abonament care indică același URL, acesta este utilizat pentru evenimentele acelui cont — același eveniment nu este livrat niciodată de două ori către un singur endpoint.
- **Conturile clienților nu îl văd.** Abonamentele moștenite nu apar în lista proprie de webhook-uri a unui cont de client, iar clientul nu le poate dezactiva — doar agenția le gestionează.
- **Starea livrării este urmărită per cont de client.** Un endpoint care continuă să eșueze este dezactivat automat pentru contul ale cărui livrări au eșuat, nu pentru întreaga agenție.
- **`subscribed_to_tags` nu se moștenește.** Lista de etichete face referire la etichetele proprii ale agenției, care nu există în conturile clienților — restrângerea rezumatului conversației se aplică doar evenimentelor proprii ale agenției.
- **Inert în altă parte.** Într-un cont fără conturi de clienți, indicatorul este stocat corect și nu face nimic.

---

## Antete pentru fiecare livrare

Aceste trei antete sunt trimise la fiecare livrare, indiferent dacă abonamentul este semnat sau nu:

| Antet | Semnificație |
|---|---|
| `X-Webhook-Delivery` | ID stabil pentru evenimentul logic. Identic între reîncercări — utilizați-l pentru deduplicare. |
| `X-Webhook-Attempt` | Numărul încercării (începând de la 1). |
| `X-Webhook-Event` | Numele evenimentului. |

---

## Payload-uri semnate

Semnarea este opțională, dezactivată implicit și setată per abonament. Când un abonament are un secret de semnare, fiecare livrare conține încă două antete pe lângă cele trei trimise la fiecare livrare (`X-Webhook-Delivery`, `X-Webhook-Attempt` și `X-Webhook-Event`):

| Antet | Semnificație |
|---|---|
| `X-Webhook-Signature` | `v1=<hex>` — HMAC-SHA256 al șirului `"<timestamp>.<raw request body>"`, chemat cu secretul de semnare per webhook pe care îl generați și rotiți la `GET/POST/DELETE /v1/webhooks/{webhookId}/signing-secret`. |
| `X-Webhook-Timestamp` | Ora trimiterii, în secunde Unix. Inclusă în semnătură, deci nu poate fi modificată independent. |

Pentru verificare, recalculați HMAC-SHA256 peste corpul brut (raw) cu secretul dumneavoastră și comparați-l cu antetul. Verificați împotriva corpului cererii **brute**. Re-serializarea JSON-ului analizat modifică octeții și strică comparația. Respingeți livrările al căror marcaj temporal este în afara unei ferestre de prospețime (300s este o valoare implicită rezonabilă) pentru a preveni atacurile de tip replay și comparați folosind o funcție sigură la sincronizare (timing-safe).

Consultați [Payload-uri semnate](../integrations/webhooks.md#signed-payloads-verifying-a-webhook-really-came-from-us) pentru exemple complete de verificare în Node și Python.

> **Semnarea nu este același lucru cu autentificarea API.** API-ul REST în sine se autentifică cu chei API în loc de OAuth (OAuth 2.1 există pentru serverele MCP pe care le înregistrați ca instrumente bot) și nu există încă pachete SDK oficiale pentru npm sau PyPI — apelați endpoint-urile cu orice client HTTP.

### Citiți secretul de semnare

`GET /webhooks/{id}/signing-secret`

```bash
curl "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_1a2b3c...",
  "signing_secret_created_at": "2026-07-15T09:30:00.000Z"
}
```

Când semnarea este dezactivată, `signing_enabled` este `false` și `signing_secret` este `null`.

### Generați sau rotiți secretul de semnare

`POST /webhooks/{id}/signing-secret`

Creează un secret (activând semnarea) sau îl înlocuiește pe cel existent. Returnează noul secret.

```bash
curl -X POST "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": true,
  "signing_secret": "whsec_9f8e7d...",
  "signing_secret_created_at": "2026-07-15T10:00:00.000Z"
}
```

Rotația intră în vigoare imediat — următoarea livrare este semnată doar cu noul secret. Acceptați ambele secrete pentru o scurtă perioadă în timp ce implementați modificarea pe un endpoint activ.

De asemenea, puteți genera un secret în momentul creării transmițând `"generate_signing_secret": true` către `POST /webhooks`; răspunsul va include apoi un câmp `signing_secret` la nivel superior.

### Dezactivarea semnării

`DELETE /webhooks/{id}/signing-secret`

```bash
curl -X DELETE "https://api.youraiconnector.com/v1/webhooks/0/signing-secret?apiKey=YOUR_API_KEY"
```

**Răspuns**

```json
{
  "success": true,
  "webhook_id": "0",
  "signing_enabled": false
}
```

> Toate cele trei rute pentru secrete de semnare necesită permisiunea **edit** pentru integrări, inclusiv `GET` — secretul este o credențială care poate falsifica livrări, deci nu este expus rolurilor cu drept de citire.

---

## Reîncercări

Opțional, dezactivat implicit și configurat per abonament prin intermediul booleanului `retries_enabled` din `POST /webhooks` sau `PUT /webhooks/{id}`.

```bash
curl -X PUT "https://api.youraiconnector.com/v1/webhooks/0?apiKey=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"retries_enabled": true}'
```

Când este activată, o livrare eșuată este reîncercată la **1m, 5m, 30m și 2h** după prima încercare (aproximativ 2h 40m de acoperire).

- **Reîncercate:** răspunsuri 5xx, timeout-uri și eșecuri de conexiune.
- **Nereîncercate:** orice 4xx. Receptorul respinge cererea în sine, deci retrimiterea ei neschimbată doar reproduce respingerea.

Reîncercările fac posibilă livrarea duplicată — un endpoint care a procesat un eveniment, dar a expirat înainte de a răspunde, îl va primi din nou. Folosește `X-Webhook-Delivery` pentru deduplicare, deoarece acesta rămâne constant pe parcursul încercărilor. Acesta este motivul pentru care reîncercările sunt opționale.

Contoarele [delivery-health](#check-delivery-health) numără o livrare întreagă, nu fiecare încercare: un eșec este înregistrat doar după epuizarea tuturor reîncercărilor, deci activarea reîncercărilor nu face ca declanșatorul de dezactivare automată să fie activat mai devreme.

---

## Erori

Toate erorile folosesc plicul standard:

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

Cazuri comune: un URL care nu este permis, un `subscribed_to` gol/invalid sau câmpuri lipsă returnează `400`; un id sau nume necunoscut returnează `404`; iar un `403` înseamnă că webhook-urile nu sunt activate pentru contul tău. Consultă [Erori](errors-and-pagination.md) pentru lista completă.

---

## Pașii următori

- [Webhook-uri (primirea de payload-uri)](../integrations/webhooks.md) — configurează receptorul și înțelege structura payload-ului.
- [Autentificare](authentication.md) — cele patru metode de autentificare a unei cereri.
- [Erori și limite de rată](errors-and-pagination.md) — coduri de stare și limita de 300 cereri/min.
