> ## Documentation Index
> Fetch the complete documentation index at: https://docs.famulor.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Benutzerdefinierte Variablen

> Variablen pro Assistent definieren und Live-Werte aus API, Kampagnen-Leads, Webhook oder Systemkontext in Prompts, Begrüßungen und Tools einsetzen

Mit benutzerdefinierten Variablen schreibst du einen Assistenten einmal und personalisierst trotzdem jeden Anruf. Statt einen Namen, einen Termin oder eine Kontonummer fest in den System-Prompt zu schreiben, referenzierst du einen Platzhalter wie `{{customer_name}}` und lieferst den Wert pro Anruf – aus deiner API-Anfrage, einem Kampagnen-Lead, einem eingehenden Anreicherungs-Webhook oder dem eingebauten Systemkontext der Plattform.

## Referenzsyntax

Referenziere eine Variable mit doppelten geschweiften Klammern – das ist die bevorzugte, JSON-sichere Form:

```text theme={null}
Hi {{customer_name}}, I see your appointment is on {{appointment_date}}.
```

Die alte Form mit einfachen Klammern `{customer_name}` wird ebenfalls aufgelöst, allerdings **nur für Schlüssel, die tatsächlich bekannt sind** (eine definierte Variable oder eine Systemvariable). So bleiben literale Klammern – zum Beispiel JSON im Body eines Tools – unangetastet. Jeder Platzhalter mit unbekanntem Schlüssel bleibt unverändert stehen.

## Variablen für einen Assistenten definieren

Jeder Assistent hat eine Liste von Variablendefinitionen. Eine Definition besteht aus:

