---
title: "telephony.incoming / web.incoming"
description: "Gelen bir aramanın yapılandırmasını gerçek zamanlı olarak şekillendiren engelleyici webhook."
---

Bir gelen telefon araması **atanmış bir yapay zeka ajanı
olmayan** bir numaraya ulaştığında veya bir web widget oturumu
`mode="webhook"` içindeki yayımlanabilir bir anahtarda başladığında, ThunderPhone
[eski webhook URL'nize](/api-reference/organizations#legacy-single-url-webhook)
**engelleyici** bir `telephony.incoming` / `web.incoming` isteği gönderir
ve yapılandırma yanıtını bekler: telefon araması için, bir yeniden deneme
dahil, en fazla **13 saniye**; widget oturumu için ise en fazla **10 saniye**
([Zaman aşımları ve yeniden denemeler](#timeouts-and-retries) bölümüne bakın). Bu
alışverişi kullanarak her arama için istemi, sesi ve araçları dinamik olarak seçin —
uçtan uca akış için [dinamik arama yapılandırma kılavuzuna](/tr/guides/dynamic-call-config)
bakın.

<Note>
  Abone olunan [webhook uç noktaları](/tr/webhooks/endpoints) da
  `telephony.incoming` / `web.incoming` alır — ajan yapılandırılmış
  olsun veya olmasın **her** gelen çağrı ve web oturumu için — ancak bu
  teslimatlar `event_id` içeren, yanıt beklemeyen bildirimlerdir ve
  hiçbir zaman bloklayıcı değildir. Bu sayfadaki yapılandırma
  alışverişini yalnızca eski tek URL webhook'u taşır. Uç nokta bildirim
  biçimleri [olay kataloğunda](/tr/webhooks/events)
  bulunur.
</Note>

## Zaman aşımları ve yeniden denemeler

Hızlı yanıt verin: siz karar verirken arayan kişi hatta bekliyor.

Bir telefon görüşmesi (`telephony.incoming`) için:

- İlk deneme **10 saniyeye** kadar sürebilir.
- Zaman aşımına uğrarsa, bağlanamazsa veya `5xx`, `408` ya da `429`
  yanıtı alırsa ThunderPhone bir kez daha dener. Yeniden deneme, tüm
  alışveriş için ayrılan **13 saniyelik** bütçeden kalan süreyi kullanır: zaman
  aşımına uğrayan ilk denemeden sonra yaklaşık 3 saniye, hızlı bir hatadan sonra
  ise neredeyse 13 saniyenin tamamı.
  2 saniyeden az süre kalacaksa yeniden deneme yapılmaz.
- Diğer tüm `4xx` yanıtları, [boyut sınırını](#response-size-limit)
  aşan yanıtlar veya gövdesi geçerli bir yapılandırma olmayan `2xx`
  yanıtları kesindir ve yeniden denenmez.
- Her iki deneme de aynı gövdeyi, aynı `X-ThunderPhone-Signature`
  ve aynı `X-ThunderPhone-Idempotency-Key` üst bilgisini
  (`telephony-incoming-<call_id>`) gönderir; böylece yan etkileri olan
  bir işleyici yeniden denemeyi tanıyabilir.

Yedek yapay zeka ajanı yoktur. Kullanılabilir bir yapılandırma gelmezse,
arayan kişiyi sessiz bir hatta bekletmek yerine görüşme hemen sonlandırılır.
Çağrı geçmişinde `end_reason` değeri `inbound_config_webhook_failed` olan
başarısız, ücretlendirilmeyen bir çağrı olarak görünür ve standart
[`telephony.complete`](/tr/webhooks/call-complete) olayı gönderilir.

Bir widget oturumu (`web.incoming`), 10 saniyeye kadar tek bir deneme alır.
Başarısız olursa oturum isteği `502` veya `422` ile başarısız olur.

<Warning>
  **Webhook ile yapılandırılan çağrılar ThunderPhone onay
  duyurusu içermez.** Bu alışveriş üzerinden yapılandırılan çağrılar,
  ajan düzeyindeki çağrı başlangıcı duyurusunu atlar ve ThunderPhone'un
  onay duyurusu çerçevesinin (Hizmet Koşulları, "Kayıt ve onay"
  bölümü) açıkça dışındadır. Bu çağrılarda gerekli olan her türlü kayıt,
  izleme, yapay zeka katılımı ve arayan kimliği bildirimi ile onaydan
  yalnızca kuruluşunuz sorumludur — çağrılar yine de kaydedilebilir,
  yazıya dökülebilir, analiz edilebilir ve yapay zeka tarafından
  işlenebilir. Bu yolu etkinleştirmeden önce gerekli açıklamaları kendi
  çağrı akışınıza ekleyin.
</Warning>

## İstek yükü

Telefon çağrıları için (`telephony.incoming`):

```json
{
  "type": "telephony.incoming",
  "data": {
    "call_id":     987654321,
    "from_number": "+14155550199",
    "to_number":   "+15551234567"
  }
}
```

| Alan | Tür | Açıklama |
|-------|------|-------------|
| `call_id` | integer | Çağrı kimliği — bu çağrıdaki tüm olaylarda sabittir |
| `from_number` | string | E.164 arayan numarası |
| `to_number` | string | E.164 hedefi (ThunderPhone numaralarınızdan biri) |

Web bileşeni oturumları için (`web.incoming`) `data`, telefon
numaraları yerine yerleştirme sayfasını tanımlar:

```json
{
  "type": "web.incoming",
  "data": {
    "call_id": 987654322,
    "origin_domain": "https://example.com",
    "publishable_key_prefix": "pk_live_a1b2"
  }
}
```

| Alan | Tür | Açıklama |
|-------|------|-------------|
| `call_id` | integer | Arama kimliği |
| `origin_domain` | string | Tarayıcının gönderdiği şekilde widget'ı barındıran sayfanın kaynağı. Tarayıcı dışı bir istemci herhangi bir değer gönderebileceğinden, bunu isteğin geldiği yerin kanıtı olarak kabul etmeyin |
| `publishable_key_prefix` | string | Oturumu açan yayımlanabilir anahtarın ilk karakterleri |
| `language`, `primary_language` | string | Widget oturumu bir dil geçersiz kılması istediğinde bulunur |
| `voice` | string | Widget oturumu bir ses geçersiz kılması istediğinde bulunur |
| `website_context` | string | Widget oturum başına sayfa bağlamı ilettiğinde bulunur |

Geçersiz kılma alanları (`language`, `voice`, `website_context` ve tüm
tarayıcı `variables` değerleri), yalnızca yayımlanabilir anahtar bunlara
[tarayıcı geçersiz kılmalarında](/tr/guides/embed-web-widget) izin verdiğinde gelir. Anahtarın izin vermediği bir alanı içeren oturum isteği,
bu webhook çağrılmadan önce reddedilir.

<Note>
  Webhook modundaki bileşenler, ayarlanmışsa bu isteği yayınlanabilir
  anahtarın kendi `webhook_url` adresine gönderir; aksi halde kuruluş
  düzeyindeki webhook URL'sine geri döner. Her iki durumda da kuruluş
  webhook `secret` değeriyle imzalanır.
</Note>

---

## Yanıt şeması

Bu çağrı için ajan yapılandırmasını açıklayan bir JSON nesnesi döndürün.
`prompt` ve `voice` zorunludur; diğer her şey isteğe bağlıdır.

```json
{
  "prompt":  "You are a helpful booking assistant for Acme Restaurant.",
  "voice":   "john",
  "product": "spark",
  "background_track": null,
  "tools":   []
}
```

| Alan | Tür | Zorunlu | Açıklama |
|-------|------|----------|-------------|
| `prompt` | string | evet | Ajanı yönlendiren sistem istemi |
| `voice` | string | evet | [`GET /v1/voices`](/api-reference/agents#voices) içindeki ses kimliği; örneğin `john`. `voice_name` diğer ad olarak kabul edilir. Bilinmeyen sesler doğrulamadan geçemez ve çağrı reddedilir |
| `product` | string | hayır | Varsayılan değer `spark` olur. İzin verilenler: `spark`, `bolt`, `storm-base`, `storm-base-with-ack`, `storm-extra`, `storm-extra-with-ack` |
| `thinking_level` | string | hayır | `minimal`, `base` (varsayılan) veya `extra`. Storm ürünleri için geçersiz kılınır: `storm-extra*`, `extra` değerini zorunlu kılar; diğer `storm-*` ürünleri `base` değerini zorunlu kılar |
| `audio_context_mode` | string | hayır | `full` (varsayılan) veya `reduced` |
| `watchdog_enabled` | boolean | hayır | Bu çağrı için denetimi etkinleştirin. Varsayılan değer `false` |
| `additional_audio_context` | boolean \| null | hayır | Yalnızca en son tur yerine arayanın sesinin son birkaç turunu dahil ederek, küçük bir gecikme/maliyet artışı karşılığında düzeltmeleri ve yazım/sayı ağırlıklı veri toplamayı iyileştirin. Gelen oturumlarda varsayılan olarak açıktır, giden telefon çağrılarında kapalıdır; `null` varsayılanı korur |
| `storm_feedback_mode` | string | hayır | `none`, `acknowledgement` (varsayılan) veya `tick` |
| `language` | string | hayır | `primary_language` için kısa ad |
| `primary_language` | string | hayır | Normalleştirilmiş dil kodu (varsayılan `en`). Çözümlenemeyen kodlar çağrıyı reddeder |
| `has_additional_languages` | boolean | hayır | Varsayılan değer `false` |
| `additional_languages` | array of string | hayır | Ajanın geçiş yapabileceği ek diller |
| `native_voice_switching` | boolean | hayır | Varsayılan değer `false`. Çağrı başka bir dile geçtiğinde, yapılandırılmış sesi korumak yerine o dile özgü bir sesle değiştirin (cinsiyete göre eşleştirilir) |
| `language_switching` | string \| null | hayır | `ask_first` (varsayılan) veya `follow_caller`; `null`, `ask_first` ile aynıdır. Çok dilli bir ajanın, diğer kişinin kendi dillerinden başka birini konuşmasını nasıl ele aldığını belirler. `ask_first`, kişi dili istediğinde veya o dilde tam bir cümle söylediğinde hemen geçiş yapar; "evet" gibi kısa bir şeyden sonra ise o dilde devam edilip edilmeyeceğini sorar. `follow_caller`, tek bir kelime bile olsa konuşulan yapılandırılmış dile geçiş yapar. Yalnızca `additional_languages` ayarlandığında uygulanır |
| `background_track` | string \| null | hayır | Ortam sesi kimliği veya `null` |
| `acknowledgement_prompt_mode` | string | hayır | `auto` (varsayılan) veya `manual` (Storm-with-ack ürünleri) |
| `acknowledgement_prompt` | string | hayır | `acknowledgement_prompt_mode="manual"` olduğunda kullanılır |
| `silence_interval_seconds` | integer \| null | hayır | 5–120. Bir kontrol mesajından önce arayanın sessiz kalacağı saniye sayısı |
| `silence_max_checkins` | integer \| null | hayır | 1–10 |
| `silence_checkins_enabled` | boolean | hayır | Varsayılan değer `true` |
| `connect_tone_enabled` | boolean | hayır | Varsayılan değer `false` |
| `pronunciation_dicts` | boolean \| null | hayır | Varsayılan değer `false`; `null`, `false` ile aynıdır. `true` olduğunda, çağrının Cartesia konuşması, mevcutsa çağrının dili için ThunderPhone'un telaffuz sözlüğünü kullanır. Telefon ve widget çağrılarında çalışır. Yalnızca ThunderPhone'un kendi Cartesia sesleri için geçerlidir; kendi Cartesia API anahtarınızdaki sesler için geçerli değildir. Kaydedilmiş ajanın ayarlarının uygulandığı `agent_id` ile kullanılmaz |
| `voicemail_action` | string | hayır | `prompt` (varsayılan), `hangup` veya `message` |
| `voicemail_message` | string | hayır | `voicemail_action="message"` olduğunda kullanılır |
| `agent_name` | string | hayır | Panolara ve widget'a bildirilen görünen ad |
| `org_name` | string | hayır | Ajanın kişiliği için kuruluş görünen adı |
| `tools` | array | hayır | Satır içi işlev aracı şemaları (bkz. [İşlev Araçları](/tr/tools/overview)) |
| `transfer_destinations` | array of object \| null | hayır | Bu çağrının aktarabileceği en fazla 50 `{name, number}` girişi; bir ajanın [aktarım numaraları](/api-reference/agents#transfer-numbers) gibi doğrulanır. Ajan ada göre ve yalnızca bunlara aktarım yapar; `[]`, aktarım olmadığı anlamına gelir. Ajanın seçtiği bir numaraya aktarım yapmasına izin vermek için bunu atlayın veya `null` gönderin |
| `timezone` | string | hayır | Bu çağrı için `America/Chicago` gibi IANA saat dilimi. Ajan, kendi saat diliminden önce bu saat dilimindeki tarihi ve saati belirtir. `agent_id` yanında da izin verilir. IANA saat dilimi olmayan değerler yok sayılır. Bkz. [Çağrı başına saat dilimini ayarlama](/tr/guides/dynamic-call-config) |
| `call_id` | integer | hayır | İsteğin çağrı kimliğinin isteğe bağlı yankısı; yok sayılır |

<Note>
  Bilinmeyen üst düzey anahtarlar sessizce **yoksayılır** — yazım hatalı bir alan
  adı yapılandırmayı reddetmez, yalnızca uygulanmaz. Konuşma sırası
  ve `max_hold_seconds` burada kabul edilmez; yalnızca
  [Agent](/api-reference/agents) üzerinde yapılandırılabilir.
</Note>

`prompt` ve `voice` zorunlu olduğundan, `{}` döndürmek veya doğrulamadan geçemeyen herhangi bir yanıt aramayı reddeder: telefon araması [Zaman aşımları ve yeniden denemeler](#timeouts-and-retries) bölümünde açıklandığı şekilde sonlandırılır ve bileşen oturumu isteği `422` ile başarısız olur. Bu yolda statik ajan geri dönüşü yoktur (webhook modundaki bir numaraya veya anahtara atanmış bir ajan bulunmaz).

---

## Yanıt boyutu sınırı

<Warning>
  Yapılandırma yanıtları **5 MiB** ile sınırlıdır. Bir işleyici,
  `2xx` durumu da dahil olmak üzere daha büyük bir yanıt döndürürse,
  ThunderPhone yanıtın sınırı aştığını bildirir ve çağrıyı veya
  widget oturumunu reddeder. Yanıtı çağrı kurulumu için gerekli
  alanlarla sınırlı tutun; büyük verileri yapılandırmaya gömmek yerine
  işlev araçlarının veya başka bir hizmetin arkasında barındırın.
</Warning>

---

## Örnek işleyici

<CodeGroup>
```python Python (FastAPI)
import hashlib
import hmac
import json
import os

from fastapi import FastAPI, HTTPException, Request

app = FastAPI()
WEBHOOK_SECRET = os.environ["THUNDERPHONE_WEBHOOK_SECRET"]

def verify(body: bytes, signature: str) -> bool:
    expected = hmac.new(WEBHOOK_SECRET.encode(), body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature or "")

@app.post("/thunderphone-webhook")
async def webhook(request: Request):
    body = await request.body()
    if not verify(body, request.headers.get("X-ThunderPhone-Signature", "")):
        raise HTTPException(status_code=401)

    event = json.loads(body)
    if event["type"] == "telephony.incoming":
        caller = event["data"]["from_number"]
        prompt = (
            "Greet the caller as a San Francisco local…"
            if caller.startswith("+1415")
            else "You are a friendly customer support agent…"
        )
        return {
            "prompt": prompt,
            "voice": "john",
            "product": "spark",
        }
    if event["type"] == "web.incoming":
        return {
            "prompt": "You are the website's helpful voice assistant…",
            "voice": "john",
            "product": "spark",
        }
    return {}
```

```javascript Node.js (Express)
import crypto from "node:crypto";
import express from "express";

const app = express();
const SECRET = process.env.THUNDERPHONE_WEBHOOK_SECRET;

function verify(body, signature) {
  const expected = crypto
    .createHmac("sha256", SECRET)
    .update(body)
    .digest("hex");
  return signature &&
    crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(signature));
}

app.post(
  "/thunderphone-webhook",
  express.raw({ type: "application/json" }),
  (req, res) => {
    if (!verify(req.body, req.header("X-ThunderPhone-Signature"))) {
      return res.sendStatus(401);
    }
    const event = JSON.parse(req.body.toString("utf8"));

    if (event.type === "telephony.incoming" || event.type === "web.incoming") {
      const caller = event.data.from_number || "web";
      const prompt = caller.startsWith("+1415")
        ? "Greet the caller as a San Francisco local…"
        : "You are a friendly customer support agent…";
      return res.json({
        prompt,
        voice: "john",
        product: "spark",
      });
    }
    res.json({});
  },
);
```
</CodeGroup>

---

## İşlev araçlarıyla yanıt

Yapay zekanın görüşme sırasında API'lerinizi çağırabilmesi için araçlar ekleyin:

```json
{
  "prompt":  "You are a booking assistant. Use the available tools to help customers schedule appointments.",
  "voice":   "john",
  "product": "spark",
  "tools": [
    {
      "type": "function",
      "function": {
        "name": "search_appointments",
        "description": "Find available appointment slots",
        "parameters": {
          "type": "object",
          "properties": {
            "date": { "type": "string", "description": "YYYY-MM-DD" },
            "service": { "type": "string" }
          },
          "required": ["date"]
        }
      },
      "endpoint": {
        "url": "https://api.example.com/appointments/search",
        "method": "POST",
        "headers": {
          "X-Api-Key": "your-key"
        }
      }
    }
  ]
}
```

<Tip>
  Araç uç noktası istekleri, bu alışverişi imzalayan **aynı kuruluş
  webhook gizli anahtarı** ile imzalanır. Tam yapı ve imzalı istek
  biçimi için [İşlev Araçları](/tr/tools/overview) sayfasına bakın.
</Tip>

---

## Ürün katmanı hızlı başvuru

| Ürün | Gecikme | Akıl yürütme | Onay |
|---------|---------|-----------|-----------------|
| `spark` | En düşük | Temel | — |
| `bolt` | Düşük | Gelişmiş | — |
| `storm-base` | Orta | Güçlü | — |
| `storm-base-with-ack` | Orta | Güçlü | Düşünürken otomatik dolgu |
| `storm-extra` | Daha yüksek | Derin | — |
| `storm-extra-with-ack` | Daha yüksek | Derin | Düşünürken otomatik dolgu |

---

## İlgili

<CardGroup cols={2}>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/tr/webhooks/call-complete">
    Engellemeyen çağrı sonu olayı.
  </Card>
  <Card title="İşlev Araçları" icon="screwdriver-wrench" href="/tr/tools/overview">
    `tools[]` için tam JSON şeması ve imzalı uç nokta sözleşmesi.
  </Card>
  <Card title="Webhook uç noktaları" icon="bolt" href="/tr/webhooks/endpoints">
    Birden çok URL'yi `telephony.incoming` / `web.incoming` olaylarına abone edin.
  </Card>
  <Card title="Dinamik çağrı yapılandırması" icon="wand-magic-sparkles" href="/tr/guides/dynamic-call-config">
    Arayana özel istemler, araçlar ve A/B testleri için kalıplar.
  </Card>
</CardGroup>
