
Mit der inDeal API legst du Deals zu deinen Leads an, führst sie durch die Phasen bis zum Abschluss und holst dir fertige Kennzahlen, ohne selbst durch Listen zu blättern. Schlüssel, Base-URL und Grundlagen sind dieselben wie bei den Leads: [inDeal API: Leads per Schnittstelle anlegen und aktualisieren](https://success.indeal.ai/hc/indeal/articles/indeal-api-leads-anlegen-und-aktualisieren).

**Inhalt**
- [Was ein Deal ist](#was-ein-deal-ist)
- [Deal anlegen](#deal-anlegen)
- [Deal lesen und aktualisieren](#deal-lesen-und-aktualisieren)
- [Deals auflisten](#deals-auflisten)
- [Aktivitäten am Deal](#aktivitaeten-am-deal)
- [Felder](#felder)
- [Auswertungen](#auswertungen)
- [Kennzahlen im Einzelnen](#kennzahlen-im-einzelnen)
- [Weiter](#weiter)


## Was ein Deal ist

Ein Deal entsteht aus einem Lead und behält über `lead_id` seine Herkunft. Er läuft durch die Phasen `send_offer` (Angebot senden) und `order_received` (Auftrag erhalten) und endet in `won` (gewonnen) oder `lost` (verloren). Zu jedem Lead gibt es höchstens einen offenen Deal - dieselbe Regel wie in der App, siehe [Vom Lead zum Deal und zurück](https://success.indeal.ai/hc/indeal/articles/vom-lead-zum-deal-und-zurueck).

## Deal anlegen

`POST /deals` legt einen Deal an. `lead_id` ist Pflicht; der Lead muss in deinem Account existieren, sonst antwortet die API mit `404`.

```bash
curl -X POST https://app.indeal.ai/api/v1/deals \
  -H "Authorization: Bearer indeal_..." \
  -H "Content-Type: application/json" \
  -d '{
    "lead_id": "0b0e...",
    "value": 12000,
    "confidence": 40,
    "expected_close_date": "2026-10-15"
  }'
```

Antwort mit Status `201`:

```json
{
  "status": "created",
  "deal": {
    "id": "7c1d...",
    "lead_id": "0b0e...",
    "stage": "send_offer",
    "value": 12000,
    "confidence": 40,
    "weighted_value": 4800,
    "expected_close_date": "2026-10-15",
    "won_at": null,
    "lost_at": null,
    "url": "https://app.indeal.ai/pipeline/7c1d...",
    "lead": {
      "id": "0b0e...",
      "full_name": "Julia Weber",
      "company_name": "Muster GmbH",
      "email": "julia.weber@muster.de",
      "url": "https://app.indeal.ai/leads/0b0e..."
    }
  }
}
```

Drei Dinge passieren dabei automatisch:

- Fehlt `value`, übernimmt der Deal den geschätzten Wert (`est_value`) des Leads. Fehlt `confidence`, gilt 25.
- Der Lead gilt ab jetzt als konvertiert. Seine Phase bleibt unverändert.
- Hat der Lead schon einen Deal, der nicht im Papierkorb liegt, wird kein zweiter angelegt. Du bekommst Status `200` mit `"status": "duplicate"` und dem bestehenden Deal. Prüfe also einfach `status`, statt vorher nachzusehen.

## Deal lesen und aktualisieren

`GET /deals/{id}` liefert `{ "deal": { ... } }`. Eine unbekannte ID oder ein Deal aus einem anderen Account ergibt `404`.

`PATCH /deals/{id}` ändert nur die Felder, die du schickst. `null` leert ein Feld.

```bash
curl -X PATCH https://app.indeal.ai/api/v1/deals/7c1d... \
  -H "Authorization: Bearer indeal_..." \
  -H "Content-Type: application/json" \
  -d '{ "stage": "won", "value": 15000 }'
```

- `stage` wechselt die Phase. `won` setzt `won_at`, `lost` setzt `lost_at` auf jetzt. Die Historie der Phasenwechsel schreibt inDeal selbst.
- Bei `lost` lohnt sich `lost_reason` - der Grund erscheint in der App und im Webhook-Ereignis `deal.lost`.
- Änderst du `next_step_due`, verfällt eine Erinnerung, die in der App zu diesem Termin gesetzt war.

## Deals auflisten

`GET /deals` liefert Deals seitenweise, sortiert nach der letzten Änderung.

| Parameter | Bedeutung |
|---|---|
| `stage` | nur diese Phase |
| `lead_id` | nur Deals dieses Leads |
| `updated_since` | ISO 8601, nur Deals, die seitdem geändert wurden |
| `order` | `asc` (Standard, älteste zuerst) oder `desc` |
| `limit` | 1 bis 200, Standard 100 |
| `cursor` | `next_cursor` aus der vorigen Antwort |

Antwort: `{ "deals": [...], "next_cursor": "..." }`. Ist `next_cursor` `null`, war das die letzte Seite. Für Summen und Zähler brauchst du diese Liste nicht - dafür gibt es die [Auswertungen](#auswertungen).

## Aktivitäten am Deal

Deals haben eine eigene Timeline. `POST /deals/{id}/activities` und `GET /deals/{id}/activities` funktionieren genau wie die Aktivitäten am Lead: dieselben Typen (`note`, `call`, `email`, `meeting_scheduled`), dieselben Felder, dieselbe Seitensteuerung. Ein Eintrag am Deal hängt nur am Deal, nicht zusätzlich am Lead.

## Felder

| Feld | Typ | Hinweis |
|---|---|---|
| `id`, `created_at`, `updated_at`, `stage_entered_at` | nur lesend | |
| `lead_id` | ID | Herkunfts-Lead, beim Anlegen Pflicht |
| `stage` | Auswahl | `send_offer`, `order_received`, `won`, `lost` |
| `value` | Zahl | Dealvolumen |
| `confidence` | Ganzzahl 0 bis 100 | Wahrscheinlichkeit in Prozent |
| `weighted_value` | nur lesend | `value` mal `confidence` geteilt durch 100 |
| `expected_close_date` | Datum `YYYY-MM-DD` | erwarteter Abschluss |
| `offer_sent_at`, `next_step_due` | ISO 8601 | |
| `next_step`, `notes`, `lost_reason` | Text | `lost_reason` nur beim Aktualisieren |
| `won_at`, `lost_at` | nur lesend | gesetzt beim Wechsel auf `won` oder `lost` |
| `url` | nur lesend | Link zur Deal-Seite in inDeal |
| `lead` | nur lesend | `id`, `full_name`, `company_name`, `email` und `url` des Leads |
| `custom_data` | Objekt | eigene Felder für Deals, gleiches Format und gleiche Prüfung wie bei Leads, siehe [Eigene Felder](https://success.indeal.ai/hc/indeal/articles/indeal-api-leads-anlegen-und-aktualisieren#eigene-felder); die Felder liefert `GET /custom-fields?entity=deal` |

Nicht über die API erreichbar: die Zuordnung zu einer Person im Team, Erinnerungen und der Papierkorb.

## Auswertungen

`GET /reports/summary` liefert fertige Kennzahlen für einen Zeitraum - Leads, Termine, Deals und Conversion in einer Antwort. Die Zahlen gelten für den ganzen Account, unabhängig davon, wem ein Lead zugeordnet ist. Alle Zeiten sind UTC.

| Parameter | Bedeutung |
|---|---|
| `from` | Beginn, `YYYY-MM-DD` oder ISO 8601. Standard: der 1. des laufenden Monats |
| `to` | Ende, `YYYY-MM-DD` (der Tag zählt mit) oder ISO 8601 (exklusiv). Standard: jetzt |
| `sections` | kommagetrennt aus `leads`, `meetings`, `deals`, `conversion`. Standard: alle vier |

Der Zeitraum darf höchstens 366 Tage lang sein, und `from` muss vor `to` liegen - sonst antwortet die API mit `400`.

```bash
curl "https://app.indeal.ai/api/v1/reports/summary?from=2026-09-01&to=2026-09-30&sections=deals,conversion" \
  -H "Authorization: Bearer indeal_..."
```

Antwort mit Status `200`, hier alle vier Blöcke:

```json
{
  "period": { "from": "2026-09-01T00:00:00+00:00", "to": "2026-10-01T00:00:00+00:00" },
  "leads": {
    "created": 12,
    "by_stage": [ { "stage": "qualifying", "count": 40, "est_value_sum": 380000 } ],
    "by_source_tool": [ { "source_tool": "api", "count": 12 } ],
    "by_lead_source": [ { "lead_source": "Webinar", "count": 7 } ]
  },
  "meetings": { "scheduled": 5, "done": 3 },
  "deals": {
    "created": 3,
    "by_stage": [ { "stage": "send_offer", "count": 4, "value_sum": 54000, "weighted_sum": 21600 } ],
    "pipeline_value": 54000,
    "pipeline_weighted": 21600,
    "won_count": 1,
    "won_value": 15000,
    "lost_count": 1,
    "avg_days_to_won": 12.5
  },
  "conversion": {
    "leads_created": 12,
    "meetings_scheduled": 5,
    "deals_created": 3,
    "deals_won": 1,
    "meeting_rate": 0.4167,
    "deal_rate": 0.6,
    "win_rate": 0.3333
  }
}
```

Quoten sind Zahlen zwischen 0 und 1 mit vier Nachkommastellen. Leads und Deals im Papierkorb zählen nirgends mit.

## Kennzahlen im Einzelnen

Zwei Arten von Zahlen stecken in der Antwort: Zähler für den Zeitraum (was ist zwischen `from` und `to` passiert) und Bestandszahlen von heute (wie sieht die Pipeline jetzt aus). `by_stage`, `pipeline_value` und `pipeline_weighted` sind Bestandszahlen, alles andere bezieht sich auf den Zeitraum.

| Kennzahl | Bedeutung |
|---|---|
| `period.from`, `period.to` | der ausgewertete Zeitraum, `from` inklusive, `to` exklusiv |
| `leads.created` | Leads, die im Zeitraum angelegt wurden |
| `leads.by_stage` | alle aktuellen Leads je Phase mit Anzahl und Summe des geschätzten Werts |
| `leads.by_source_tool` | im Zeitraum angelegte Leads je Quelle (zum Beispiel `api`, `import`, `extension`) |
| `leads.by_lead_source` | im Zeitraum angelegte Leads je Herkunft aus dem Feld Lead-Quelle, die 20 häufigsten; leer heißt `unknown` |
| `meetings.scheduled` | Leads, die im Zeitraum auf Termin vereinbart gesetzt wurden |
| `meetings.done` | Leads, die im Zeitraum auf Termin stattgefunden gesetzt wurden |
| `deals.created` | Deals, die im Zeitraum angelegt wurden |
| `deals.by_stage` | alle aktuellen Deals je Phase mit Anzahl, Summe der Werte und gewichteter Summe |
| `deals.pipeline_value` | Summe der Werte aller offenen Deals (Angebot senden, Auftrag erhalten), Stand heute |
| `deals.pipeline_weighted` | dieselbe Summe, gewichtet mit der Wahrscheinlichkeit |
| `deals.won_count`, `deals.won_value` | im Zeitraum gewonnene Deals, Anzahl und Summe der Werte |
| `deals.lost_count` | im Zeitraum verlorene Deals |
| `deals.avg_days_to_won` | durchschnittliche Tage vom Anlegen des Deals bis zum Gewinn, nur für die im Zeitraum gewonnenen Deals; `null` ohne gewonnene Deals |
| `conversion.leads_created` | wie `leads.created` |
| `conversion.meetings_scheduled` | wie `meetings.scheduled` |
| `conversion.deals_created` | wie `deals.created` |
| `conversion.deals_won` | wie `deals.won_count` |
| `conversion.meeting_rate` | vereinbarte Termine geteilt durch angelegte Leads; `null` ohne Leads |
| `conversion.deal_rate` | angelegte Deals geteilt durch vereinbarte Termine; `null` ohne Termine |
| `conversion.win_rate` | gewonnene Deals geteilt durch angelegte Deals; `null` ohne Deals |

Die Quoten in `conversion` rechnen mit den Zählern desselben Zeitraums. Sie sind deshalb kein echter Trichter einer Kohorte: ein Termin im September kann zu einem Lead aus dem August gehören.

## Weiter

- [inDeal API: Leads per Schnittstelle anlegen und aktualisieren](https://success.indeal.ai/hc/indeal/articles/indeal-api-leads-anlegen-und-aktualisieren)
- [inDeal Webhooks: Lead- und Deal-Änderungen an andere Systeme senden](https://success.indeal.ai/hc/indeal/articles/indeal-webhooks-lead-aenderungen-senden)
- [MCP: Claude, ChatGPT und Cursor verbinden](https://success.indeal.ai/hc/indeal/articles/ki-assistenten-mit-indeal-verbinden)