| Feld            | Erforderlich | Beschreibung                                                                                                                                                                                                                                                             |
| --------------- | ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `key`           | ja           | Der Bezeichner, der als `{{key}}` verwendet wird. Beginnt mit einem Kleinbuchstaben, danach Kleinbuchstaben, Ziffern und Unterstriche; 1–64 Zeichen (`^[a-z][a-z0-9_]{0,63}$`). Pro Assistent eindeutig. Darf keine reservierte [Systemvariable](#systemvariablen) sein. |
| `label`         | ja           | Für Menschen lesbarer Name, der im Editor angezeigt wird.                                                                                                                                                                                                                |
| `description`   | nein         | Notiz, wofür die Variable gedacht ist.                                                                                                                                                                                                                                   |
| `default_value` | nein         | Fallback-Wert, der genutzt wird, wenn zum Zeitpunkt des Anrufs kein Wert übergeben wird.                                                                                                                                                                                 |
| `example`       | nein         | Beispielwert (nur für Editor/Doku, wird nie gesendet).                                                                                                                                                                                                                   |
| `source`        | nein         | Informativer Hinweis: `manual` (Standard), `lead`, `webhook` oder `system`. Steuert UI-Hinweise und das Webhook-Mapping, schränkt aber nicht ein, woher ein Wert tatsächlich kommen kann.                                                                                |

<Note>
  Schlüssel werden beim Speichern validiert: Ein ungültiges Format, eine Kollision mit einer reservierten Systemvariable, ein doppelter Schlüssel oder ein fehlendes Label werden allesamt abgelehnt.
</Note>

## Wo Variablen ersetzt werden

Werte werden beim Start des Anrufs ersetzt, bevor Modell oder Flow laufen – und zwar in diesen Feldern:

* **system prompt** des Assistenten
* **first message** des Assistenten (Begrüßung)
* Flow-Node **`start.greeting`**
* Flow-Node **`agent.instructions`**
* **URL** und Header-**values** der Anfrage im Flow-**Tool-Node**
* Ziel-**number** und **announcement** im Flow-**Transfer-Node**
* Ziel-**number**, **caller announcement** und **briefing instructions** im Flow-**Warm-Transfer-Node**
* **Built-in tool texts** – **description** des Tools, **announcement** bei der Weiterleitung, **hold message**, **connected message**, **briefing first message** und **summary instructions** beim Warm Transfer, **farewell** beim Beenden des Anrufs, **pre-transfer message** bei der Übergabe an einen anderen Assistenten und **prompt** beim Erfassen der Zahlungskarte

So kann ein Transfer-Node jeden Anruf an eine Lead-spezifische Nummer wie `{{handover_number}}` weiterleiten, geliefert über die benutzerdefinierten Felder des Kampagnen-Leads, `variables` im API-Aufruf oder den eingehenden Variablen-Webhook – und ein Warm-Transfer-Briefing kann mit `Hallo, hier {{assistant_name}} von {{company}} — Anrufer {{caller_name}}` beginnen. Was jedes Flow-Feld steuert, steht in der [Flow-Knotenreferenz](/de/flow-builder/nodes).

Gesprochene Tool-Texte werden zweimal ersetzt: einmal beim Start des Anrufs mit den aufgelösten Eingabevariablen, und erneut in dem Moment, in dem das Tool ausgeführt wird – dadurch sind auch Werte enthalten, die **während** des Gesprächs erfasst wurden (über `set_variable` oder Collect-Schritte), und diese haben Vorrang.

So kann ein Tool-Node `https://api.example.com/orders/{{order_id}}` aufrufen oder `Authorization: Bearer {{api_token}}` mit Werten pro Anruf senden.

## Wertquellen und Priorität

Ein Wert kann aus mehreren Quellen kommen. Beim Start des Anrufs verwendet die Plattform diese Priorität, höchste zuerst:

1. **Explizit** – Werte, die direkt mit dem Anruf übergeben werden: über `variables` im API-Aufruf `make-call`, oder die benutzerdefinierten Felder eines Kampagnen-Leads, die auf passende Schlüssel gemappt werden.
2. **Eingehender Variablen-Webhook** – Anreicherung, die beim Start des Anrufs abgerufen wird (siehe [unten](#eingehender-variablen-webhook)).
3. **Systemvariablen** – von der Plattform aus dem Anrufkontext befüllt.
4. **Standardwert** – der `default_value` aus der Definition.

Ein Platzhalter, der auf keiner Ebene einen Wert bekommt, bleibt unverändert.

### Explizite Werte über die API

```bash theme={null}
curl -X POST https://app.famulor.io/api/v1/calls \
  -H "Authorization: Bearer fam_..." \
  -H "Content-Type: application/json" \
  -d '{
    "assistant_id": "asst_123",
    "to_number": "+493012345678",
    "variables": { "customer_name": "Jordan", "appointment_date": "2026-07-10" }
  }'
```

### Kampagnen-Leads → Variablen

In einer [Kampagne](/de/campaigns/overview) kann jeder Lead frei definierbare **benutzerdefinierte Felder** haben. Beim Wählen wird ein Feld auf eine Variable mit dem **gleichen Schlüssel** gemappt. So wird aus einer CSV-Spalte eine Variable:

```csv theme={null}
phone_number,name,customer_name,appointment_date
+493012345678,Jordan,Jordan,2026-07-10
+491701234567,Alex,Alex,2026-07-11
```

Hier befüllen die Spalten `customer_name` und `appointment_date` bei jedem Anruf `{{customer_name}}` und `{{appointment_date}}`. Gib einer Lead-basierten Variable `source: "lead"`, um die Absicht zu dokumentieren.

## Systemvariablen

Diese Schlüssel sind beim Start des Anrufs immer verfügbar. Sie sind reserviert – du kannst keine benutzerdefinierte Variable mit einem dieser Schlüssel anlegen.

| Schlüssel        | Label                | Beschreibung                                                                                   | Beispiel               |
| ---------------- | -------------------- | ---------------------------------------------------------------------------------------------- | ---------------------- |
| `caller_number`  | Anrufernummer        | Die Telefonnummer, von der der Anruf kommt (eingehend) bzw. an die er geht (ausgehend), E.164. | `+493012345678`        |
| `called_number`  | Angerufene Nummer    | Die gewählte Nummer bzw. deine Nummer, die den Anruf empfangen hat, E.164.                     | `+498998765432`        |
| `assistant_name` | Name des Assistenten | Der Name des Assistenten, der den Anruf bearbeitet.                                            | `Reception Bot`        |
| `direction`      | Anrufrichtung        | `inbound`, `outbound` oder `web`.                                                              | `inbound`              |
| `call_id`        | Anruf-ID             | Eindeutige ID dieses Anrufs.                                                                   | `c_a1b2c3`             |
| `date`           | Datum                | Aktuelles Datum beim Start des Anrufs (Zeitzone des Assistenten), `YYYY-MM-DD`.                | `2026-07-05`           |
| `time`           | Uhrzeit              | Aktuelle Uhrzeit beim Start des Anrufs (Zeitzone des Assistenten), `HH:MM`.                    | `14:30`                |
| `datetime`       | Datum & Uhrzeit      | Aktuelles Datum und Uhrzeit beim Start des Anrufs (ISO 8601).                                  | `2026-07-05T14:30:00Z` |
| `weekday`        | Wochentag            | Aktueller Wochentag beim Start des Anrufs.                                                     | `Sunday`               |

## Eingehender Variablen-Webhook

Bei **eingehenden** Anrufen kennst du den Anrufer oft nicht im Voraus. Konfiguriere einen **Variablen-Webhook** am Assistenten. Famulor ruft ihn beim Start auf, um Variablen anzureichern, zum Beispiel anhand der Anrufernummer. Das passiert vor dem Anruf; was Famulor nach dessen Ende sendet, steht unter [Webhooks nach dem Anruf](/de/assistants/webhooks).

### Anfrage

Famulor sendet einen `POST` mit JSON-Body:

```json theme={null}
{
  "event": "call.variables",
  "assistant_id": "asst_123",
  "call_id": "c_a1b2c3",
  "direction": "inbound",
  "from_number": "+493012345678",
  "to_number": "+498998765432"
}
```

Der rohe Request-Body wird mit HMAC-SHA256 und dem konfigurierten Webhook-Secret signiert. Die Signatur wird im Header mitgesendet:

```text theme={null}
X-Famulor-Signature: sha256=<hexdigest>
```

### Antwort

Gib die zu mergenden Variablen zurück:

```json theme={null}
{
  "variables": {
    "customer_name": "Jordan",
    "open_amount": "128.50"
  }
}
```

Diese Werte überschreiben Systemvariablen und Standardwerte; explizit für den Anruf übergebene Werte haben Vorrang. Schlägt der Abruf fehl, läuft der Anruf mit den bereits vorhandenen Werten weiter.

### Native Automation (Alternative)

Statt eines eigenen Webhooks kannst du eine [**Automation**](/de/automations/overview) mit dem Trigger **Inject input variables** anlegen und an den Assistenten binden. Füge eine Aktion **Return variables** mit demselben `{ variables: {…} }`-Format hinzu. Ohne passende aktive Automation wird der konfigurierte Webhook verwendet.

### Signatur verifizieren

<CodeGroup>
  ```js Node.js theme={null}
  import crypto from "node:crypto";

  // rawBody: die exakten empfangenen Bytes, vor JSON.parse
  function verify(rawBody, signatureHeader, secret) {
    const expected =
      "sha256=" +
      crypto.createHmac("sha256", secret).update(rawBody).digest("hex");
    const a = Buffer.from(signatureHeader);
    const b = Buffer.from(expected);
    return a.length === b.length && crypto.timingSafeEqual(a, b);
  }
  ```

  ```python Python theme={null}
  import hmac, hashlib

  # raw_body: die exakten empfangenen Bytes, vor json.loads
  def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
      expected = "sha256=" + hmac.new(
          secret.encode(), raw_body, hashlib.sha256
      ).hexdigest()
      return hmac.compare_digest(expected, signature_header)
  ```
</CodeGroup>

<Warning>
  Berechne den HMAC immer über die **rohen** Bytes des Request-Bodys, nicht über ein neu serialisiertes Objekt – eine erneute Serialisierung kann Whitespace oder die Key-Reihenfolge verändern und damit die Signatur brechen. Verwende einen zeitkonstanten Vergleich.
</Warning>

### Beispielanfrage

```bash theme={null}
curl -X POST https://your-app.example.com/famulor/variables \
  -H "Content-Type: application/json" \
  -H "X-Famulor-Signature: sha256=6d3a...e1f0" \
  -d '{
    "event": "call.variables",
    "assistant_id": "asst_123",
    "call_id": "c_a1b2c3",
    "direction": "inbound",
    "from_number": "+493012345678",
    "to_number": "+498998765432"
  }'
```

## API & MCP

* `GET /api/v1/assistants/{id}/variables` – liest die Variablendefinitionen des Assistenten; Scope `assistants:read`.
* `PATCH /api/v1/assistants/{id}/variables` – ersetzt die Variablendefinitionen; Scope `assistants:write`.
* MCP-Tools: `get_assistant_variables`, `set_assistant_variables`.

<Tip>
  Die vollständige REST-Referenz findest du unter [docs.famulor.io](https://docs.famulor.io). Nutze `{{key}}` überall dort, wo du einen Wert pro Anruf brauchst, halte Schlüssel in `snake_case` und gib jeder Variable einen sinnvollen `default_value`, damit Anrufe sauber degradieren, wenn eine Quelle fehlt.
</Tip>
