API - Kunden & Kontakte Admin
📕 Für Administratoren und Entwickler
Über die spiritflow Public API können Kunden und deren Kontaktpersonen programmatisch verwaltet werden. Alle Endpunkte sind unter dem Basis-Pfad /api/v1/customers erreichbar und erfordern einen gültigen API-Key mit dem entsprechenden Scope.
Referenzwerte
Kunden-Status-Werte
| Status | Bedeutung |
|---|---|
ACTIVE | Aktiver Kunde |
LEAD | Lead / Interessent |
PROSPECT | Potenzieller Kunde |
LOST | Verlorener Kunde |
INACTIVE | Inaktiv |
SUSPENDED | Gesperrt |
ARCHIVED | Archiviert |
Kunden-Typen
| Typ | Bedeutung |
|---|---|
COMPANY | Unternehmen |
INDIVIDUAL | Privatperson |
Kunden auflisten
GET /api/v1/customers
Erforderlicher Scope: customers:read
Query-Parameter:
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
status | String | Nein | Filtern nach Status (z.B. ACTIVE) |
customerType | String | Nein | Filtern nach Typ (COMPANY oder INDIVIDUAL) |
search | String | Nein | Volltextsuche in Name, E-Mail, Kundennummer |
createdAfter | String (ISO 8601) | Nein | Nur Kunden, die nach diesem Zeitpunkt erstellt wurden |
createdBefore | String (ISO 8601) | Nein | Nur Kunden, die vor diesem Zeitpunkt erstellt wurden |
page | Integer | Nein | Seite (Standard: 0) |
size | Integer | Nein | Einträge pro Seite, max. 100 (Standard: 20) |
sort | String | Nein | Sortierung (Standard: name,asc). Erlaubte Felder: createdAt, updatedAt, name, customerNumber, email, city, status |
Antwort (200 OK):
{
"data": [
{
"id": 12,
"name": "ACME GmbH",
"customerNumber": "KD-00042",
"email": "kontakt@acme-gmbh.de",
"phone": "+49 40 123456",
"mobile": null,
"street": "Musterstrasse 1",
"postalCode": "20095",
"city": "Hamburg",
"country": "Deutschland",
"website": "https://www.acme-gmbh.de",
"description": "Langjaehriger Kunde seit 2018.",
"taxNumber": "48/123/45678",
"vatId": "DE123456789",
"status": "ACTIVE",
"industry": "Software",
"customerType": "COMPANY",
"customerSince": "2018-06-01T00:00:00Z",
"createdAt": "2018-06-01T09:00:00Z",
"updatedAt": "2025-01-15T11:30:00Z"
}
],
"pagination": {
"page": 0,
"size": 20,
"totalElements": 34,
"totalPages": 2
},
"meta": {
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-03-01T10:30:00Z"
}
}
cURL-Beispiel:
curl -X GET "https://app.spiritflow.team/api/v1/customers?status=ACTIVE&sort=name,asc" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Einzelnen Kunden abrufen
GET /api/v1/customers/{id}
Erforderlicher Scope: customers:read
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
id | Long | ID des Kunden |
Antwort (200 OK): Einzelnes Kunden-Objekt (gleiche Struktur wie in der Liste)
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 404 | NOT_FOUND | Kunde nicht gefunden oder gehoert nicht zu diesem Mandanten |
cURL-Beispiel:
curl -X GET "https://app.spiritflow.team/api/v1/customers/12" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Kunden erstellen
POST /api/v1/customers
Erforderlicher Scope: customers:write
Request-Body:
| Feld | Typ | Pflicht | Standard | Beschreibung |
|---|---|---|---|---|
name | String | Ja | - | Name des Kunden (max. 255 Zeichen) |
customerNumber | String | Nein | null | Kundennummer (max. 50 Zeichen) |
email | String | Nein | null | E-Mail-Adresse (max. 255 Zeichen, muss gültig sein) |
phone | String | Nein | null | Telefonnummer (max. 50 Zeichen) |
mobile | String | Nein | null | Mobilnummer (max. 50 Zeichen) |
street | String | Nein | null | Strasse und Hausnummer (max. 255 Zeichen) |
postalCode | String | Nein | null | Postleitzahl (max. 10 Zeichen) |
city | String | Nein | null | Stadt (max. 100 Zeichen) |
country | String | Nein | null | Land (max. 100 Zeichen) |
website | String | Nein | null | Webseite (max. 100 Zeichen) |
description | String | Nein | null | Notizen / Beschreibung |
taxNumber | String | Nein | null | Steuernummer (max. 50 Zeichen) |
vatId | String | Nein | null | USt-IdNr. (max. 50 Zeichen) |
status | String | Nein | ACTIVE | Status (siehe Referenzwerte oben) |
industry | String | Nein | null | Branche (max. 100 Zeichen) |
customerType | String | Nein | COMPANY | Kundentyp (COMPANY oder INDIVIDUAL) |
Beispiel-Request:
{
"name": "Mustermann GmbH",
"customerNumber": "KD-00099",
"email": "info@mustermann-gmbh.de",
"phone": "+49 30 987654",
"street": "Berliner Allee 42",
"postalCode": "10115",
"city": "Berlin",
"country": "Deutschland",
"website": "https://www.mustermann-gmbh.de",
"vatId": "DE987654321",
"status": "LEAD",
"industry": "Handwerk",
"customerType": "COMPANY"
}
Antwort (201 Created):
{
"data": {
"id": 35,
"name": "Mustermann GmbH",
"customerNumber": "KD-00099",
"email": "info@mustermann-gmbh.de",
"phone": "+49 30 987654",
"mobile": null,
"street": "Berliner Allee 42",
"postalCode": "10115",
"city": "Berlin",
"country": "Deutschland",
"website": "https://www.mustermann-gmbh.de",
"description": null,
"taxNumber": null,
"vatId": "DE987654321",
"status": "LEAD",
"industry": "Handwerk",
"customerType": "COMPANY",
"customerSince": "2025-03-01T10:30:00Z",
"createdAt": "2025-03-01T10:30:00Z",
"updatedAt": "2025-03-01T10:30:00Z"
},
"meta": {
"requestId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"timestamp": "2025-03-01T10:30:00Z"
}
}
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 400 | VALIDATION_ERROR | Pflichtfeld fehlt, E-Mail ungültig oder Feldlimit überschritten |
cURL-Beispiel:
curl -X POST "https://app.spiritflow.team/api/v1/customers" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Mustermann GmbH",
"email": "info@mustermann-gmbh.de",
"status": "LEAD",
"customerType": "COMPANY"
}'
Kunden aktualisieren
PUT /api/v1/customers/{id}
Erforderlicher Scope: customers:write
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
id | Long | ID des Kunden |
Request-Body (alle Felder optional):
Gleiche Felder wie beim Erstellen, alle optional. Nur übermittelte Felder werden aktualisiert.
Beispiel-Request:
{
"status": "ACTIVE",
"email": "neuemail@mustermann-gmbh.de",
"phone": "+49 30 112233"
}
Antwort (200 OK): Aktualisiertes Kunden-Objekt
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 400 | VALIDATION_ERROR | Ungültige Feldwerte |
| 404 | NOT_FOUND | Kunde nicht gefunden |
cURL-Beispiel:
curl -X PUT "https://app.spiritflow.team/api/v1/customers/35" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"status": "ACTIVE",
"email": "neuemail@mustermann-gmbh.de"
}'
Kunden löschen (archivieren)
DELETE /api/v1/customers/{id}
Erforderlicher Scope: customers:write
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
id | Long | ID des Kunden |
Antwort: 204 No Content
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 404 | NOT_FOUND | Kunde nicht gefunden |
cURL-Beispiel:
curl -X DELETE "https://app.spiritflow.team/api/v1/customers/35" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Kontaktpersonen
Basis-Pfad: /api/v1/customers/{customerId}/contacts
Kontaktpersonen sind Ansprechpartner eines Kunden, zum Beispiel Geschäftsführer, Projektleiter oder Buchhaltung. Sie sind immer einem Kunden zugeordnet.
Kontaktpersonen auflisten
GET /api/v1/customers/{customerId}/contacts
Erforderlicher Scope: customers:read
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
customerId | Long | ID des Kunden |
Antwort-Felder:
| Feld | Typ | Beschreibung |
|---|---|---|
id | number | Eindeutige ID der Kontaktperson |
customerId | number | ID des zugehoerigen Kunden |
salutation | string? | Anrede |
firstName | string | Vorname |
lastName | string | Nachname |
position | string? | Position / Funktion |
department | string? | Abteilung |
email | string? | E-Mail-Adresse |
phone | string? | Telefonnummer |
mobile | string? | Mobilnummer |
isPrimary | boolean | Ist Hauptansprechpartner |
notes | string? | Notizen |
preferredLanguage | string? | Bevorzugte Sprache (ISO-Code) |
createdAt | string | Erstellungszeitpunkt (ISO 8601) |
updatedAt | string | Letzter Aenderungszeitpunkt (ISO 8601) |
cURL-Beispiel:
curl -X GET "https://app.spiritflow.team/api/v1/customers/12/contacts" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Einzelne Kontaktperson abrufen
GET /api/v1/customers/{customerId}/contacts/{contactId}
Erforderlicher Scope: customers:read
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
customerId | Long | ID des Kunden |
contactId | Long | ID der Kontaktperson |
Antwort (200 OK): Einzelnes Kontaktpersonen-Objekt (gleiche Felder wie in der Liste)
cURL-Beispiel:
curl -X GET "https://app.spiritflow.team/api/v1/customers/12/contacts/7" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Kontaktperson erstellen
POST /api/v1/customers/{customerId}/contacts
Erforderlicher Scope: customers:write
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
customerId | Long | ID des Kunden |
Request-Body:
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
firstName | string | Ja | Vorname (max. 100 Zeichen) |
lastName | string | Ja | Nachname (max. 100 Zeichen) |
salutation | string | Nein | Anrede (max. 20 Zeichen) |
position | string | Nein | Position / Funktion (max. 200 Zeichen) |
department | string | Nein | Abteilung (max. 100 Zeichen) |
email | string | Nein | E-Mail-Adresse |
phone | string | Nein | Telefonnummer (max. 50 Zeichen) |
mobile | string | Nein | Mobilnummer (max. 50 Zeichen) |
isPrimary | boolean | Nein | Hauptansprechpartner (Standard: false) |
notes | string | Nein | Notizen |
preferredLanguage | string | Nein | Sprachcode, z.B. de oder en (Standard: de) |
Antwort (201 Created): Gleiche Felder wie bei der Kontaktliste.
cURL-Beispiel:
curl -X POST "https://app.spiritflow.team/api/v1/customers/15/contacts" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"firstName": "Andrea",
"lastName": "Bauer",
"position": "Geschäftsführerin",
"email": "a.bauer@acme.de",
"phone": "+49 221 12345678",
"isPrimary": true
}'
Kunden-Logo
Logo hochladen
POST /api/v1/customers/{id}/logo
Lädt ein Logo für den Kunden hoch. Das Bild wird auf max. 512px verkleinert. Unterstützte Formate: JPEG, PNG, WebP.
Erforderlicher Scope: customers:write
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
id | Long | ID des Kunden |
Request: Multipart Form-Data mit dem Feld file.
Antwort (200 OK):
{
"data": {
"logoUrl": "/api/attachments/customer-logos/50_1234567890.png"
}
}
Die Logo-URL ist öffentlich ohne Authentifizierung abrufbar.
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 400 | BAD_REQUEST | Dateiformat nicht unterstützt oder Datei fehlt |
| 404 | NOT_FOUND | Kunde nicht gefunden |
cURL-Beispiel:
curl -X POST "https://app.spiritflow.team/api/v1/customers/12/logo" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-F "file=@/pfad/zum/logo.png"
Logo entfernen
DELETE /api/v1/customers/{id}/logo
Entfernt das Logo eines Kunden.
Erforderlicher Scope: customers:write
Pfad-Parameter:
| Parameter | Typ | Beschreibung |
|---|---|---|
id | Long | ID des Kunden |
Antwort: 204 No Content
Fehler-Codes:
| HTTP-Status | Code | Beschreibung |
|---|---|---|
| 404 | NOT_FOUND | Kunde nicht gefunden |
cURL-Beispiel:
curl -X DELETE "https://app.spiritflow.team/api/v1/customers/12/logo" \
-H "X-API-Key: sf_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"