inDeal API: Deals und Auswertungen

Lars Krüger

Lars Krüger

Zuletzt aktualisiert am Sep 26, 2026

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

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. 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.

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.

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&sections=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.

Weiter