Documentation Index
Fetch the complete documentation index at: https://docs.telli.com/llms.txt
Use this file to discover all available pages before exploring further.
Die telli V2 API ist eine neue RESTful API zur Verwaltung von Kontakten und Kontakteigenschaften. Sie existiert parallel zur V1 API — beide bleiben vollständig funktionsfähig. Diese Anleitung zeigt dir die Unterschiede und wie du deine Integration migrierst.
Voraussetzungen
- Ein telli Konto mit API-Zugang
- Ein API-Schlüssel aus deinem telli Dashboard (Einstellungen > API & Webhooks)
Was sich geändert hat
Die V2 API bringt mehrere Verbesserungen gegenüber V1:
- Typisierte Kontakteigenschaften — Strukturierte, validierte Eigenschaften ersetzen untypisierte dynamische Variablen (siehe Kontakteigenschaften für Hintergrundinformationen)
- Cursor-basierte Paginierung — Effiziente Paginierung beim Auflisten von Kontakten
- Strukturierte Fehler — Einheitliche Fehlerantworten mit HTTP-Statuscodes und Fehlercodes
Authentifizierung
Die Authentifizierung bleibt unverändert. Verwende denselben API-Schlüssel mit demselben Authorization-Header:
Authorization: Bearer <your-api-key>
Die Basis-URL bleibt gleich — V2-Endpunkte sind unter dem /v2/-Präfix verfügbar.
Endpunkt-Zuordnung
| V1-Endpunkt | V2-Endpunkt | Hinweise |
|---|
POST /v1/add-contact | POST /v2/contacts | Gibt 201 mit vollständigem Kontaktobjekt zurück |
GET /v1/get-contact/:contactId | GET /v2/contacts/{id} | Gibt typisierte Antwort mit properties zurück |
GET /v1/get-contact-by-external-id/:externalId | GET /v2/external/contacts/{externalId} | Gleiches Verhalten, neuer Pfad |
PATCH /v1/update-contact | PATCH /v2/contacts/{id} | Kontakt-ID wandert vom Body in den URL-Pfad |
DELETE /v1/delete-contact/:contact_id | DELETE /v2/contacts/{id} | Gibt 204 zurück (kein Body) |
| — | GET /v2/contacts | Neu. Cursor-paginierte Kontaktliste |
POST /v1/add-contacts-batch | — | Noch nicht in V2 verfügbar |
PATCH /v1/update-contacts-batch | — | Noch nicht in V2 verfügbar |
POST /v1/get-contacts-batch | — | Noch nicht in V2 verfügbar |
Feld-Zuordnung
Request- und Response-Felder wurden von snake_case zu camelCase geändert:
| V1-Feld | V2-Feld | Hinweise |
|---|
external_contact_id | externalId | |
external_url | externalUrl | |
first_name | firstName | |
last_name | lastName | |
phone_number | phoneNumber | |
email | email | Unverändert |
salutation | salutation | Unverändert |
timezone | timezoneIana | Umbenannt zur Verdeutlichung |
dynamic_variables | properties | Siehe Dynamische Variablen migrieren |
contact_details | properties | Siehe Dynamische Variablen migrieren |
contact_id (Response) | id (Response) | |
created_at (Response) | createdAt (Response) | ISO 8601 Datums-/Zeitzeichenkette |
V2-Antworten enthalten ein type-Feld und geben angereicherte Kontakteigenschaftsdaten zurück.
{
"contact_id": "b3f1a2c4-5d6e-7f8a-9b0c-1d2e3f4a5b6c",
"external_contact_id": "crm-123",
"external_url": null,
"first_name": "Max",
"last_name": "Mustermann",
"phone_number": "+4915112345678",
"email": "[email protected]",
"salutation": null,
"timezone": "Europe/Berlin",
"contact_details": {
"appointment_date": "2026-03-15",
"interest_level": "high"
},
"created_at": "2026-02-06T10:00:00.000Z",
"status": "new",
"call_attempts": 0,
"next_call_at": null,
"in_call_since": null,
"reached_at": null
}
Wichtige Unterschiede in der Antwort:
contact_id ist jetzt id
contact_details (flaches Key-Value-Objekt) ist jetzt properties (Array aus typisierten, angereicherten Objekten)
- Jede Eigenschaft in der Antwort enthält ihren
dataType, label und options (bei Select-Typen)
- Das
type-Feld identifiziert den Ressourcentyp ("Contact")
- Anruf-bezogene Felder (
status, call_attempts, next_call_at, in_call_since, reached_at) sind nicht Teil der V2-Kontaktantwort
Dynamische Variablen zu Kontakteigenschaften migrieren
Dies ist die bedeutendste Änderung zwischen V1 und V2. In V1 konntest du beliebige Key-Value-Daten über dynamic_variables oder contact_details an Kontakte anhängen, ohne vorherige Einrichtung. In V2 definierst du zuerst ein Eigenschaftsschema und verwendest dann den generierten Eigenschaftsschlüssel beim Setzen von Werten.
Einen vollständigen Überblick darüber, was Kontakteigenschaften sind und wie du sie in der telli-Oberfläche verwaltest, findest du unter Kontakteigenschaften.
So funktioniert es
- Eigenschaft definieren — Erstelle eine Eigenschaftsdefinition mit einem Datentyp, Label und optionalen Einschränkungen über die API (oder über die telli-Oberfläche)
- Eigenschaftsschlüssel erhalten — Jede Eigenschaft erhält einen automatisch generierten Schlüssel (z.B.
aB3xK9mP2nQ4)
- Schlüssel bei Kontakten verwenden — Beim Erstellen oder Aktualisieren von Kontakten übergibst du Eigenschaften als
[{key, value}]-Paare mit den generierten Schlüsseln
Beispiel: Vorher und Nachher
Angenommen, du hast diese dynamischen Variablen in V1 bei Kontakten gespeichert:
{
"dynamic_variables": {
"appointment_date": "2026-03-15",
"interest_level": "high",
"notes": "Interested in premium plan"
}
}
Um auf V2 zu migrieren, definiere zunächst jede als typisierte Eigenschaft:
# Create a date property for appointment dates
curl -X POST https://api.telli.com/v2/properties/contacts \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"dataType": "date",
"label": "Appointment Date"
}'
# Response: { "key": "aB3xK9mP2nQ4", "dataType": "date", ... }
# Create a select property for interest level
curl -X POST https://api.telli.com/v2/properties/contacts \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"dataType": "select",
"label": "Interest Level",
"options": [
{ "value": "low", "label": "Low" },
{ "value": "medium", "label": "Medium" },
{ "value": "high", "label": "High" }
]
}'
# Response: { "key": "wLs7rT5yU8vX", "dataType": "select", ... }
# Create a text property for notes
curl -X POST https://api.telli.com/v2/properties/contacts \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"dataType": "string",
"label": "Notes"
}'
# Response: { "key": "jF2hG6kD9pN1", "dataType": "string", ... }
Verwende dann die zurückgegebenen Schlüssel beim Erstellen oder Aktualisieren von Kontakten:
{
"properties": [
{ "key": "aB3xK9mP2nQ4", "value": "2026-03-15" },
{ "key": "wLs7rT5yU8vX", "value": "high" },
{ "key": "jF2hG6kD9pN1", "value": "Interested in premium plan" }
]
}
Verfügbare Eigenschaftstypen
| API-Datentyp | Beschreibung | Beispielwert |
|---|
string | Freitext-Zeichenkette | "Enterprise" |
number | Numerischer Wert | 42 |
boolean | Wahr oder falsch | true |
date | Kalenderdatum (YYYY-MM-DD) | "2026-03-15" |
datetime | Datum mit Uhrzeit (ISO 8601) | "2026-03-15T14:30:00Z" |
select | Einzelauswahl aus vordefinierten Optionen | "gold" |
multi_select | Mehrfachauswahl aus vordefinierten Optionen | ["german", "english"] |
phone_number | Telefonnummer im E.164-Format | "+4915112345678" |
email | E-Mail-Adresse | "[email protected]" |
Systemeigenschaften
Einige Kontaktfelder werden in V2 als Systemeigenschaften dargestellt. Diese sind immer vorhanden und können nicht über die Properties-API geändert oder gelöscht werden:
| Key | Datentyp | Label |
|---|
externalId | string | External ID |
firstName | string | First Name |
lastName | string | Last Name |
phoneNumber | phone_number | Phone Number |
email | email | Email |
timezoneIana | string | Timezone |
externalUrl | string | External URL |
Systemeigenschaften werden direkt als Top-Level-Felder am Kontakt gesetzt (z.B. firstName, email), nicht über das properties-Array.
Migration Schritt für Schritt
Kontakt erstellen
curl -X POST https://api.telli.com/v1/add-contact \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"external_contact_id": "crm-123",
"first_name": "Max",
"last_name": "Mustermann",
"phone_number": "+4915112345678",
"email": "[email protected]",
"timezone": "Europe/Berlin",
"dynamic_variables": {
"appointment_date": "2026-03-15",
"interest_level": "high"
}
}'
V1 gibt { "contact_id": "..." } zurück. V2 gibt 201 mit dem vollständigen Kontaktobjekt einschließlich angereicherter Eigenschaften zurück.
Kontakt per ID abrufen
curl https://api.telli.com/v1/get-contact/<contact-id> \
-H "Authorization: Bearer <your-api-key>"
Kontakt per externer ID abrufen
curl https://api.telli.com/v1/get-contact-by-external-id/crm-123 \
-H "Authorization: Bearer <your-api-key>"
Kontakte auflisten
Dieser Endpunkt ist neu in V2 — es gibt kein V1-Äquivalent. Er gibt eine paginierte Liste von Kontakten mit Cursor-basierter Paginierung zurück.
curl "https://api.telli.com/v2/contacts?limit=10" \
-H "Authorization: Bearer <your-api-key>"
Antwort:
{
"type": "ContactCollection",
"data": [
{ "id": "...", "type": "Contact", "firstName": "Max", ... }
],
"pageInfo": {
"hasNextPage": true,
"endCursor": "eyJjcmVhdGVkQXQiOi..."
},
"meta": {
"totalCount": 142
}
}
Um die nächste Seite abzurufen, übergib den endCursor-Wert als cursor-Query-Parameter:
curl "https://api.telli.com/v2/contacts?limit=10&cursor=eyJjcmVhdGVkQXQiOi..." \
-H "Authorization: Bearer <your-api-key>"
Kontakt aktualisieren
In V1 übergibst du die contact_id im Request-Body. In V2 ist die Kontakt-ID Teil des URL-Pfads.
curl -X PATCH https://api.telli.com/v1/update-contact \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"contact_id": "<contact-id>",
"first_name": "Maximilian",
"dynamic_variables": {
"interest_level": "medium"
}
}'
Wichtiger Unterschied beim Update-Verhalten:
- V1 ersetzt das gesamte
dynamic_variables-Objekt. Wenn du nur {"interest_level": "medium"} sendest, gehen alle anderen dynamischen Variablen verloren.
- V2 führt Eigenschaften zusammen. Nur die Schlüssel, die du angibst, werden aktualisiert — alle anderen bestehenden Eigenschaften bleiben erhalten. Um eine Eigenschaft zu löschen, setze ihren Wert auf
null.
Kontakt löschen
curl -X DELETE https://api.telli.com/v1/delete-contact/<contact-id> \
-H "Authorization: Bearer <your-api-key>"
V1 gibt { "message": "Contact deleted successfully", "contact_id": "..." } zurück. V2 gibt 204 No Content mit einem leeren Antwort-Body zurück.
Kontakteigenschaften-API
V2 führt eine eigene API zur Verwaltung von Eigenschaftsdefinitionen ein. Du musst Eigenschaftsdefinitionen nur einmal pro Konto erstellen — sie gelten dann für alle Kontakte.
Informationen zur Verwaltung von Eigenschaften über die telli-Oberfläche findest du unter Kontakteigenschaften.
Alle Eigenschaftsdefinitionen auflisten
curl https://api.telli.com/v2/properties/contacts \
-H "Authorization: Bearer <your-api-key>"
Gibt sowohl Systemeigenschaften als auch deine benutzerdefinierten Eigenschaften zurück:
{
"type": "ContactPropertyList",
"data": [
{
"type": "ContactProperty",
"key": "firstName",
"dataType": "string",
"source": "system",
"label": "First Name",
"createdAt": "2026-01-01T00:00:00.000Z",
"updatedAt": "2026-01-01T00:00:00.000Z"
},
{
"type": "ContactProperty",
"key": "aB3xK9mP2nQ4",
"dataType": "date",
"source": "user",
"label": "Appointment Date",
"createdAt": "2026-02-06T10:00:00.000Z",
"updatedAt": "2026-02-06T10:00:00.000Z"
}
]
}
Einzelne Eigenschaftsdefinition abrufen
curl https://api.telli.com/v2/properties/contacts/aB3xK9mP2nQ4 \
-H "Authorization: Bearer <your-api-key>"
Eigenschaftsdefinition erstellen
curl -X POST https://api.telli.com/v2/properties/contacts \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"dataType": "select",
"label": "Customer Tier",
"options": [
{ "value": "free", "label": "Free" },
{ "value": "pro", "label": "Pro" },
{ "value": "enterprise", "label": "Enterprise" }
]
}'
Eigenschaftsdefinition aktualisieren
Du kannst das Label, die Beschreibung und neue Optionen (bei Select-Typen) aktualisieren. Der Datentyp kann nicht geändert und bestehende Optionen können nicht entfernt werden.
curl -X PATCH https://api.telli.com/v2/properties/contacts/aB3xK9mP2nQ4 \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-d '{
"label": "Appointment Date (Updated)",
"description": "The next scheduled appointment date"
}'
Wichtige Unterschiede im Überblick
-
Eigenschaften erfordern eine vorherige Definition — Du musst eine Eigenschaftsdefinition erstellen, bevor du sie bei Kontakten verwenden kannst. Unbekannte Eigenschaftsschlüssel werden mit einem
422-Validierungsfehler abgelehnt.
-
Eigenschaftsschlüssel werden systemseitig generiert — Schlüssel wie
aB3xK9mP2nQ4 werden von telli beim Erstellen einer Eigenschaft zugewiesen. Verwende den Endpunkt zum Auflisten von Eigenschaften, um die Schlüssel deiner Eigenschaften nachzuschlagen.
-
Updates führen Eigenschaften zusammen — In V2 wirkt sich das Aktualisieren der Eigenschaften eines Kontakts nur auf die angegebenen Schlüssel aus. Bestehende Eigenschaften bleiben erhalten. Setze einen Wert auf
null, um eine bestimmte Eigenschaft zu löschen. In V1 wurde beim Senden von dynamic_variables das gesamte Objekt ersetzt.
-
Werte werden validiert — V2 validiert Eigenschaftswerte gegen ihren Datentyp und ihre Einschränkungen (z.B. lehnt eine
date-Eigenschaft "not-a-date" ab, eine select-Eigenschaft lehnt Werte ab, die nicht in der Optionsliste enthalten sind). V1 akzeptierte jeden Wert.
-
Batch-Endpunkte sind in V2 noch nicht verfügbar — Wenn du auf Batch-Operationen (
add-contacts-batch, update-contacts-batch, get-contacts-batch) angewiesen bist, verwende vorerst weiterhin die V1-Endpunkte.
-
V2 gibt angereicherte Eigenschaften zurück — GET-Antworten enthalten den
dataType, das label und die options für jeden Eigenschaftswert, sodass du keinen separaten Lookup benötigst, um Eigenschaftsdaten zu interpretieren.