Reactive CRM Multi-Vertrags-Lead-Erfassung von der Website ← Integrationsanleitung

Multi-Vertrags-Lead-Erfassung von der Website

Dieses Dokument beschreibt einen einheitlichen API-Vertrag, über den das Website-Backend Lead-Daten, Besucherkontaktdaten und Marketing-UTM-Metriken mit einer einzigen Anfrage an ReactiveCRM sendet.

1. Zweck

Der Website-Integrator muss nicht separat Kontakt, Telefon, E-Mail, Lead und Marketing-Ereignis erstellen. Eine einzige Anfrage soll atomar Folgendes erstellen:

  1. Kontakt;
  2. primäre Telefonnummer des Kontakts;
  3. primäre E-Mail des Kontakts, falls angegeben;
  4. Lead;
  5. Verknüpfung zwischen Kontakt und Lead;
  6. Marketing-Ereignis und UTM-Attribution.

Wenn ein Schritt fehlschlägt, wird die gesamte Anfrage zurückgerollt, und teilweise erstellte Daten werden nicht gespeichert.

2. Endpunkt

http
POST /api/site/leads
Authorization: Bearer <CRM_ACCESS_TOKEN>
Content-Type: application/json

Das Token darf nur vom Website-Backend oder einer Serverless-Funktion gesendet werden. Platzieren Sie das CRM-Token niemals in JavaScript im Browser.

Der Mandant wird aus dem Autorisierungs-Token abgeleitet. Alle übergebenen UUIDs werden im Rahmen dieses Mandanten geprüft.

3. Vollständiger JSON-Vertrag

json
{
  "externalId": "site-form-01J7K9A2M4Y5T6",
  "lead": {
    "leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47",
    "quality": "WARM",
    "message": "Ich möchte eine Beratung zur CRM-Einführung"
  },
  "contact": {
    "firstName": "Ivan",
    "lastName": "Ivanov",
    "phone": "+79991234567",
    "email": "ivan@example.com"
  },
  "marketing": {
    "occurredAt": "2026-09-06T18:00:00Z",
    "visitorId": "visitor-8b7f",
    "sessionId": "session-31ac",
    "source": "website",
    "channel": "paid",
    "utmSource": "google",
    "utmMedium": "cpc",
    "utmCampaign": "summer-consulting",
    "utmContent": "banner-a",
    "utmTerm": "crm consultation",
    "gclid": "EAIaIQobChMI-example",
    "fbclid": null,
    "landingUrl": "https://example.com/consultation",
    "referrer": "https://www.google.com/"
  }
}

4. Anfragefelder

4.1. Stammfelder

FeldTypErforderlichBeschreibung
externalIdstringempfohlenStabile eindeutige ID der Formularübermittlung für Idempotenz
leadobjectjaDaten des zu erstellenden Leads
contactobjectjaDaten der Kontaktperson
marketingobjectneinUTM-Metriken und technische Daten des Marketing-Besuchs

externalId wird vor dem ersten Sendeversuch generiert. Bei Wiederholung der Anfrage nach Timeout oder Netzwerkfehler verwenden Sie denselben Wert.

4.2. Objekt lead

FeldTypErforderlichBeschreibung
leadSourceIduuidjaID der Lead-Quelle im aktuellen Mandanten
qualitystringneinAnfängliche Bewertung: HOT, WARM, COOL oder COLD
messagestringneinNachricht des Besuchers oder Kommentar zur Anfrage

Wenn die Website keine Vorqualifizierung durchführt, sollte das Feld quality besser nicht gesendet werden.

4.3. Objekt contact

FeldTypErforderlichBeschreibung
firstNamestringjaVorname der Kontaktperson
lastNamestringneinNachname der Kontaktperson
phonestringjaPrimäre Telefonnummer; empfohlenes Format E.164
emailstring(email)neinPrimäre E-Mail der Kontaktperson

Der minimale Datensatz für die Bearbeitung einer Anfrage ist firstName und phone.

4.4. Objekt marketing

FeldTypErforderlichBeschreibung
occurredAtdate-timeneinZeitpunkt der Formularübermittlung; wenn nicht angegeben, wird die CRM-Zeit verwendet
visitorIdstringneinAnonyme Besucher-ID
sessionIdstringneinID der Website-Sitzung
sourcestringneinEreignisquelle, Standardwert website
channelstringneinKanal, z.B. paid, organic, social, email, direct
utmSourcestringneinWert von utm_source
utmMediumstringneinWert von utm_medium
utmCampaignstringneinWert von utm_campaign
utmContentstringneinWert von utm_content
utmTermstringneinWert von utm_term
gclidstringneinGoogle Click Identifier
fbclidstringneinMeta/Facebook Click Identifier
landingUrlstringneinURL der Landingpage
referrerstringneinURL der vorherigen Seite

Personenbezogene Daten dürfen nicht im Marketing-Objekt dupliziert werden. Name, Telefon, E-Mail und Nachrichtentext werden nur in contact und lead übermittelt.

5. Minimale Anfrage

json
{
  "externalId": "site-form-550e8400-e29b-41d4-a716-446655440000",
  "lead": {
    "leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47"
  },
  "contact": {
    "firstName": "Ivan",
    "phone": "+79991234567"
  }
}

6. Erfolgreiche Antwort

Erste Anfrage — 201 Created

