---
title: "telephony.incoming / web.incoming"
description: "Blokirni spletni klic, ki v realnem času oblikuje konfiguracijo dohodnega klica."
---

Ko dohodni telefonski klic doseže številko **brez dodeljenega
agenta** ali se seja spletnega gradnika začne z objavljivim ključem v
`mode="webhook"`, ThunderPhone pošlje **blokirajočo**
zahtevo `telephony.incoming` / `web.incoming` na vaš
[podedovani URL webhooka](/api-reference/organizations#legacy-single-url-webhook)
in čaka do **10 sekund** na odgovor s konfiguracijo. To izmenjavo
uporabite za dinamično izbiro poziva, glasu in orodij za vsak klic —
za celoten vzorec glejte [vodnik za dinamično konfiguracijo klicev](/sl/guides/dynamic-call-config).

<Note>
  Naročene [končne točke webhookov](/sl/webhooks/endpoints) prav tako prejmejo
  `telephony.incoming` / `web.incoming` — za **vsak** dohodni klic
  in spletno sejo, ne glede na to, ali je agent konfiguriran — vendar so te
  dostave obvestila brez čakanja na odgovor z `event_id` in nikoli ne blokirajo.
  Samo podedovani webhook z enim URL-jem prenaša izmenjavo konfiguracije
  na tej strani. Oblike obvestil končnih točk so v
  [katalogu dogodkov](/sl/webhooks/events).
</Note>

Blokirajoča izmenjava nima nadomestne možnosti: če vaš obravnavalnik vrne
stanje, ki ni 2xx, poteče časovna omejitev ali vrne konfiguracijo, ki ne uspe
pri preverjanju veljavnosti, je klic zavrnjen (telefonski klic se ne poveže;
zahteva za sejo gradnika ne uspe z `502`/`422`). Odgovorite hitro — klicatelj
med vašo odločitvijo sliši povratni signal zvonjenja.

<Warning>
  **Klici, konfigurirani z webhookom, ne vključujejo obvestila ThunderPhone
  o soglasju.** Klici, konfigurirani prek te izmenjave, obidejo obvestilo ob
  začetku klica na ravni agenta in so izrecno izključeni iz okvira ThunderPhone
  za obvestila o soglasju (Pogoji uporabe, razdelek »Snemanje in soglasje«).
  Vaša organizacija je izključno odgovorna za vsa obvestila in soglasja glede
  snemanja, spremljanja, sodelovanja umetne inteligence in identifikacije
  klicatelja, ki so potrebna pri teh klicih — klici so lahko še vedno snemani,
  prepisani, analizirani in obravnavani z umetno inteligenco. Preden omogočite
  to pot, v svoj potek klica vključite zahtevana razkritja.
</Warning>

## Telo zahteve

Za telefonske klice (`telephony.incoming`):

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

| Polje | Vrsta | Opis |
|-------|------|-------------|
| `call_id` | celo število | ID klica — enak v vseh dogodkih za ta klic |
| `from_number` | niz | Številka klicatelja v formatu E.164 |
| `to_number` | niz | Cilj v formatu E.164 (ena od vaših številk ThunderPhone) |

Za seje spletnega gradnika (`web.incoming`) `data` namesto telefonskih
številk določa stran, v katero je gradnik vdelan:

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

| Polje | Vrsta | Opis |
|-------|------|-------------|
| `call_id` | celo število | ID klica |
| `origin_domain` | niz | Izvor strani, ki gosti gradnik |
| `publishable_key_prefix` | niz | Prvi znaki objavljivega ključa, ki je odprl sejo |
| `language`, `primary_language` | niz | Prisotno, kadar seja gradnika zahteva preglasitev jezika |
| `voice` | niz | Prisotno, kadar seja gradnika zahteva preglasitev glasu |
| `website_context` | niz | Prisotno, kadar gradnik posreduje kontekst strani za posamezno sejo |

<Note>
  Gradniki v načinu webhook pošljejo to zahtevo na lastni `webhook_url`
  objavljivega ključa, kadar je nastavljen, sicer pa na URL webhooka na ravni
  organizacije. V obeh primerih je podpisana s `secret` webhooka organizacije.
</Note>

---

## Shema odgovora

Vrnite objekt JSON, ki opisuje konfiguracijo agenta za ta klic.
`prompt` in `voice` sta obvezna; vse drugo je izbirno.

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

| Polje | Vrsta | Obvezno | Opis |
|-------|------|----------|-------------|
| `prompt` | niz | da | Sistemski poziv, ki usmerja agenta |
| `voice` | niz | da | ID glasu iz [`GET /v1/voices`](/api-reference/agents#voices), npr. `john`. `voice_name` je sprejet kot vzdevek. Neznani glasovi ne prestanejo preverjanja in zavrnejo klic |
| `product` | niz | ne | Privzeto je `spark`. Dovoljeno: `spark`, `bolt`, `storm-base`, `storm-base-with-ack`, `storm-extra`, `storm-extra-with-ack` |
| `thinking_level` | niz | ne | `minimal`, `base` (privzeto) ali `extra`. Za izdelke Storm je prepisano: `storm-extra*` vsili `extra`, drugi `storm-*` vsilijo `base` |
| `audio_context_mode` | niz | ne | `full` (privzeto) ali `reduced` |
| `watchdog_enabled` | logična vrednost | ne | Omogočite nadzor za ta klic. Privzeto `false` |
| `additional_audio_context` | logična vrednost \| null | ne | Vključite zadnjih nekaj izmenjav zvoka klicatelja namesto samo najnovejše izmenjave, kar z majhnim dodatnim zamikom/stroškom izboljša popravke ter zbiranje podatkov z veliko črkovanja ali številk. Za dohodne seje je privzeto vklopljeno, za odhodne telefonske klice pa izklopljeno; `null` ohrani privzeto nastavitev |
| `storm_feedback_mode` | niz | ne | `none`, `acknowledgement` (privzeto) ali `tick` |
| `language` | niz | ne | Okrajšava za `primary_language` |
| `primary_language` | niz | ne | Jezikovna koda, normalizirana (privzeto `en`). Nerazrešljive kode zavrnejo klic |
| `has_additional_languages` | logična vrednost | ne | Privzeto `false` |
| `additional_languages` | polje nizov | ne | Dodatni jeziki, na katere lahko agent preklopi |
| `native_voice_switching` | logična vrednost | ne | Privzeto `false`. Ko klic preklopi v drug jezik, zamenjajte glas z glasom, katerega materni jezik je ta jezik (ujemanje po spolu), namesto da ohranite nastavljeni glas |
| `background_track` | niz \| null | ne | ID ambientalnega zvoka ali `null` |
| `acknowledgement_prompt_mode` | niz | ne | `auto` (privzeto) ali `manual` (izdelki Storm-with-ack) |
| `acknowledgement_prompt` | niz | ne | Uporabi se, ko je `acknowledgement_prompt_mode="manual"` |
| `silence_interval_seconds` | celo število \| null | ne | 5–120. Sekunde tišine klicatelja pred preverjanjem |
| `silence_max_checkins` | celo število \| null | ne | 1–10 |
| `silence_checkins_enabled` | logična vrednost | ne | Privzeto `true` |
| `connect_tone_enabled` | logična vrednost | ne | Privzeto `false` |
| `voicemail_action` | niz | ne | `prompt` (privzeto), `hangup` ali `message` |
| `voicemail_message` | niz | ne | Uporabi se, ko je `voicemail_action="message"` |
| `agent_name` | niz | ne | Prikazno ime, prikazano na nadzornih ploščah in v pripomočku |
| `org_name` | niz | ne | Prikazno ime organizacije za persono agenta |
| `tools` | polje | ne | Vgrajene sheme funkcijskih orodij (glejte [Funkcijska orodja](/sl/tools/overview)) |
| `call_id` | celo število | ne | Izbirni odmev ID-ja klica iz zahteve; prezrto |

<Note>
  Neznani ključi na najvišji ravni so tiho **prezrti** — polje z napačno
  zapisanim imenom ne zavrne konfiguracije, ampak se preprosto ne uporabi.
  Vrstni red govora in `max_hold_seconds` tukaj nista sprejeta; nastaviti ju je
  mogoče samo v samem [Agentu](/api-reference/agents).
</Note>

Ker sta `prompt` in `voice` obvezna, vrnitev `{}` ali katerega koli
odgovora, ki ne prestane preverjanja, zavrne klic s `422` — na tej poti
ni nadomestnega statičnega agenta (številka ali ključ v načinu webhook
nima dodeljenega agenta).

---

## Omejitev velikosti odziva

<Warning>
  Konfiguracijski odzivi so omejeni na **5 MiB**. Če obdelovalnik
  vrne večji odziv, tudi s stanjem `2xx`, ThunderPhone sporoči, da je
  odziv presegel omejitev, ter zavrne klic ali sejo pripomočka. Odziv
  omejite na polja, potrebna za vzpostavitev klica; velike podatke
  gostite za funkcijskimi orodji ali drugo storitvijo, namesto da jih
  vključite v konfiguracijo.
</Warning>

---

## Primer obdelovalnika

<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>

---

## Odziv s funkcijskimi orodji

Priložite orodja, da lahko umetna inteligenca med pogovorom pokliče vaše API-je:

```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>
  Zahteve do končne točke orodja so podpisane z **istim skrivnim
  ključem spletnega kljuka organizacije**, ki je podpisal to izmenjavo.
  Za natančno obliko in obliko podpisane zahteve glejte
  [Funkcijska orodja](/sl/tools/overview).
</Tip>

---

## Hiter pregled ravni izdelkov

| Izdelek | Zakasnitev | Sklepanje | Potrditev |
|---------|---------|-----------|-----------------|
| `spark` | Najnižja | Osnovno | — |
| `bolt` | Nizka | Izboljšano | — |
| `storm-base` | Srednja | Zmogljivo | — |
| `storm-base-with-ack` | Srednja | Zmogljivo | Samodejno zapolnilo med razmišljanjem |
| `storm-extra` | Višja | Poglobljeno | — |
| `storm-extra-with-ack` | Višja | Poglobljeno | Samodejno zapolnilo med razmišljanjem |

---

## Povezano

<CardGroup cols={2}>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/sl/webhooks/call-complete">
    Neblokirajoč dogodek ob koncu klica.
  </Card>
  <Card title="Funkcijska orodja" icon="screwdriver-wrench" href="/sl/tools/overview">
    Celotna shema JSON za `tools[]` in pogodba podpisane končne točke.
  </Card>
  <Card title="Končne točke webhookov" icon="bolt" href="/sl/webhooks/endpoints">
    Naročite več naslovov URL na `telephony.incoming` / `web.incoming`.
  </Card>
  <Card title="Dinamična konfiguracija klicev" icon="wand-magic-sparkles" href="/sl/guides/dynamic-call-config">
    Vzorci za pozive, orodja in A/B-teste za posamezne klicatelje.
  </Card>
</CardGroup>
