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.
Inhalt
- Was ein Deal ist
- Deal anlegen
- Deal lesen und aktualisieren
- Deals auflisten
- Aktivitäten am Deal
- Felder
- Auswertungen
- Kennzahlen im Einzelnen
- 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.
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.
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:
{
"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. Fehltconfidence, 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
200mit"status": "duplicate"und dem bestehenden Deal. Prüfe also einfachstatus, 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.
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 }'
stagewechselt die Phase.wonsetztwon_at,lostsetztlost_atauf jetzt. Die Historie der Phasenwechsel schreibt inDeal selbst.- Bei
lostlohnt sichlost_reason- der Grund erscheint in der App und im Webhook-Ereignisdeal.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.
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; 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.
curl "https://app.indeal.ai/api/v1/reports/summary?from=2026-09-01&to=2026-09-30§ions=deals,conversion" \
-H "Authorization: Bearer indeal_..."
Antwort mit Status 200, hier alle vier Blöcke:
{
"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.