---
title: "telephony.incoming / web.incoming"
description: "Webhook αποκλεισμού που διαμορφώνει τη ρύθμιση μιας εισερχόμενης κλήσης σε πραγματικό χρόνο."
---

Όταν μια εισερχόμενη τηλεφωνική κλήση φτάνει σε έναν αριθμό **χωρίς ανατεθειμένο
πράκτορα**, ή όταν ξεκινά μια συνεδρία γραφικού στοιχείου ιστού με ένα δημοσιεύσιμο κλειδί σε
`mode="webhook"`, το ThunderPhone στέλνει ένα **δεσμευτικό**
αίτημα `telephony.incoming` / `web.incoming` στο
[παλαιό URL webhook](/api-reference/organizations#legacy-single-url-webhook)
σας και περιμένει έως **10 δευτερόλεπτα** για μια απάντηση διαμόρφωσης. Χρησιμοποιήστε αυτή την
ανταλλαγή για να επιλέγετε δυναμικά ένα prompt, φωνή και εργαλεία ανά κλήση —
δείτε τον [οδηγό δυναμικής διαμόρφωσης κλήσεων](/el/guides/dynamic-call-config)
για την ολοκληρωμένη ροή.

<Note>
  Τα εγγεγραμμένα [endpoint webhook](/el/webhooks/endpoints) λαμβάνουν επίσης
  `telephony.incoming` / `web.incoming` — για **κάθε** εισερχόμενη κλήση
  και συνεδρία ιστού, ανεξάρτητα από το αν έχει διαμορφωθεί πράκτορας — όμως αυτές οι παραδόσεις
  είναι ειδοποιήσεις fire-and-forget με `event_id`, ποτέ δεσμευτικές.
  Μόνο το παλαιό webhook ενός URL μεταφέρει την ανταλλαγή διαμόρφωσης
  αυτής της σελίδας. Τα σχήματα ειδοποιήσεων endpoint βρίσκονται στον
  [κατάλογο συμβάντων](/el/webhooks/events).
</Note>

Η δεσμευτική ανταλλαγή δεν διαθέτει εναλλακτική: αν ο χειριστής σας επιστρέψει κατάσταση
εκτός 2xx, λήξει το χρονικό όριο ή επιστρέψει διαμόρφωση που αποτυγχάνει στην επικύρωση,
η κλήση απορρίπτεται (η τηλεφωνική κλήση δεν συνδέεται· το αίτημα συνεδρίας του γραφικού στοιχείου
αποτυγχάνει με `502`/`422`). Απαντήστε γρήγορα — ο καλών ακούει τόνο αναμονής όσο
αποφασίζετε.

<Warning>
  **Οι κλήσεις που διαμορφώνονται μέσω webhook δεν περιλαμβάνουν ανακοίνωση συναίνεσης
  του ThunderPhone.** Οι κλήσεις που διαμορφώνονται μέσω αυτής της ανταλλαγής παρακάμπτουν την
  ανακοίνωση έναρξης κλήσης σε επίπεδο πράκτορα και εξαιρούνται ρητά από το πλαίσιο
  ανακοινώσεων συναίνεσης του ThunderPhone (Όροι Παροχής Υπηρεσιών,
  ενότητα «Καταγραφή και συναίνεση»). Ο οργανισμός σας είναι αποκλειστικά
  υπεύθυνος για κάθε ειδοποίηση και συναίνεση σχετικά με καταγραφή, παρακολούθηση,
  συμμετοχή AI και αναγνώριση καλούντος που απαιτείται σε αυτές τις κλήσεις —
  οι κλήσεις εξακολουθούν να μπορούν να καταγράφονται, να απομαγνητοφωνούνται, να αναλύονται
  και να εξυπηρετούνται από AI. Ενσωματώστε τις απαιτούμενες γνωστοποιήσεις στη δική σας ροή κλήσεων πριν
  ενεργοποιήσετε αυτή τη διαδρομή.
</Warning>

## Ωφέλιμο φορτίο αιτήματος

Για τηλεφωνικές κλήσεις (`telephony.incoming`):

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

| Πεδίο | Τύπος | Περιγραφή |
|-------|------|-------------|
| `call_id` | integer | ID κλήσης — σταθερό σε όλα τα συμβάντα αυτής της κλήσης |
| `from_number` | string | Αριθμός καλούντος E.164 |
| `to_number` | string | Προορισμός E.164 (ένας από τους αριθμούς ThunderPhone σας) |

Για συνεδρίες γραφικού στοιχείου ιστού (`web.incoming`), το `data` αναγνωρίζει τη
σελίδα ενσωμάτωσης αντί για τηλεφωνικούς αριθμούς:

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

| Πεδίο | Τύπος | Περιγραφή |
|-------|------|-------------|
| `call_id` | integer | ID κλήσης |
| `origin_domain` | string | Η προέλευση της σελίδας που φιλοξενεί το γραφικό στοιχείο |
| `publishable_key_prefix` | string | Πρώτοι χαρακτήρες του δημοσιεύσιμου κλειδιού που άνοιξε τη συνεδρία |
| `language`, `primary_language` | string | Παρόν όταν η συνεδρία γραφικού στοιχείου ζήτησε παράκαμψη γλώσσας |
| `voice` | string | Παρόν όταν η συνεδρία γραφικού στοιχείου ζήτησε παράκαμψη φωνής |
| `website_context` | string | Παρόν όταν το γραφικό στοιχείο πέρασε περιεχόμενο σελίδας ανά συνεδρία |

<Note>
  Τα γραφικά στοιχεία σε λειτουργία webhook παραδίδουν αυτό το αίτημα στο
  δικό τους `webhook_url` του δημοσιεύσιμου κλειδιού όταν έχει οριστεί, με
  εναλλακτική το URL webhook σε επίπεδο οργανισμού. Και στις δύο περιπτώσεις υπογράφεται με το `secret`
  webhook του οργανισμού.
</Note>

---

## Σχήμα απόκρισης

Επιστρέψτε ένα αντικείμενο JSON που περιγράφει τη διαμόρφωση του πράκτορα για αυτή την κλήση.
Τα `prompt` και `voice` είναι υποχρεωτικά· όλα τα υπόλοιπα είναι προαιρετικά.

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

| Πεδίο | Τύπος | Υποχρεωτικό | Περιγραφή |
|-------|------|----------|-------------|
| `prompt` | string | ναι | Προτροπή συστήματος που καθοδηγεί τον πράκτορα |
| `voice` | string | ναι | Αναγνωριστικό φωνής από το [`GET /v1/voices`](/api-reference/agents#voices), π.χ. `john`. Το `voice_name` γίνεται δεκτό ως ψευδώνυμο. Άγνωστες φωνές αποτυγχάνουν στην επικύρωση και απορρίπτουν την κλήση |
| `product` | string | όχι | Προεπιλογή: `spark`. Επιτρεπόμενα: `spark`, `bolt`, `storm-base`, `storm-base-with-ack`, `storm-extra`, `storm-extra-with-ack` |
| `thinking_level` | string | όχι | `minimal`, `base` (προεπιλογή) ή `extra`. Παρακάμπτεται για προϊόντα Storm: το `storm-extra*` επιβάλλει `extra`, ενώ τα άλλα `storm-*` επιβάλλουν `base` |
| `audio_context_mode` | string | όχι | `full` (προεπιλογή) ή `reduced` |
| `watchdog_enabled` | boolean | όχι | Ενεργοποίηση επιτήρησης για αυτή την κλήση. Προεπιλογή: `false` |
| `additional_audio_context` | boolean \| null | όχι | Συμπεριλάβετε τις τελευταίες λίγες εναλλαγές ήχου του καλούντος αντί μόνο της πιο πρόσφατης, βελτιώνοντας τις διορθώσεις και τη συλλογή δεδομένων με πολλά ορθογραφικά στοιχεία ή αριθμούς, με μικρή επιβάρυνση καθυστέρησης/κόστους. Ενεργοποιείται από προεπιλογή για εισερχόμενες συνεδρίες και απενεργοποιείται για εξερχόμενες τηλεφωνικές κλήσεις· το `null` διατηρεί την προεπιλογή |
| `storm_feedback_mode` | string | όχι | `none`, `acknowledgement` (προεπιλογή) ή `tick` |
| `language` | string | όχι | Συντομογραφία για το `primary_language` |
| `primary_language` | string | όχι | Κωδικός γλώσσας, κανονικοποιημένος (προεπιλογή `en`). Κωδικοί που δεν μπορούν να επιλυθούν απορρίπτουν την κλήση |
| `has_additional_languages` | boolean | όχι | Προεπιλογή: `false` |
| `additional_languages` | array of string | όχι | Επιπλέον γλώσσες στις οποίες μπορεί να μεταβεί ο πράκτορας |
| `native_voice_switching` | boolean | όχι | Προεπιλογή: `false`. Όταν η κλήση μεταβαίνει σε άλλη γλώσσα, αλλάζει σε φωνή μητρική σε εκείνη τη γλώσσα (αντιστοιχισμένη κατά φύλο), αντί να διατηρεί τη διαμορφωμένη φωνή |
| `background_track` | string \| null | όχι | Αναγνωριστικό ήχου περιβάλλοντος ή `null` |
| `acknowledgement_prompt_mode` | string | όχι | `auto` (προεπιλογή) ή `manual` (προϊόντα Storm-with-ack) |
| `acknowledgement_prompt` | string | όχι | Χρησιμοποιείται όταν `acknowledgement_prompt_mode="manual"` |
| `silence_interval_seconds` | integer \| null | όχι | 5–120. Δευτερόλεπτα σιωπής του καλούντος πριν από έλεγχο |
| `silence_max_checkins` | integer \| null | όχι | 1–10 |
| `silence_checkins_enabled` | boolean | όχι | Προεπιλογή: `true` |
| `connect_tone_enabled` | boolean | όχι | Προεπιλογή: `false` |
| `voicemail_action` | string | όχι | `prompt` (προεπιλογή), `hangup` ή `message` |
| `voicemail_message` | string | όχι | Χρησιμοποιείται όταν `voicemail_action="message"` |
| `agent_name` | string | όχι | Εμφανιζόμενο όνομα που αναφέρεται στους πίνακες ελέγχου και στο γραφικό στοιχείο |
| `org_name` | string | όχι | Εμφανιζόμενο όνομα οργανισμού για την περσόνα του πράκτορα |
| `tools` | array | όχι | Ενσωματωμένα σχήματα εργαλείων συναρτήσεων (δείτε [Εργαλεία Συναρτήσεων](/el/tools/overview)) |
| `call_id` | integer | όχι | Προαιρετική επανάληψη του αναγνωριστικού κλήσης του αιτήματος· αγνοείται |

<Note>
  Άγνωστα κλειδιά ανώτατου επιπέδου **αγνοούνται** σιωπηρά — ένα πεδίο
  με ορθογραφικό λάθος δεν απορρίπτει τη διαμόρφωση, απλώς δεν εφαρμόζεται. Η σειρά
  ομιλίας και το `max_hold_seconds` δεν γίνονται δεκτά εδώ· είναι
  διαμορφώσιμα μόνο στον ίδιο τον [Πράκτορα](/api-reference/agents).
</Note>

Επειδή τα `prompt` και `voice` είναι υποχρεωτικά, η επιστροφή `{}` ή οποιασδήποτε
απόκρισης που αποτυγχάνει στην επικύρωση απορρίπτει την κλήση με `422` — δεν υπάρχει
εναλλακτική λύση στατικού πράκτορα σε αυτή τη διαδρομή (ένας αριθμός ή κλειδί σε λειτουργία webhook
δεν έχει εκχωρημένο πράκτορα).

---

## Όριο μεγέθους απόκρισης

<Warning>
  Οι αποκρίσεις διαμόρφωσης περιορίζονται σε **5 MiB**. Αν ένας χειριστής
  επιστρέψει μεγαλύτερη απόκριση, ακόμη και με κατάσταση `2xx`,
  το ThunderPhone αναφέρει ότι η απόκριση υπερέβη το όριο και
  απορρίπτει την κλήση ή τη συνεδρία widget. Περιορίστε την απόκριση στα πεδία
  που απαιτούνται για τη ρύθμιση της κλήσης· φιλοξενήστε μεγάλα δεδομένα πίσω από
  εργαλεία συναρτήσεων ή άλλη υπηρεσία αντί να τα ενσωματώνετε στη διαμόρφωση.
</Warning>

---

## Παράδειγμα χειριστή

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

---

## Απόκριση με εργαλεία συναρτήσεων

Επισυνάψτε εργαλεία ώστε ο AI πράκτορας να μπορεί να καλεί τα API σας κατά τη διάρκεια της συνομιλίας:

```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>
  Τα αιτήματα προς τελικά σημεία εργαλείων υπογράφονται με το **ίδιο μυστικό
  webhook του οργανισμού** που υπέγραψε αυτή την ανταλλαγή. Δείτε τα
  [Εργαλεία συναρτήσεων](/el/tools/overview) για την ακριβή δομή και τη μορφή
  υπογεγραμμένου αιτήματος.
</Tip>

---

## Συνοπτικός οδηγός επιπέδων προϊόντος

| Προϊόν | Καθυστέρηση | Συλλογισμός | Επιβεβαίωση |
|---------|---------|-----------|-----------------|
| `spark` | Η χαμηλότερη | Βασικός | — |
| `bolt` | Χαμηλή | Βελτιωμένος | — |
| `storm-base` | Μέτρια | Ισχυρός | — |
| `storm-base-with-ack` | Μέτρια | Ισχυρός | Αυτόματο συμπλήρωμα κατά τη σκέψη |
| `storm-extra` | Υψηλότερη | Βαθύς | — |
| `storm-extra-with-ack` | Υψηλότερη | Βαθύς | Αυτόματο συμπλήρωμα κατά τη σκέψη |

---

## Σχετικά

<CardGroup cols={2}>
  <Card title="telephony.complete / web.complete" icon="phone-slash" href="/el/webhooks/call-complete">
    Το μη αποκλειστικό συμβάν ολοκλήρωσης κλήσης.
  </Card>
  <Card title="Εργαλεία συναρτήσεων" icon="screwdriver-wrench" href="/el/tools/overview">
    Πλήρες σχήμα JSON για `tools[]` και το συμβόλαιο του υπογεγραμμένου endpoint.
  </Card>
  <Card title="Τελικά σημεία webhook" icon="bolt" href="/el/webhooks/endpoints">
    Εγγράψτε πολλαπλά URL στα `telephony.incoming` / `web.incoming`.
  </Card>
  <Card title="Δυναμική διαμόρφωση κλήσης" icon="wand-magic-sparkles" href="/el/guides/dynamic-call-config">
    Μοτίβα για προτροπές, εργαλεία και δοκιμές A/B ανά καλούντα.
  </Card>
</CardGroup>
