> This is a page from the ElevenLabs documentation. For a complete page index, fetch https://elevenlabs.io/docs/llms.txt. For the full documentation in a single file, fetch https://elevenlabs.io/docs/llms-full.txt.

# Webhooki

## Omówienie

Wybrane zdarzenia w ElevenLabs można skonfigurować tak, aby wywoływały webhooki, dzięki czemu zewnętrzne aplikacje i systemy mogą je odbierać i przetwarzać na bieżąco. Obecnie obsługiwane są następujące typy zdarzeń:

| Typ zdarzenia                    | Opis                                                                                                                               |
| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| `post_call_transcription`        | Połączenie Agents Platform zakończyło się, a analiza jest gotowa                                                                   |
| `voice_removal_notice`           | Zaplanowano usunięcie udostępnionego głosu                                                                                         |
| `voice_removal_notice_withdrawn` | Usunięcie udostępnionego głosu nie jest już zaplanowane                                                                            |
| `voice_removed`                  | Udostępniony głos został usunięty i nie można go już używać                                                                        |
| `flows_generation`               | [Generowanie Image & Video](/docs/pl/eleven-api/guides/how-to/image-and-video/webhooks) zakończyło się lub nie powiodło            |
| `flows_template_run`             | [Uruchomienie szablonu](/docs/pl/eleven-api/guides/how-to/templates/run-a-template#get-the-result) zakończyło się lub nie powiodło |

## Konfiguracja

Webhooki można tworzyć, wyłączać i usuwać na stronie ustawień ogólnych. W przypadku użytkowników w [obszarach roboczych](/docs/pl/overview/administration/workspaces/overview) webhooki dla obszaru roboczego mogą konfigurować tylko jego administratorzy.

![Konfiguracja webhooka HMAC](/docs/_fern-img/9ea298daac1c64eb43c802a12f7824e83accca44ba2edd1d01a39bcd62c0b9d6.webp)

Po utworzeniu webhook można wybrać do nasłuchiwania zdarzeń w ustawieniach produktu, na przykład [Agents Platform](/docs/pl/eleven-agents/workflows/post-call-webhooks).

Zdarzenia `flows_generation` i `flows_template_run` są włączane przez jedną subskrypcję: w sekcji **Select events to listen to** zaznacz **Image & Video API generation or template run completed** albo przekaż zdarzenie `flows` do [Update workspace webhook](/docs/pl/api-reference/webhooks/update). Generowanie lub proces wysyła swoje zdarzenie tylko wtedy, gdy żądanie jego utworzenia zawiera pole `webhook`.

Webhooki można w każdej chwili wyłączyć na stronie ustawień ogólnych. Webhooki, które wielokrotnie zawodzą, są automatycznie wyłączane, jeśli wystąpiło co najmniej 10 kolejnych niepowodzeń, a ostatnie udane dostarczenie miało miejsce ponad 7 dni temu lub nie było żadnego udanego dostarczenia. Webhooki wyłączone automatycznie trzeba ponownie włączyć na stronie ustawień. Webhooki można usunąć, jeśli nie są używane przez żadne produkty.

## Ponowienia

Ponowienia webhooków można włączyć osobno dla każdego webhooka, aby automatycznie ponawiać dostarczenie, gdy żądanie się nie powiedzie. Ponowienia są domyślnie wyłączone. Włącz je podczas tworzenia lub aktualizowania webhooka przez [API](/docs/pl/api-reference/webhooks/create) albo w ustawieniach webhooka.

> **Note**
>
> Ponowienia są obsługiwane dla webhooków [po połączeniu ElevenAgents](/docs/pl/eleven-agents/workflows/post-call-webhooks), w tym zdarzeń transkrypcji
> (`post_call_transcription`), audio (`post_call_audio`) i niepowodzenia rozpoczęcia połączenia
> (`call_initiation_failure`).

### Harmonogram ponowień

Gdy próba dostarczenia zakończy się błędem kwalifikującym się do ponowienia, system podejmuje do 5 prób z rosnącymi opóźnieniami:

| Próba | Opóźnienie  |
| ----- | ----------- |
| 1     | Natychmiast |
| 2     | 30 sekund   |
| 3     | 2 minuty    |
| 4     | 8 minut     |
| 5     | 30 minut    |

Do każdego ponowienia dodawane jest niewielkie losowe odchylenie (do 10% opóźnienia), aby rozłożyć obciążenie i uniknąć problemów typu thundering herd.

### Błędy kwalifikujące się do ponowienia

Nie wszystkie błędy wywołują ponowienie. Za kwalifikujące się uznawane są tylko:

* Kody stanu `5xx` (błędy serwera, takie jak 500, 502, 503, 504).
* `429` (Too Many Requests).
* `408` (Request Timeout).
* Błędy połączenia i przekroczenia limitu czasu żądania.

Błędy żądań z zakresu `4xx` (takie jak 400, 401, 403, 404) **nie** są ponawiane, ponieważ zwykle wskazują problem z konfiguracją wymagający ręcznej poprawy.

### Limity kolejki dla webhooka

Każdy webhook może mieć maksymalnie 100 oczekujących zadań ponowienia. Jeśli webhook zgromadzi ponad 100 ponowień w kolejce, dodatkowe zadania są odrzucane, dopóki istniejące ponowienia nie zostaną przetworzone. Zapobiega to zużywaniu nadmiernych zasobów przez jeden błędnie skonfigurowany webhook.

Webhooki audio mają dwa dodatkowe limity. Ładunek audio większy niż 50 MiB jest dostarczany raz i nie jest ponawiany, a oczekujące ponowienia audio dla jednego webhooka nie mogą łącznie przekraczać 400 MiB.

### Automatyczne wyłączanie

System śledzi kolejne niepowodzenia dostarczania dla każdego webhooka. Webhook jest automatycznie wyłączany, gdy spełnione są oba poniższe warunki:

* Wystąpiło co najmniej 10 kolejnych niepowodzeń dostarczania.
* Webhook nigdy nie został pomyślnie dostarczony lub ostatnie udane dostarczenie miało miejsce ponad 7 dni temu.

Gdy webhook zostanie automatycznie wyłączony, administratorzy obszaru roboczego otrzymują powiadomienie e-mail. Webhook trzeba ręcznie włączyć ponownie na stronie ustawień, zanim wznowi dostarczanie.

## Integracja

Aby zintegrować webhooki, utwórz procedurę obsługi punktu końcowego, która odbiera dane zdarzeń webhook jako żądania POST. Po zweryfikowaniu podpisu procedura powinna szybko zwrócić HTTP 200, aby potwierdzić pomyślny odbiór. Powtarzający się brak odpowiedzi sukcesu może spowodować automatyczne wyłączenie webhooka.

Ładunek ponowienia jest identyczny jak przy pierwotnej próbie dostarczenia. Odbiorcy webhooków nie mogą rozróżnić pierwszego dostarczenia od ponowienia wyłącznie na podstawie ładunku, dlatego zaprojektuj procedurę jako **idempotentną** — wielokrotne przetworzenie tego samego zdarzenia powinno dawać ten sam wynik. W razie potrzeby użyj `event_timestamp` i identyfikatorów charakterystycznych dla zdarzenia (takich jak `conversation_id`) do usuwania duplikatów.

### Pola najwyższego poziomu

| Pole              | Typ    | Opis                       |
| ----------------- | ------ | -------------------------- |
| `type`            | string | Typ zdarzenia              |
| `data`            | object | Dane zdarzenia             |
| `event_timestamp` | string | Czas wystąpienia zdarzenia |

## Przykładowy ładunek webhooka

```json
{
  "type": "post_call_transcription",
  "event_timestamp": 1739537297,
  "data": {
    "agent_id": "xyz",
    "conversation_id": "abc",
    "status": "done",
    "transcript": [
      {
        "role": "agent",
        "message": "Hey there angelo. How are you?",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 0,
        "conversation_turn_metrics": null
      },
      {
        "role": "user",
        "message": "Hey, can you tell me, like, a fun fact about 11 Labs?",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 2,
        "conversation_turn_metrics": null
      },
      {
        "role": "agent",
        "message": "I do not have access to fun facts about Eleven Labs. However, I can share some general information about the company. Eleven Labs is an AI voice technology platform that specializes in voice cloning and text-to-speech...",
        "tool_calls": null,
        "tool_results": null,
        "feedback": null,
        "time_in_call_secs": 9,
        "conversation_turn_metrics": {
          "convai_llm_service_ttfb": {
            "elapsed_time": 0.3704247010173276
          },
          "convai_llm_service_ttf_sentence": {
            "elapsed_time": 0.5551181449554861
          }
        }
      }
    ],
    "metadata": {
      "start_time_unix_secs": 1739537297,
      "call_duration_secs": 22,
      "cost": 296,
      "deletion_settings": {
        "deletion_time_unix_secs": 1802609320,
        "deleted_logs_at_time_unix_secs": null,
        "deleted_audio_at_time_unix_secs": null,
        "deleted_transcript_at_time_unix_secs": null,
        "delete_transcript_and_pii": true,
        "delete_audio": true
      },
      "feedback": {
        "overall_score": null,
        "likes": 0,
        "dislikes": 0
      },
      "authorization_method": "authorization_header",
      "charging": {
        "dev_discount": true
      },
      "termination_reason": ""
    },
    "analysis": {
      "evaluation_criteria_results": {},
      "data_collection_results": {},
      "call_successful": "success",
      "transcript_summary": "The conversation begins with the agent asking how Angelo is, but Angelo redirects the conversation by requesting a fun fact about 11 Labs. The agent acknowledges they don't have specific fun facts about Eleven Labs but offers to provide general information about the company. They briefly describe Eleven Labs as an AI voice technology platform specializing in voice cloning and text-to-speech technology. The conversation is brief and informational, with the agent adapting to the user's request despite not having the exact information asked for."
    },
    "conversation_initiation_client_data": {
      "conversation_config_override": {
        "agent": {
          "prompt": null,
          "first_message": null,
          "language": "en"
        },
        "tts": {
          "voice_id": null
        }
      },
      "custom_llm_extra_body": {},
      "dynamic_variables": {
        "user_name": "angelo"
      }
    }
  }
}
```

## Uwierzytelnianie

Ważne, by odbiornik weryfikował wszystkie przychodzące webhooki. Webhooki obecnie obsługują uwierzytelnianie za pomocą podpisów HMAC. Aby skonfigurować uwierzytelnianie HMAC:

* Bezpiecznie przechowuj współdzielony sekret wygenerowany podczas tworzenia webhooka
* Zweryfikuj nagłówek ElevenLabs-Signature w swoim endpointzie za pomocą SDK

SDK JavaScript udostępnia `constructEvent`, a SDK Python `construct_event` z parametrami **`rawBody`**, **`sig_header`** i **`secret`** (w Pythonie nie nazywają się one `payload` / `signature`). Oba weryfikują podpis, sprawdzają znacznik czasu i parsują dane JSON.

#### Python

Przykładowy handler webhooka z użyciem FastAPI:

```python
from dotenv import load_dotenv
from fastapi import FastAPI, Request
from fastapi.responses import JSONResponse
from elevenlabs.client import ElevenLabs
from elevenlabs.errors import BadRequestError
import os

load_dotenv()

app = FastAPI()
elevenlabs = ElevenLabs(
    api_key=os.getenv("ELEVENLABS_API_KEY"),
)

WEBHOOK_SECRET = os.getenv("WEBHOOK_SECRET")

@app.post("/webhook")
async def receive_message(request: Request):
    payload = await request.body()
    signature = request.headers.get("elevenlabs-signature")

    try:
        event = elevenlabs.webhooks.construct_event(
            rawBody=payload.decode("utf-8"),
            sig_header=signature,
            secret=WEBHOOK_SECRET,
        )
    except BadRequestError as e:
        return JSONResponse(content={"error": "Invalid signature"}, status_code=401)

    # construct_event returns a dict (parsed JSON), not an object with attributes
    if event.get("type") == "post_call_transcription":
        print(f"Received transcription: {event.get('data')}")

    return {"status": "received"}
```

#### JavaScript

#### Express

Przykładowy handler webhooka z użyciem Express:

```javascript
import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';
import express from 'express';

const app = express();

const elevenlabs = new ElevenLabsClient();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

// Use express.text() to preserve raw body for signature verification
app.post('/webhook', express.text({ type: 'application/json' }), async (req, res) => {
  const signature = req.headers['elevenlabs-signature'];
  const payload = req.body; // Raw string body

  let event;
  try {
    event = await elevenlabs.webhooks.constructEvent(payload, signature, WEBHOOK_SECRET);
  } catch (error) {
    return res.status(401).json({ error: 'Invalid signature' });
  }

  // Process the webhook event
  if (event.type === 'post_call_transcription') {
    console.log('Received transcription:', event.data);
  }

  res.status(200).json({ received: true });
});
```

#### Next.js

Przykładowy handler webhooka z użyciem trasy API Next.js:

**`app/api/webhook/route.ts`**

```typescript app/api/webhook/route.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/server';
import { ElevenLabsClient } from '@elevenlabs/elevenlabs-js';

const elevenlabs = new ElevenLabsClient();
const WEBHOOK_SECRET = process.env.WEBHOOK_SECRET;

export async function POST(req: NextRequest) {
  const body = await req.text();
  const signature = req.headers.get('elevenlabs-signature');

  let event;
  try {
    event = await elevenlabs.webhooks.constructEvent(body, signature, WEBHOOK_SECRET);
  } catch (error) {
    return NextResponse.json({ error: 'Invalid signature' }, { status: 401 });
  }

  // Process the webhook event
  if (event.type === 'post_call_transcription') {
    console.log('Received transcription:', event.data);
  }

  return NextResponse.json({ received: true }, { status: 200 });
}
```