Telofy
Telofy là lễ tân điện thoại AI dành cho doanh nghiệp tại Đức, từ hộ kinh doanh cá thể đến doanh nghiệp vừa. Dịch vụ trả lời cuộc gọi trên số điện thoại hiện có bất cứ khi nào không có ai nhấc máy, làm rõ yêu cầu của người gọi, đặt, đổi lịch hoặc hủy lịch hẹn qua cal.com (cũng kết nối lịch Google và Outlook), nhận đơn hàng và chuyển tiếp các cuộc gọi khẩn cấp đến một số điện thoại theo quy tắc. Sau mỗi cuộc gọi, một bản tóm tắt sẵn sàng để xử lý xuất hiện trong cổng thông tin và doanh nghiệp được thông báo qua e-mail, Telegram hoặc push. 30 giọng nói, hơn 20 ngôn ngữ, mẫu hội thoại cho 62 ngành nghề, API mở, webhook có chữ ký và một máy chủ MCP. Người gọi được thông báo rằng họ đang nói chuyện với AI, không lưu trữ âm thanh và dữ liệu được xử lý tại EU. Các gói bắt đầu từ 79 EUR mỗi tháng khi thanh toán theo năm.
Tài liệu
Telofy für Entwickler.
Schnittstelle, Webhooks und MCP: Anrufe, Anliegen und Termine holen, Ereignisse sicher empfangen, KI-Assistenten anbinden. Basis-Adresse https://api.telofy.app.
Überblick
Die Telofy-Schnittstelle richtet sich an Server, nicht an Browser. Sie ist für den Zugriff von Ihrer Software, Ihrer Agentur oder Ihrem KI-Assistenten gedacht. Browser-Zugriff (CORS) ist nicht vorgesehen.
| Basis-Adresse | https://api.telofy.app |
| Format | JSON, UTF-8 |
| Anmeldung | Authorization: Bearer tlfy_… |
| Lesen | Anrufe, Anliegen, Termine |
| Schreiben | Ausgehenden Anruf auslösen (ab Business) |
| Ratenlimit | 60 Anfragen pro Minute und Schlüssel |
| Ereignisse | Webhooks, signiert |
| KI-Assistenten | MCP, Streamable HTTP unter /mcp |
Eine OpenAPI-Beschreibung gibt es derzeit nicht. Diese Seite ist die Referenz. Sie gibt es auch als reinen Markdown-Text unter /entwickler.md.
Authentifizierung
Jede Anfrage trägt einen API-Schlüssel im Kopf-Feld Authorization.
Authorization: Bearer tlfy_IhrSchluessel
- Einen Schlüssel erstellen Sie im Portal unter Integrationen > API-Schlüssel (Knopf „Schlüssel erstellen“). Er beginnt mit
tlfy_und wird nur einmal vollständig angezeigt. Bewahren Sie ihn wie ein Passwort auf. - Es sind bis zu drei aktive Schlüssel möglich. Ein widerrufener Schlüssel funktioniert nicht mehr.
- Der Betrieb, auf den sich eine Anfrage bezieht, ergibt sich allein aus dem Schlüssel. Eine Angabe in der Anfrage kann ihn nicht ändern.
- Ab Werk liest ein Schlüssel nur. Beim Anlegen können Sie drei Rechte zusätzlich ankreuzen: „Anrufe auslösen“ (ab Business), „Kundenstamm lesen und bearbeiten“ (ab Pro) und „Abwesenheiten bearbeiten“. Geben Sie ihn nur an Systeme, denen Sie das Angekreuzte zutrauen.
- Fehlt der Schlüssel, ist er falsch oder widerrufen, antwortet Telofy immer gleich:
{ "error": "unauthorized" }
Endpunkte
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /api/v1/calls | Anrufe, neueste zuerst |
| GET | /api/v1/outcomes | Anliegen aus Anrufen: Lead, Ticket, Termin, Auskunft, Bestellung, Sonstiges |
| GET | /api/v1/appointments | Nur Anliegen vom Typ Termin |
| POST | /api/v1/outbound-calls | Ausgehenden Anruf auslösen (ab Business) |
| GET, POST, DELETE | /api/v1/contacts, /api/v1/absences (und /batch, /{id}) | Kundenstamm und Abwesenheiten, siehe unten (Zusatzrechte) |
| POST | /mcp | MCP für KI-Assistenten |
Anrufe abrufen
GET /api/v1/calls
curl -H "Authorization: Bearer tlfy_IhrSchluessel" "https://api.telofy.app/api/v1/calls?limit=2"
{
"page": 1,
"limit": 2,
"calls": [
{
"id": "call_9f2a1b",
"startedAt": "2026-07-14T10:15:00.000Z",
"endedAt": "2026-07-14T10:19:30.000Z",
"direction": "inbound",
"status": "completed",
"callerNumber": "+4930555099",
"durationSeconds": 270,
"summary": "Anrufer möchte einen Termin für nächsten Dienstag.",
"outcomeType": "appointment",
"employeeName": "Anna"
},
{
"id": "call_3c7d2e",
"startedAt": "2026-07-14T09:00:00.000Z",
"endedAt": "2026-07-14T09:04:12.000Z",
"direction": "inbound",
"status": "completed",
"callerNumber": "+4930555010",
"durationSeconds": 252,
"summary": "Anrufer fragt nach Öffnungszeiten am Samstag.",
"outcomeType": "lead",
"employeeName": "Anna"
}
]
}
| Feld | Bedeutung |
|---|---|
id | Kennung des Anrufs |
startedAt, endedAt | Beginn und Ende, ISO 8601 |
direction | inbound oder outbound |
status | Status des Anrufs, zum Beispiel completed |
callerNumber | Rufnummer des Anrufers |
durationSeconds | Dauer in Sekunden |
summary | Zusammenfassung des Gesprächs |
outcomeType | Art des Anliegens, falls eines entstand |
employeeName | Name des Mitarbeiters, der den Anruf geführt hat |
Das Gesprächsprotokoll ist nicht Teil der Antwort. Es steht nur im Portal und nur, wenn Sie es dort eingeschaltet haben.
Anliegen abrufen
GET /api/v1/outcomes
curl -H "Authorization: Bearer tlfy_IhrSchluessel" "https://api.telofy.app/api/v1/outcomes?limit=2"
{
"page": 1,
"limit": 2,
"outcomes": [
{
"id": "outcome_7b1a4c",
"type": "appointment",
"title": "Termin am Dienstag, 10:00 Uhr",
"structuredData": {
"requestedTime": "2026-07-21T10:00:00.000Z",
"contactName": "Frau Beispiel"
},
"createdAt": "2026-07-14T10:19:35.000Z",
"callId": "call_9f2a1b",
"callerNumber": "+4930555099",
"callStartedAt": "2026-07-14T10:15:00.000Z",
"callSummary": "Anrufer möchte einen Termin für nächsten Dienstag.",
"handlingStatus": "open"
},
{
"id": "outcome_2e9f31",
"type": "lead",
"title": "Interesse an Beratungstermin",
"structuredData": {
"interesse": "Erstberatung"
},
"createdAt": "2026-07-14T09:04:20.000Z",
"callId": "call_3c7d2e",
"callerNumber": "+4930555010",
"callStartedAt": "2026-07-14T09:00:00.000Z",
"callSummary": "Anrufer fragt nach Öffnungszeiten am Samstag.",
"handlingStatus": "open"
}
]
}
| Feld | Bedeutung |
|---|---|
type | lead, ticket, appointment, info, other, order oder emergency |
title | Kurzer Titel des Anliegens |
structuredData | Erfasste Angaben. Die Felder hängen von der Art des Anliegens ab |
callId | Verweis auf den Anruf |
handlingStatus | Bearbeitungsstand im Portal: open (offen), in Arbeit oder erledigt |
Termine abrufen
GET /api/v1/appointments
Wie /api/v1/outcomes, aber auf Anliegen vom Typ Termin beschränkt. Die Liste heißt in der Antwort appointments.
curl -H "Authorization: Bearer tlfy_IhrSchluessel" "https://api.telofy.app/api/v1/appointments"
{
"page": 1,
"limit": 50,
"appointments": [
{
"id": "outcome_7b1a4c",
"type": "appointment",
"title": "Termin am Dienstag, 10:00 Uhr",
"structuredData": {
"requestedTime": "2026-07-21T10:00:00.000Z",
"contactName": "Frau Beispiel"
},
"createdAt": "2026-07-14T10:19:35.000Z",
"callId": "call_9f2a1b",
"callerNumber": "+4930555099",
"callStartedAt": "2026-07-14T10:15:00.000Z",
"callSummary": "Anrufer möchte einen Termin für nächsten Dienstag.",
"handlingStatus": "open"
}
]
}
Kundenstamm und Abwesenheiten
Beide Bereiche brauchen ein Zusatzrecht am Schlüssel, das Sie beim Anlegen im Portal ankreuzen. Ab Werk ist es aus. Kundenstamm (auch Lesen): Recht „Kundenstamm lesen und bearbeiten“, ab dem Tarif Pro. Abwesenheiten: Lesen mit jedem Schlüssel, Anlegen und Löschen mit dem Recht „Abwesenheiten bearbeiten“.
| Methode | Pfad | Zweck |
|---|---|---|
| GET | /api/v1/contacts | Kontakte; Filter phone, q (Name oder Firma), page, limit |
| POST | /api/v1/contacts | Kontakt anlegen (201) oder den mit gleicher Rufnummer ändern (200); nicht angegebene Felder bleiben unverändert |
| POST | /api/v1/contacts/batch | Bis zu 100 Kontakte, Ergebnis je Zeile |
| DELETE | /api/v1/contacts/{id} | Kontakt löschen (204) |
| GET | /api/v1/absences | Abwesenheiten; Filter from, to (JJJJ-MM-TT) |
| POST | /api/v1/absences | Abwesenheit eintragen (201) |
| DELETE | /api/v1/absences/{id} | Abwesenheit löschen (204) |
Ein Kontakt braucht phone und mindestens firstName, lastName oder company; optional sind salutation („Herr“ oder „Frau“), email und note. Die Rufnummer darf international (+491701234567) oder national (0170 1234567) geschrieben sein. Beim Ändern eines vorhandenen Kontakts bleiben nicht angegebene Felder unverändert; null oder ein leerer Text löscht ein Feld. Vorname, Nachname und Firma lassen sich nicht alle zugleich löschen (Fehler name_required). Im Filter phone kodieren Sie das Pluszeichen als %2B (ein unkodiertes + wird toleriert).
curl -X POST -H "Authorization: Bearer tlfy_IhrSchluessel" -H "Content-Type: application/json" \
-d '{"phone": "0170 1234567", "firstName": "Anna", "lastName": "Sommer", "company": "Sommer Gartenbau"}' \
"https://api.telofy.app/api/v1/contacts"
{
"contact": {
"id": "contact_4d8e1a",
"phone": "+491701234567",
"salutation": null,
"firstName": "Anna",
"lastName": "Sommer",
"company": "Sommer Gartenbau",
"email": null,
"note": null,
"origin": "api",
"confirmed": true
}
}
Eine Abwesenheit hat kind (closed oder modified_hours), startDate, endDate, reason und bei modified_hours openTime und closeTime (HH:MM). Die Antwort enthält zusätzlich conflictingReservationsCount, die Zahl bereits gebuchter Termine im Zeitraum. Überschneidet sich der Zeitraum mit einer vorhandenen Abwesenheit, antwortet Telofy mit 409 absence_overlaps und nennt existingId.
curl -X POST -H "Authorization: Bearer tlfy_IhrSchluessel" -H "Content-Type: application/json" \
-d '{"kind": "closed", "startDate": "2026-12-24", "endDate": "2026-12-31", "reason": "Betriebsferien"}' \
"https://api.telofy.app/api/v1/absences"
Weitere Fehlercodes: 403 scope_missing (Recht fehlt), 403 plan_not_eligible (Kundenstamm unter Pro), 409 data_limit_reached (Datentopf des Tarifs voll), 503 writes_disabled (Schreiben vorübergehend gesperrt), 400 name_required, invalid_email, invalid_absence, invalid_date, too_many_items.
Paginierung
Alle Listen liefern die neuesten Einträge zuerst.
pagebeginnt bei 1 (Vorgabe 1).limitist 50 (Vorgabe) und höchstens 100.- Die Antwort enthält
pageundlimit, aber keinen Gesamtzähler und keinen Cursor. Blättern Sie weiter, bis eine Seite weniger Einträge alslimitliefert. - Filterparameter gibt es nicht. Es werden nur
pageundlimitgelesen.
curl -H "Authorization: Bearer tlfy_IhrSchluessel" "https://api.telofy.app/api/v1/calls?page=2&limit=25"
Ratenlimit
Pro Schlüssel sind 60 Anfragen pro Minute erlaubt, zusammengezählt über alle Endpunkte und alle MCP-Aufrufe. Gezählt wird erst nach erfolgreicher Anmeldung. Wird das Limit überschritten, antwortet Telofy bis zum Ende der Minute mit Status 429:
{ "error": "rate_limited" }
Warten Sie nach einer 429-Antwort kurz, bevor Ihr Programm es erneut versucht.
Fehlercodes
Fehler kommen als JSON mit dem Feld error, zum Beispiel { "error": "unauthorized" }.
| Status | error | Bedeutung |
|---|---|---|
| 400 | invalid_request, purpose_required, invalid_number, employee_id_required | Die Anfrage ist unvollständig oder fehlerhaft |
| 401 | unauthorized | Schlüssel fehlt, ist falsch oder widerrufen |
| 403 | plan_not_eligible, scope_missing | Die Funktion gibt es im aktuellen Tarif nicht, oder dem Schlüssel fehlt das Recht |
| 404 | not_found, employee_not_found | Pfad unbekannt, oder die employeeId passt zu keinem Mitarbeiter |
| 405 | method_not_allowed | Falsche Methode. Der Kopf Allow nennt die erlaubte |
| 409 | duplicate_external_reference, data_limit_reached, absence_overlaps | Die externalReference wurde schon verwendet, der Datentopf ist voll, oder die Abwesenheit überschneidet sich |
| 429 | rate_limited | Mehr als 60 Anfragen in einer Minute |
| 500 | internal_error | Fehler bei Telofy |
| 503 | writes_disabled | Schreiben auf Abwesenheiten vorübergehend gesperrt |
| 502 | provider_request_failed | Der Anruf konnte technisch nicht gestartet werden |
Ausgehender Anruf
POST /api/v1/outbound-calls. Verfügbar ab dem Tarif Business. In anderen Tarifen antwortet Telofy mit 403 plan_not_eligible.
| Feld | Pflicht | Bedeutung |
|---|---|---|
toNumber | ja | Zielnummer im internationalen Format, zum Beispiel +4930123456 |
purpose | ja | Freitext: worum es im Anruf geht |
employeeId | nein | Nur nötig, wenn mehr als ein Mitarbeiter eine Nummer hat |
externalReference | nein | Ihre eigene Kennung, zum Beispiel eine Auftragsnummer. Ein zweiter Aufruf mit demselben Wert wird mit 409 abgelehnt |
Der Mitarbeiter, der anruft, braucht eine zugewiesene Rufnummer.
curl -X POST -H "Authorization: Bearer tlfy_IhrSchluessel" -H "Content-Type: application/json" \
-d '{"toNumber": "+4930111111", "purpose": "Ihr Auto ist fertig zur Abholung."}' \
"https://api.telofy.app/api/v1/outbound-calls"
{ "callId": "call_9f2a1b" }
Die Antwort (Status 202) bestätigt nur, dass der Anruf gestartet wurde. Was besprochen wurde, erfahren Sie asynchron über den Webhook call.completed, sobald das Gespräch beendet und ausgewertet ist. Der MCP-Server löst keine Anrufe aus.
Webhook-Ereignisse
Webhooks legen Sie im Portal unter Integrationen > Webhooks an (Knopf „Webhook anlegen“). Sie tragen eine https-Adresse ein, wählen die Ereignisse und optional einen einzelnen Mitarbeiter. Das Signatur-Geheimnis (whsec_…) erscheint nur einmal in der Antwort.
Telofy sendet die Ereignisse nach der Anrufauswertung, nicht im Moment des Auflegens, und stellt sie asynchron zu. Planen Sie also mit einigen Minuten Abstand zum Ende des Gesprächs und nicht mit „in Echtzeit“.
| Ereignis | Wann |
|---|---|
call.completed | Nach jedem ausgewerteten Anruf |
outcome.created | Wenn der Anruf ein Anliegen vom Typ lead, ticket, appointment oder order ergab |
appointment.created | Zusätzlich zu outcome.created, wenn das Anliegen ein Termin war |
Jede Nachricht ist ein POST mit Content-Type: application/json und dem Kopf X-Telofy-Signature. Der Rumpf hat die Form { "event": …, "data": … }. Ein Gesprächsprotokoll enthält er nie, nur den Link callUrl ins Portal. Weitere Köpfe oder eine eigene Ereignis-Kennung gibt es nicht. Entdoppeln Sie über callId und outcomeId im Rumpf.
call.completed
{
"event": "call.completed",
"data": {
"callId": "call_9f2a1b",
"completedAt": "2026-07-14T09:04:12.000Z",
"durationSeconds": 252,
"employeeName": "Anna",
"summary": "Anrufer fragt nach Öffnungszeiten am Samstag.",
"outcomeType": "lead",
"callUrl": "https://telofy.app/calls/call_9f2a1b"
}
}
outcome.created
{
"event": "outcome.created",
"data": {
"outcomeId": "outcome_2e9f31",
"callId": "call_3c7d2e",
"createdAt": "2026-07-14T09:04:20.000Z",
"outcomeType": "lead",
"summary": "Interesse an Beratungstermin",
"callUrl": "https://telofy.app/calls/call_3c7d2e"
}
}
appointment.created
{
"event": "appointment.created",
"data": {
"outcomeId": "outcome_7b1a4c",
"callId": "call_9f2a1b",
"createdAt": "2026-07-14T10:19:35.000Z",
"requestedTime": "2026-07-21T10:00:00.000Z",
"contactName": "Frau Beispiel",
"contactPhone": "+4930555099",
"callUrl": "https://telofy.app/calls/call_9f2a1b"
}
}
Zustellung
- Als Erfolg gilt jeder Status 2xx. Antworten Sie innerhalb von 10 Sekunden.
- Bei Misserfolg gibt es bis zu fünf Versuche insgesamt, mit Wartezeiten von 1, 5, 30 und 120 Minuten dazwischen. Danach gilt die Zustellung als gescheitert.
- Weiterleitungen (Redirects) werden nicht verfolgt. Die Adresse muss direkt antworten.
- Nur
https://, ohne Zugangsdaten in der Adresse und ohne private oder interne Hostnamen wielocalhostoder.local. Telofy prüft das beim Versand erneut. - Die Reihenfolge ist nicht garantiert. Ein Wiederholungsversuch trägt denselben Rumpf, aber einen neuen Zeitstempel in der Signatur.
- Bis zu fünf Webhooks je Betrieb. Das Zustellprotokoll zeigt die letzten 50 Zustellungen je Webhook und wird nach 30 Tagen gelöscht.
- Der Knopf „Test-Ereignis senden“ im Portal schickt ein
call.completedmit"test": trueauf der obersten Ebene,callIdtestundoutcomeTypetest. Höchstens einmal pro Minute und Webhook. Ein Wiederholen vergangener Ereignisse gibt es nicht.
Signatur prüfen
Jede Nachricht trägt den Kopf
X-Telofy-Signature: t=1752482652,v1=<64 Hexzeichen>
t ist die Unix-Zeit in Sekunden des Versandversuchs. v1 ist der HMAC-SHA256 als Hexwert über den Text <t>.<Rohkörper>, gebildet mit dem Geheimnis Ihres Webhooks (whsec_…).
So prüfen Sie:
- Lesen Sie den Anfragetext unverändert als Text. Wenn Ihr Framework ihn schon in ein Objekt umgewandelt hat, stimmt die Prüfsumme nicht mehr. In Express nutzen Sie dafür
express.raw({ type: "application/json" }), in Flaskrequest.get_data(). - Trennen Sie
tundv1aus dem Kopf. - Bilden Sie den HMAC-SHA256 über
t, einen Punkt und den Rohkörper. - Vergleichen Sie mit
v1in konstanter Zeit. - Lehnen Sie Nachrichten ab, deren Zeitstempel mehr als fünf Minuten von Ihrer Uhr abweicht.
Node.js
import { createHmac, timingSafeEqual } from "node:crypto";
// rohKoerper: der unveränderte Anfragetext als String, nicht das geparste Objekt.
export function istTelofySignaturGueltig(
geheimnis,
rohKoerper,
kopfzeile,
jetzt = Math.floor(Date.now() / 1000)
) {
const teile = {};
for (const stueck of kopfzeile.split(",")) {
const i = stueck.indexOf("=");
if (i > 0) teile[stueck.slice(0, i).trim()] = stueck.slice(i + 1).trim();
}
const t = Number(teile.t);
if (!Number.isFinite(t) || !teile.v1) return false;
if (Math.abs(jetzt - t) > 300) return false; // höchstens fünf Minuten alt
const erwartet = createHmac("sha256", geheimnis)
.update(\`${teile.t}.${rohKoerper}\`, "utf8")
.digest("hex");
const a = Buffer.from(erwartet);
const b = Buffer.from(teile.v1);
return a.length === b.length && timingSafeEqual(a, b);
}
Python
import hashlib
import hmac
import time
def telofy_signatur_gueltig(geheimnis, roh_koerper, kopfzeile, jetzt=None):
"""roh_koerper: der unveränderte Anfragetext als bytes."""
teile = {}
for stueck in kopfzeile.split(","):
schluessel, _, wert = stueck.partition("=")
teile[schluessel.strip()] = wert.strip()
t_text = teile.get("t")
v1 = teile.get("v1")
if not t_text or not v1:
return False
try:
t = int(t_text)
except ValueError:
return False
jetzt = time.time() if jetzt is None else jetzt
if abs(jetzt - t) > 300: # höchstens fünf Minuten alt
return False
erwartet = hmac.new(
geheimnis.encode("utf-8"),
t_text.encode("utf-8") + b"." + roh_koerper,
hashlib.sha256,
).hexdigest()
return hmac.compare_digest(erwartet.encode("utf-8"), v1.encode("utf-8"))
MCP für KI-Assistenten
Der MCP-Server liegt unter https://api.telofy.app/mcp (Streamable HTTP, ohne Sitzungszustand, Antwort als JSON). Er nutzt denselben API-Schlüssel und dasselbe Ratenlimit wie die Schnittstelle.
| Werkzeug | Zweck | Parameter |
|---|---|---|
list_calls | Anrufe, neueste zuerst | page, limit (optional) |
list_outcomes | Anliegen aus Anrufen | page, limit (optional) |
list_appointments | Termine | page, limit (optional) |
list_absences | Abwesenheiten | from, to (optional) |
find_contacts | Kundenstamm suchen (Recht Kundenstamm, ab Pro) | phone, query, page, limit (optional) |
save_contact | Kontakt anlegen oder ändern (Recht Kundenstamm); nicht angegebene Felder bleiben unverändert, null oder leer löscht ein Feld | phone (Pflicht), salutation, firstName, lastName, company, email, note |
delete_contact | Kontakt löschen (Recht Kundenstamm) | id |
add_absence | Abwesenheit eintragen (Recht Abwesenheiten) | kind, startDate, endDate, reason, openTime, closeTime |
delete_absence | Abwesenheit löschen (Recht Abwesenheiten) | id |
Die ersten vier lesen und stehen immer bereit. Die Werkzeuge für Kundenstamm und Abwesenheiten sieht der Assistent nur, wenn der Schlüssel das jeweilige Recht hat; mit beiden Rechten sind es neun Werkzeuge. Wer per Klick verbindet (ChatGPT, Claude), hakt die Rechte auf der Zustimmungsseite an. Der MCP-Server löst keine Anrufe aus. Ein fehlender oder ungültiger Schlüssel am Endpunkt selbst ergibt Status 401.
Eine übliche Konfiguration für Assistenten, die MCP-Server über eine Adresse einbinden:
{
"mcpServers": {
"telofy": {
"url": "https://api.telofy.app/mcp",
"headers": {
"Authorization": "Bearer tlfy_IhrSchluessel"
}
}
}
}
Wo Sie das eintragen, unterscheidet sich je Assistent. Schauen Sie in dessen Anleitung nach der Stelle für entfernte MCP-Server. Ein Fehler beim Werkzeugaufruf, etwa durch einen ungültigen Schlüssel, kommt als Werkzeugfehler zurück und nicht als HTTP-Fehler.
Eigene Werkzeuge
Mit eigenen Werkzeugen ruft Telofy während eines Gesprächs eine https-Adresse Ihres Systems auf und liest die Antwort vor. Das ist die umgekehrte Richtung: Sie liefern Telofy Daten, statt welche abzuholen.
Anlegen im Portal unter Integrationen > Eigene Werkzeuge (Knopf „Werkzeug anlegen“). Sie legen fest:
- Funktionsname: Nur der Assistent sieht ihn, ohne Leerzeichen, zum Beispiel
lookup_shipping_status. - Beschreibung: Sie entscheidet, ob Telofy das Werkzeug im richtigen Moment aufruft. Schreiben Sie, wann es genutzt werden soll.
- Parameter-Schema (JSON): Welche Angaben Telofy aus dem Gespräch mitschickt.
- Ziel-Adresse: https, öffentlich erreichbar.
- Auth-Header-Name und Geheimnis (optional): Telofy sendet sie bei jedem Aufruf mit. Das Geheimnis wird verschlüsselt gespeichert.
Beispiel für ein Parameter-Schema:
{
"type": "OBJECT",
"properties": {
"order_number": { "type": "STRING", "description": "Bestellnummer" }
},
"required": ["order_number"]
}
Telofy sendet einen POST mit den Angaben unter arguments:
POST /versandstatus HTTP/1.1
Host: ihr-system.de
Content-Type: application/json
{ "arguments": { "order_number": "A-1042" } }
Ihr System antwortet mit Status 2xx und genau diesem Aufbau:
{ "result": "Die Bestellung A-1042 wurde heute mit DHL verschickt und kommt voraussichtlich morgen an." }
Grenzen:
- Bis zu 10 Werkzeuge je Betrieb.
- 4 Sekunden Zeit je Aufruf. Die Antwort darf höchstens 4.000 Byte groß sein, der Text in
resultwird auf 800 Zeichen gekürzt. - Weiterleitungen werden nicht verfolgt. Private und interne Adressen werden abgelehnt.
- Schlägt ein Aufruf fehl, sagt Telofy dem Anrufer ehrlich, dass es das gerade nicht nachsehen kann, und bietet an, das Anliegen aufzunehmen. Das Gespräch bricht nicht ab.
- Reservierte Namen lassen sich nicht vergeben.
Was die Schnittstelle nicht kann
- Sie schreibt keine Termine, Katalogpositionen oder Wissenseinträge. Die Pflege dieser Daten läuft über das Portal und den Import. Schreibend sind nur der ausgehende Anruf, der Kundenstamm und die Abwesenheiten, jeweils mit Zusatzrecht am Schlüssel.
- Bei den Anrufen gibt es keine Filter und keinen Gesamtzähler.
- MCP liest ab Werk nur; Kundenstamm und Abwesenheiten kommen nur mit den Zusatzrechten hinzu, Anrufe auslösen kann MCP nie.
- Webhooks haben keine Ereignis-Kennung im Kopf, keine Reihenfolgegarantie und keine Wiederholung vergangener Ereignisse auf Knopfdruck.
- Es gibt kein Programmierpaket (SDK) und keine OpenAPI-Datei.
- Eine eigene App für Zapier, Make oder n8n gibt es nicht. Die Anbindung läuft über deren Webhook-Bausteine, siehe Integrationen.
Fragen von Entwicklern.
Wie lautet die Basis-Adresse der Schnittstelle?
https://api.telofy.app. Die Anfragen gehen an Pfade wie /api/v1/calls und /mcp. Jede Anfrage braucht den Kopf Authorization: Bearer mit Ihrem Schlüssel.
Wie bekomme ich einen API-Schlüssel?
Im Portal unter Integrationen > API-Schlüssel erstellen Sie bis zu drei Schlüssel. Er wird nur einmal vollständig angezeigt und beginnt mit tlfy_.
Kann ich per Schnittstelle einen Anruf auslösen?
Ja, ab dem Tarif Business mit POST /api/v1/outbound-calls. Das Ergebnis des Gesprächs kommt anschließend über den Webhook call.completed.
Wie prüfe ich, dass ein Webhook von Telofy kommt?
Über den Kopf X-Telofy-Signature. Er enthält die Zeitangabe t und den HMAC-SHA256 v1 über t, einen Punkt und den Rohkörper, gebildet mit dem Geheimnis Ihres Webhooks. Beispiele für Node.js und Python stehen auf dieser Seite.
Sind Webhooks in Echtzeit?
Nein. Telofy sendet sie nach der Anrufauswertung und stellt sie asynchron zu. Bei Misserfolg gibt es bis zu fünf Versuche.