json
{
  "leadId": "22222222-2222-2222-2222-222222222222",
  "contactId": "33333333-3333-3333-3333-333333333333",
  "phoneId": "44444444-4444-4444-4444-444444444444",
  "emailId": "55555555-5555-5555-5555-555555555555",
  "marketingEventId": "66666666-6666-6666-6666-666666666666",
  "duplicate": false,
  "createdAt": "2026-09-06T18:00:01Z"
}

Wenn keine E-Mail oder Marketingdaten übermittelt wurden, werden die entsprechenden IDs als null zurückgegeben.

Wiederholung mit derselben externalId — 200 OK

json
{
  "leadId": "22222222-2222-2222-2222-222222222222",
  "contactId": "33333333-3333-3333-3333-333333333333",
  "phoneId": "44444444-4444-4444-4444-444444444444",
  "emailId": "55555555-5555-5555-5555-555555555555",
  "marketingEventId": "66666666-6666-6666-6666-666666666666",
  "duplicate": true,
  "createdAt": "2026-09-06T18:00:01Z"
}

Eine wiederholte Anfrage darf keinen zweiten Lead oder Kontakt erstellen.

7. cURL-Beispiel

bash
curl -X POST "$CRM_BASE_URL/api/site/leads" \
  -H "Authorization: Bearer $CRM_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "externalId": "site-form-01J7K9A2M4Y5T6",
    "lead": {
      "leadSourceId": "7b33b18f-55bd-48a5-a8f0-e450a56dde47",
      "quality": "WARM",
      "message": "Rufen Sie mich zurück"
    },
    "contact": {
      "firstName": "Ivan",
      "lastName": "Ivanov",
      "phone": "+79991234567",
      "email": "ivan@example.com"
    },
    "marketing": {
      "utmSource": "google",
      "utmMedium": "cpc",
      "utmCampaign": "crm-demo",
      "landingUrl": "https://example.com/demo"
    }
  }'

8. TypeScript-Schnittstellen

ts
type LeadQuality = 'HOT' | 'WARM' | 'COOL' | 'COLD';

interface SiteLeadRequest {
  externalId?: string;
  lead: {
    leadSourceId: string;
    quality?: LeadQuality;
    message?: string;
  };
  contact: {
    firstName: string;
    lastName?: string;
    phone: string;
    email?: string;
  };
  marketing?: {
    occurredAt?: string;
    visitorId?: string;
    sessionId?: string;
    source?: string;
    channel?: string;
    utmSource?: string;
    utmMedium?: string;
    utmCampaign?: string;
    utmContent?: string;
    utmTerm?: string;
    gclid?: string;
    fbclid?: string;
    landingUrl?: string;
    referrer?: string;
  };
}

interface SiteLeadResponse {
  leadId: string;
  contactId: string;
  phoneId: string;
  emailId: string | null;
  marketingEventId: string | null;
  duplicate: boolean;
  createdAt: string;
}

9. Serverseitiges Beispiel

ts
export async function sendLeadToCrm(payload: SiteLeadRequest): Promise<SiteLeadResponse> {
  const response = await fetch(`${process.env.CRM_BASE_URL}/api/site/leads`, {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.CRM_ACCESS_TOKEN}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify(payload),
  });

  if (!response.ok) {
    const body = await response.text();
    throw new Error(`ReactiveCRM returned ${response.status}: ${body}`);
  }

  return response.json() as Promise<SiteLeadResponse>;
}

10. Fehler

HTTPUrsacheMaßnahme für den Integrator
400Formatfehler, Pflichtfeld fehlt, ungültige E-Mail/Telefon/qualityDaten korrigieren; nicht automatisch ohne Änderungen wiederholen
401Token fehlt oder ist ungültigIntegrationstoken aktualisieren
403Kein Zugriff auf Mandanten oder OperationBenutzer und Integrationsrolle prüfen
404leadSourceId im aktuellen Mandanten nicht gefundenQuellen-ID in den Website-Einstellungen aktualisieren
409externalId bereits mit inkompatibler Anfrage verknüpftID-Generierung und Integrationsprotokoll prüfen
5xxVorübergehender CRM-FehlerDieselbe Anfrage mit derselben externalId wiederholen

Beispiel für einen Validierungsfehler:

json
{
  "status": 400,
  "error": "Bad Request",
  "message": "contact.phone must not be blank",
  "path": "/api/site/leads"
}

11. Idempotenz

12. Kurzanleitung für Website-Entwickler

  1. Speichern Sie bei der ersten Sitzung UTM-Tags, gclid, fbclid, URL der Landingpage und Referrer.
  2. Generieren Sie bei der Formularübermittlung eine stabile externalId.
  3. Senden Sie das Formular an das Website-Backend.
  4. Das Backend fügt das CRM-Token hinzu und ruft POST /api/site/leads auf.
  5. Bei 201 oder 200 mit duplicate: true gilt die Anfrage als zugestellt.
  6. Bei Timeout oder 5xx wiederholen Sie die Anfrage mit derselben externalId.
  7. Senden Sie das CRM-Token niemals direkt aus dem Browser.

13. Was der CRM-Manager sieht

Nach einer erfolgreichen Anfrage erscheint im CRM ein Lead, der:

Dieser Datensatz reicht aus, damit der Manager die Anfrage sieht, den Kontakt anruft und den Lead qualifizieren kann.