---
title: "telephony.incoming / web.incoming"
description: "Estävä webhook, joka määrittää saapuvan puhelun asetukset reaaliajassa."
---

Kun saapuva puhelu saapuu numeroon **ilman määritettyä
agenttia** tai verkkowidgetin istunto käynnistyy julkisella avaimella tilassa
`mode="webhook"`, ThunderPhone lähettää **estävän**
`telephony.incoming` / `web.incoming` -pyynnön
[vanhaan webhook-URL-osoitteeseesi](/api-reference/organizations#legacy-single-url-webhook)
ja odottaa määritysvastausta: puhelulle enintään **13 sekuntia**,
sisältäen yhden uudelleenyrityksen, ja widgetin istunnolle enintään **10 sekuntia**
(katso [Aikakatkaisut ja uudelleenyritykset](#timeouts-and-retries)). Käytä tätä
vaihtoa kehotteen, äänen ja työkalujen dynaamiseen valintaan puhelukohtaisesti —
katso kokonaisvaltainen toimintamalli
[dynaamisen puhelumäärityksen oppaasta](/fi/guides/dynamic-call-config).

<Note>
  Tilatut [webhook-päätepisteet](/fi/webhooks/endpoints) vastaanottavat myös
  `telephony.incoming` / `web.incoming` -tapahtumat — **jokaisesta**
  saapuvasta puhelusta ja web-istunnosta riippumatta siitä, onko agentti
  määritetty — mutta nämä toimitukset ovat ei-estäviä ilmoituksia, joissa on
  `event_id`. Vain vanha yhden URL-osoitteen webhook sisältää tällä sivulla
  kuvatun määritysvaihdon. Päätepisteilmoitusten muodot löytyvät
  [tapahtumaluettelosta](/fi/webhooks/events).
</Note>

## Aikakatkaisut ja uudelleenyritykset

Vastaa nopeasti: soittaja odottaa linjalla, kun teet päätöstä.

Puhelussa (`telephony.incoming`):

- Ensimmäinen yritys voi kestää enintään **10 sekuntia**.
- Jos se aikakatkaistaan, yhteyttä ei voida muodostaa tai se saa vastauksen
  `5xx`, `408` tai `429`, ThunderPhone yrittää vielä kerran. Uudelleenyritys saa käyttöönsä sen osuuden
  koko vaihdolle varatusta **13 sekunnin** ajasta, joka on jäljellä: noin 3 sekuntia
  aikakatkaistun ensimmäisen yrityksen jälkeen ja lähes kaikki 13 sekuntia nopean epäonnistumisen jälkeen.
  Uudelleenyritystä ei tehdä, jos aikaa olisi jäljellä alle 2 sekuntia.
- Mikä tahansa muu `4xx`-vastaus, [kokorajan](#response-size-limit) ylittävä
  vastaus tai `2xx`-vastaus, jonka runko ei ole kelvollinen
  määritys, on lopullinen eikä sitä yritetä uudelleen.
- Molemmat yritykset lähettävät saman rungon, saman `X-ThunderPhone-Signature`-otsakkeen
  ja saman `X-ThunderPhone-Idempotency-Key`-otsakkeen
  (`telephony-incoming-<call_id>`), joten sivuvaikutuksia aiheuttava
  käsittelijä voi tunnistaa uudelleenyrityksen.

Varapuheagenttia ei ole. Jos käyttökelpoista määritystä ei saada, puhelu
lopetetaan heti sen sijaan, että soittaja jätettäisiin hiljaiselle
linjalle. Se näkyy puheluhistoriassa epäonnistuneena, laskuttamattomana puheluna, jonka
`end_reason` on `inbound_config_webhook_failed`, ja tavallinen
[`telephony.complete`](/fi/webhooks/call-complete)-tapahtuma lähetetään.

Widget-istunto (`web.incoming`) saa yhden, enintään 10 sekuntia kestävän
yrityksen. Jos se epäonnistuu, istuntopyyntö epäonnistuu koodilla `502` tai `422`.

<Warning>
  **Webhookilla määritetyissä puheluissa ei ole ThunderPhonen
  suostumusilmoitusta.** Tämän vaihdon kautta määritetyt puhelut ohittavat
  agenttitason puhelun aloitusilmoituksen, ja ne on nimenomaisesti rajattu
  ThunderPhonen suostumusilmoituskehyksen ulkopuolelle (käyttöehdot,
  "Tallennus ja suostumus" -osio). Organisaatiosi on yksin vastuussa kaikista
  näissä puheluissa vaadittavista tallennusta, valvontaa, AI-osallistumista ja
  soittajan tunnistamista koskevista ilmoituksista ja suostumuksista —
  puhelut voidaan silti tallentaa, litteroida, analysoida ja palvella AI:n
  avulla. Sisällytä vaaditut ilmoitukset omaan puhelukulkuusi ennen tämän
  polun käyttöönottoa.
</Warning>

## Pyynnön sisältö

Puheluille (`telephony.incoming`):

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

| Kenttä | Tyyppi | Kuvaus |
|-------|------|-------------|
| `call_id` | integer | Puhelutunnus — pysyy samana tämän puhelun kaikissa tapahtumissa |
| `from_number` | string | Soittajan E.164-numero |
| `to_number` | string | Kohteen E.164-numero (yksi ThunderPhone-numeroistasi) |

Web-widget-istunnoissa (`web.incoming`) `data` tunnistaa puhelinnumeroiden
sijaan upottavan sivun:

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

| Kenttä | Tyyppi | Kuvaus |
|-------|------|-------------|
| `call_id` | kokonaisluku | Puhelun tunnus |
| `origin_domain` | merkkijono | Sivun alkuperä, jolla widgetiä isännöidään, selaimen lähettämänä. Muu kuin selainasiakas voi lähettää minkä tahansa arvon, joten älä pidä sitä todisteena siitä, mistä pyyntö tuli |
| `publishable_key_prefix` | merkkijono | Istunnon avanneen julkaistavan avaimen ensimmäiset merkit |
| `language`, `primary_language` | merkkijono | Mukana, kun widget-istunto pyysi kieliohittamista |
| `voice` | merkkijono | Mukana, kun widget-istunto pyysi äänen ohittamista |
| `website_context` | merkkijono | Mukana, kun widget välitti istuntokohtaisen sivukontekstin |

Ohituskentät (`language`, `voice`, `website_context` ja mahdolliset
selaimen `variables`) saapuvat vain, kun julkaistava avain sallii ne
[browser overrides](/fi/guides/embed-web-widget) -asetuksissaan. Istuntopyyntö, joka sisältää avaimen kieltämän ohituksen, hylätään ennen kuin tätä webhookia kutsutaan.

<Note>
  Webhook-tilan widgetit toimittavat tämän pyynnön julkaistavan avaimen
  omaan `webhook_url`-osoitteeseen, kun sellainen on asetettu, ja käyttävät
  muussa tapauksessa organisaatiotason webhook-URL-osoitetta. Molemmissa
  tapauksissa pyyntö allekirjoitetaan organisaation webhookin `secret`-avaimella.
</Note>

---

## Vastausskeema

Palauta JSON-objekti, joka kuvaa tämän puhelun agentin määrityksen.
`prompt` ja `voice` ovat pakollisia; kaikki muu on valinnaista.

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

| Kenttä | Tyyppi | Pakollinen | Kuvaus |
|-------|------|----------|-------------|
| `prompt` | string | kyllä | Agenttia ohjaava järjestelmäkehote |
| `voice` | string | kyllä | Äänitunnus kohteesta [`GET /v1/voices`](/api-reference/agents#voices), esim. `john`. `voice_name` hyväksytään aliaksena. Tuntemattomat äänet eivät läpäise validointia ja puhelu hylätään |
| `product` | string | ei | Oletusarvo on `spark`. Sallitut arvot: `spark`, `bolt`, `storm-base`, `storm-base-with-ack`, `storm-extra`, `storm-extra-with-ack` |
| `thinking_level` | string | ei | `minimal`, `base` (oletus) tai `extra`. Ohitetaan Storm-tuotteissa: `storm-extra*` pakottaa arvon `extra`, muut `storm-*`-tuotteet pakottavat arvon `base` |
| `audio_context_mode` | string | ei | `full` (oletus) tai `reduced` |
| `watchdog_enabled` | boolean | ei | Ota valvonta käyttöön tässä puhelussa. Oletusarvo on `false` |
| `additional_audio_context` | boolean \| null | ei | Sisällytä soittajan äänen viimeiset muutamat vuorot pelkän viimeisimmän vuoron sijaan. Tämä parantaa korjauksia sekä oikeinkirjoitus- ja numeropainotteista tiedonkeruuta pienellä viive- ja kustannuslisällä. Oletusarvoisesti käytössä saapuvissa istunnoissa ja pois käytöstä lähtevissä puheluissa; `null` säilyttää oletusarvon |
| `storm_feedback_mode` | string | ei | `none`, `acknowledgement` (oletus) tai `tick`. Määrittää myös, mitä soittaja kuulee, kun äänimallit käsittelevät vuoroa ja `audio_tier` on `hearing` |
| `language` | string | ei | Lyhenne kentälle `primary_language` |
| `primary_language` | string | ei | Kielikoodi normalisoituna (oletus `en`). Koodit, joita ei voida tulkita, hylkäävät puhelun |
| `has_additional_languages` | boolean | ei | Oletusarvo on `false` |
| `additional_languages` | array of string | ei | Lisäkielet, joihin agentti voi vaihtaa |
| `native_voice_switching` | boolean | ei | Oletusarvo on `false`. Kun puhelu vaihtuu toiseen kieleen, vaihda kyseiselle kielelle natiiviin ääneen (sukupuolen mukaan vastaavaan) määritetyn äänen säilyttämisen sijaan |
| `language_switching` | string \| null | ei | `ask_first` (oletus) tai `follow_caller`; `null` vastaa arvoa `ask_first`. Määrittää, miten monikielinen agentti käsittelee toisen henkilön puhumista jollakin toisella sen kielistä. `ask_first` vaihtaa heti, kun henkilö pyytää kieltä tai sanoo sillä kokonaisen lauseen, ja kysyy jatketaanko sillä, jos henkilö sanoo jotain lyhyttä, kuten "sí". `follow_caller` vaihtaa mihin tahansa määritettyyn kieleen, jota henkilö puhuu, vaikka kyse olisi vain yhdestä sanasta. Koskee vain tilanteita, joissa `additional_languages` on asetettu |
| `audio_tier` | string \| null | ei | Vain `product: "bolt"`. `standard` (oletus; `""` ja `null` tarkoittavat samaa) käyttää kolmea litteroijaa (PHI:tä käsittelevät puhelut käyttävät vain BAA-sopimuksen kattamia litteroijia). `lean` vähentää käytön yhteen litteroijaan, joka kuulee väärin useammin. `hearing` päivittää asetuksen tasolle `standard` ja lisää tehokkaan äänimallikokonaisuuden, joka kuuntelee soittajan ääntä joillakin vuoroilla. Nämä vuorot kestävät noin 1–2 sekuntia pidempään. Muut tuotteet ohittavat tämän |
| `endpointing` | string \| null | ei | `faster` (200 ms), `fast` (300 ms), `normal` (500 ms, oletus) tai `patient` (800 ms); `null` vastaa arvoa `normal`. Määrittää, kuinka kauan Bolt v2 -agentti odottaa soittajan lopetettua puhumisen ennen kuin se pyytää mallilta vastausta. Lyhyemmät odotusajat voivat vastata nopeammin, mutta lähettävät enemmän pyyntöjä, jotka soittajan seuraavat sanat vanhentavat, mikä kasvattaa mallin kustannuksia. Muut tuotteet ohittavat tämän |
| `eagerness` | string \| null | ei | Vanhentunut: `endpointing`-kentän nimi 19. lokakuuta 2026 asti, mutta luetaan edelleen. Ohitetaan, kun `endpointing` on asetettu |
| `intelligence` | string \| null | ei | `express`, `lite` tai `standard` (oletus); `null` vastaa arvoa `standard`. `bolt`-agentin älykkyystaso Bolt v2 -putkessa: mikä malli kirjoittaa sen vastaukset. `express` on noin 600 ms ensimmäiseen sanaan, edullisempi kuin Standard ja noudattaa ohjeita vähiten luotettavasti; `lite` on noin 900 ms, halvin ja vähemmän luotettava; `standard` on noin 900 ms ja noudattaa ohjeita parhaiten. Express- ja Lite-vastaukset, jotka kutsuisivat vain työkalua, ohjataan Standard-mallille. Muut tuotteet ohittavat tämän |
| `background_track` | string \| null | ei | Taustaäänen tunnus tai `null` |
| `acknowledgement_prompt_mode` | string | ei | `auto` (oletus) tai `manual` (Storm-with-ack-tuotteet) |
| `acknowledgement_prompt` | string | ei | Käytetään, kun `acknowledgement_prompt_mode="manual"` |
| `silence_interval_seconds` | integer \| null | ei | 5–120. Soittajan hiljaisuuden sekunnit ennen yhteydenottoa |
| `silence_max_checkins` | integer \| null | ei | 1–10 |
| `silence_checkins_enabled` | boolean | ei | Oletusarvo on `true` |
| `silence_final_action` | string | ei | Viimeisen yhteydenoton jälkeen: `hang_up` (oletus) tai `transfer` kohteeseen `silence_transfer_destination` |
| `silence_transfer_destination` | string | ei | Tämän määrityksen `transfer_destinations`-luettelon merkinnän nimi; pakollinen arvon `transfer` kanssa. Ilman `transfer_destinations`-asetusta siirtoa ei voi tehdä, ja agentti katkaisee puhelun |
| `silence_final_message` | string | ei | ≤ 300 merkkiä, luetaan kirjoitetussa muodossa; `""` (oletus) käyttää oletusriviä |
| `connect_tone_enabled` | boolean | ei | Oletusarvo on `false` |
| `pronunciation_dicts` | boolean \| null | ei | Oletusarvo on `false`; `null` vastaa arvoa `false`. Kun arvo on `true`, puhelun Cartesia-puhe käyttää ThunderPhonen ääntämissanakirjaa puhelun kielelle, jos sellainen on saatavilla. Toimii puhelin- ja widget-puheluissa. Koskee vain ThunderPhonen omia Cartesia-ääniä, ei omalla Cartesia API -avaimellasi olevia ääniä. Ei käytetä asetuksen `agent_id` kanssa, jolloin tallennetun agentin asetuksia käytetään |
| `voicemail_action` | string | ei | `prompt` (oletus), `hangup` tai `message` |
| `voicemail_message` | string | ei | Käytetään, kun `voicemail_action="message"` |
| `agent_name` | string | ei | Näyttönimi, joka ilmoitetaan koontinäytöille ja widgetille |
| `org_name` | string | ei | Organisaation näyttönimi agentin personaa varten |
| `tools` | array | ei | Upotetut funktiotyökalujen skeemat (katso [Funktiotyökalut](/fi/tools/overview)) |
| `transfer_destinations` | array of object \| null | ei | Enintään 50 `{name, number}`-merkintää, joihin tämä puhelu voidaan siirtää. Ne validoidaan kuten agentin [siirtonumerot](/api-reference/agents#transfer-numbers). Agentti siirtää nimen perusteella ja vain näihin kohteisiin; `[]` tarkoittaa, ettei siirtoja ole. Jätä pois tai lähetä `null`, jotta agentti voi siirtää valitsemaansa numeroon |
| `timezone` | string | ei | Tämän puhelun IANA-aikavyöhyke, kuten `America/Chicago`. Agentti ilmoittaa päivämäärän ja kellonajan tällä aikavyöhykkeellä oman aikavyöhykkeensä sijaan. Sallitaan myös `agent_id`-kentän yhteydessä. Arvot, jotka eivät ole IANA-aikavyöhykkeitä, ohitetaan. Katso [Aseta aikavyöhyke puhelukohtaisesti](/fi/guides/dynamic-call-config) |
| `call_id` | integer | ei | Pyynnön puhelutunnuksen valinnainen kaiku; ohitetaan |

<Note>
  Tuntemattomat ylimmän tason avaimet **ohitetaan** hiljaisesti — kirjoitusvirheellinen kentän
  nimi ei hylkää määritystä, mutta sitä ei käytetä. Puhejärjestystä
  ja `max_hold_seconds` ei hyväksytä täällä; ne voidaan
  määrittää vain itse [Agentille](/api-reference/agents).
</Note>

Koska `prompt` ja `voice` ovat pakollisia, arvon `{}` tai minkä tahansa
validoinnissa epäonnistuvan vastauksen palauttaminen hylkää puhelun: puhelu päätetään
kohdassa [Aikakatkaisut ja uudelleenyritykset](#timeouts-and-retries) kuvatulla tavalla, ja
pienoisohjelmaistunnon pyyntö epäonnistuu koodilla `422`. Tällä polulla ei ole
staattisen agentin varavaihtoehtoa (webhook-tilassa olevalla numerolla tai avaimella ei ole määritettyä
agenttia).

---

## Vastauksen kokorajoitus

<Warning>
  Määritysvastausten koko on rajoitettu arvoon **5 MiB**. Jos käsittelijä
  palauttaa suuremman vastauksen, myös `2xx`-tilakoodilla,
  ThunderPhone ilmoittaa vastauksen ylittäneen rajan ja
  hylkää puhelun tai widget-istunnon. Säilytä vastauksessa vain
  puhelun määrittämiseen tarvittavat kentät; isännöi suuret tiedot
  toimintotyökalujen tai muun palvelun takana sen sijaan, että upottaisit ne määritykseen.
</Warning>

---

## Esimerkkikäsittelijä

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

---

## Vastaus toimintotyökaluilla

Liitä työkaluja, jotta tekoäly voi kutsua rajapintojasi keskustelun aikana:

```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>
  Työkalun päätepistepyynnöt allekirjoitetaan **samalla organisaation webhook-salaisuudella**,
  jolla tämä vaihto allekirjoitettiin. Katso tarkka rakenne ja allekirjoitetun
  pyynnön muoto kohdasta
  [Toimintotyökalut](/fi/tools/overview).
</Tip>

---

## Tuotetason pikaopas

| Tuote | Viive | Päättely | Kuittaus |
|---------|---------|-----------|-----------------|
| `spark` | Pienin | Perustaso | — |
| `bolt` | Matala | Parannettu | — |
| `storm-base` | Keskitaso | Vahva | — |
| `storm-base-with-ack` | Keskitaso | Vahva | Automaattinen täytesana ajattelun aikana |
| `storm-extra` | Korkeampi | Syvällinen | — |
| `storm-extra-with-ack` | Korkeampi | Syvällinen | Automaattinen täytesana ajattelun aikana |

---

## Aiheeseen liittyvät

<CardGroup cols={2}>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/fi/webhooks/call-complete">
    Estämätön puhelun päättymistapahtuma.
  </Card>
  <Card title="Toimintotyökalut" icon="screwdriver-wrench" href="/fi/tools/overview">
    Täydellinen JSON-skeema kohteelle `tools[]` ja allekirjoitettu päätepistesopimus.
  </Card>
  <Card title="Webhook-päätepisteet" icon="bolt" href="/fi/webhooks/endpoints">
    Tilaa useita URL-osoitteita tapahtumille `telephony.incoming` / `web.incoming`.
  </Card>
  <Card title="Dynaaminen puhelukonfiguraatio" icon="wand-magic-sparkles" href="/fi/guides/dynamic-call-config">
    Mallit soittajakohtaisille kehotteille, työkaluille ja A/B-testeille.
  </Card>
</CardGroup>
