Zum Hauptinhalt springen
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-EndpunktV2-EndpunktHinweise
POST /v1/add-contactPOST /v2/contactsGibt 201 mit vollständigem Kontaktobjekt zurück
GET /v1/get-contact/:contactIdGET /v2/contacts/{id}Gibt typisierte Antwort mit properties zurück
GET /v1/get-contact-by-external-id/:externalIdGET /v2/external/contacts/{externalId}Gleiches Verhalten, neuer Pfad
PATCH /v1/update-contactPATCH /v2/contacts/{id}Kontakt-ID wandert vom Body in den URL-Pfad
DELETE /v1/delete-contact/:contact_idDELETE /v2/contacts/{id}Gibt 204 zurück (kein Body)
GET /v2/contactsNeu. Cursor-paginierte Kontaktliste
POST /v1/add-contacts-batchNoch nicht in V2 verfügbar
PATCH /v1/update-contacts-batchNoch nicht in V2 verfügbar
POST /v1/get-contacts-batchNoch nicht in V2 verfügbar

Feld-Zuordnung

Request- und Response-Felder wurden von snake_case zu camelCase geändert:
V1-FeldV2-FeldHinweise
external_contact_idexternalId
external_urlexternalUrl
first_namefirstName
last_namelastName
phone_numberphoneNumber
emailemailUnverändert
salutationsalutationUnverändert
timezonetimezoneIanaUmbenannt zur Verdeutlichung
dynamic_variablespropertiesSiehe Dynamische Variablen migrieren
contact_detailspropertiesSiehe Dynamische Variablen migrieren
contact_id (Response)id (Response)
created_at (Response)createdAt (Response)ISO 8601 Datums-/Zeitzeichenkette

Antwortformat

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

  1. Eigenschaft definieren — Erstelle eine Eigenschaftsdefinition mit einem Datentyp, Label und optionalen Einschränkungen über die API (oder über die telli-Oberfläche)
  2. Eigenschaftsschlüssel erhalten — Jede Eigenschaft erhält einen automatisch generierten Schlüssel (z.B. aB3xK9mP2nQ4)
  3. 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-DatentypBeschreibungBeispielwert
stringFreitext-Zeichenkette"Enterprise"
numberNumerischer Wert42
booleanWahr oder falschtrue
dateKalenderdatum (YYYY-MM-DD)"2026-03-15"
datetimeDatum mit Uhrzeit (ISO 8601)"2026-03-15T14:30:00Z"
selectEinzelauswahl aus vordefinierten Optionen"gold"
multi_selectMehrfachauswahl aus vordefinierten Optionen["german", "english"]
phone_numberTelefonnummer im E.164-Format"+4915112345678"
emailE-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:
KeyDatentypLabel
externalIdstringExternal ID
firstNamestringFirst Name
lastNamestringLast Name
phoneNumberphone_numberPhone Number
emailemailEmail
timezoneIanastringTimezone
externalUrlstringExternal 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

  1. 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.
  2. 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.
  3. 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.
  4. 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.
  5. 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.
  6. 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.