Darstellung
CRM – Vollständige API-Referenz
Fach-API für Aktivitäten, Verkaufschancen, Pipeline und die Schnellerfassung. Basis ist https://core-backend.reybex.com/api (Staging: https://io-staging-partner.reybex.com/api). Authentifizierung wie im API: --header "authorization: Basic $TOKEN".
Kunde, Lieferant, Adresse, Bank und Ansprechpartner am Partner stehen unter Kunden- und Lieferantenverwaltung. Ein Angebot aus einer Chance entsteht über die Auftragsverwaltung.
Der normale Schreibweg einer Aktivität ist POST /api/crmAction/. Der einer Chance ist POST /api/crmOpportunity/. Der Body ist der Datensatz selbst, ohne Umschlag.
1. Grundlagen
| Objekt | Rolle |
|---|---|
CrmAction | Telefonat, Aufgabe, Termin, Wiedervorlage |
CrmOpportunity | Verkaufschance mit Positionen und Status |
CrmOpportunityPipeline | Reihenfolge der Status in der Pipeline |
OpportunityStatus | Stufe der Chance |
ContactPerson | Person, getrennt von der Zuordnung am Partner |
Die Zahlen in den Beispielen sind Beispiel-Ids eines Mandanten. 30001 ist Kunde KD-1000. 501 ist die Id des Benutzers, der die Aktivität führt. 100100 ist Artikel ART-1000.
1.1 Suchschlüssel
| Ziel | Suchschlüssel |
|---|---|
| Kunde | customerNo |
| Aktionsart, Status, Priorität, Grund, Chancenstatus | name |
| Land | code, sonst name |
| Artikel an einer neuen Chancenposition | id. Ein Suchschlüssel in items[] legt keine bestehende Position an |
Benutzer und Chancenstatus an der Pipeline werden per id gelesen. Ein Suchschlüssel reicht dort nicht.
1.2 Datum
Aktivitäten akzeptieren unter anderem yyyy-MM-dd, dd.MM.yyyy und yyyy-MM-ddTHH:mm:ss.SSSZ. Für einen Termin mit Uhrzeit yyyy-MM-ddTHH:mm:ss.SSSZ senden.
1.3 Antwort- und Fehlerformat
Lesen einer Aktivität kapselt den Datensatz:
json
{
"data": { "id": 96001, "actionText": "Rückruf Nordlicht" },
"meta": { "domain": "CrmAction", "total": 1 }
}| Situation | HTTP | Körper |
|---|---|---|
| Datensatz nicht gefunden | oft 404 | { "error": "…" } |
| Aktivität ohne Benutzer | Fachlicher Fehler | message.followActionUser.empty.error |
| Chance ohne Nummernkreis | Fachlicher Fehler | object.not.set |
| Angebot ohne Positionen | Fachlicher Fehler | crmOpportunity.createSalesHead.noItems |
| Fehlende Anmeldung | 401 | — |
2. Aktivität
ActionKind.type:
type | Bedeutung |
|---|---|
0 | Termin |
1 | Task |
2 | Wiedervorlage. Die Toolbar zeigt nur diese Art |
3 | Ereignis |
actionKind darf eine Id sein oder { "id": … }. Art, Status, Priorität und Grund lesen: GET /api/domains/actionType, actionStatus, actionPriority, actionReason, actionKind.
ActionStatus.isOpen markiert offene Aktivitäten, isDone erledigte. Die Toolbar blendet erledigte aus.
2.1 Felder
| Feld | Bedeutung |
|---|---|
actionText | Kurztext |
actionTextLong | Langtext |
customer | Partner |
user | Zuständiger Benutzer, Pflicht, per id |
userDelegatedTo | Weitergegeben an |
actionKind | Termin, Task, Wiedervorlage, Ereignis |
actionType | Art, zum Beispiel Anruf |
actionStatus | Offen oder erledigt |
actionPriority | Priorität |
actionReason | Grund |
actionDate, endDate | Beginn und Ende |
customerEmployee | Ansprechpartner am Partner, per id |
isInbound | Eingehend |
progress | Fortschritt 0 bis 100 |
isPinned | Angepinnt |
isInformUser | Die Benutzer in usersToBeInformed erhalten eine Mail |
usersToBeInformed | Liste { "id": … } |
mainAction | Übergeordnete Aktivität. Die Hauptaktion bekommt hasSubActions |
crmOpportunity | Zugehörige Chance |
createAppointment | Termin soll entstehen |
isDelete | Logisch gelöscht |
2.2 Anruf anlegen
POST /api/crmAction/
actionKind ist die Id aus GET /api/domains/actionKind. Der Typ 0 bis 3 steht an dieser Zeile im Feld type und wird nicht selbst gesendet. 12 ist in den Beispielen die Id der Aktionsart Ereignis.
json
{
"actionText": "Rückruf Nordlicht",
"actionTextLong": "Liefertermin der Nachbestellung klären",
"customer": { "customerNo": "KD-1000" },
"user": { "id": 501 },
"actionKind": 12,
"actionType": { "name": "Anruf" },
"actionStatus": { "name": "Offen" },
"actionPriority": { "name": "Hoch" },
"actionDate": "2026-10-13T09:30:00.000Z",
"isInbound": true,
"progress": 0
}Response enthält actionInstance mit der gespeicherten Aktivität, newActionInstance true bei einer Neuanlage und actionIdPrefix mit der Id.
2.3 Wiedervorlage mit Hinweis
json
{
"actionText": "Angebot nachfassen",
"customer": { "customerNo": "KD-1000" },
"user": { "id": 501 },
"actionKind": 11,
"actionStatus": { "name": "Offen" },
"actionDate": "2026-10-20T08:00:00.000Z",
"endDate": "2026-10-20T08:30:00.000Z",
"isInformUser": true,
"usersToBeInformed": [{ "id": 502 }]
}11 ist die Id der Wiedervorlage (type 2). 502 ist ein weiterer Benutzer. Hat er eine E-Mail, geht der Hinweis an diese Adresse.
2.4 Folgeaktion
mainAction.id ist die Id der ersten Aktivität, hier 96001.
json
{
"actionText": "Zweiter Anruf",
"customer": { "customerNo": "KD-1000" },
"user": { "id": 501 },
"actionKind": 12,
"actionDate": "2026-10-15T11:00:00.000Z",
"mainAction": { "id": 96001 }
}Die Hauptaktion wird auf hasSubActions gesetzt. Die Unteraktionen liest GET /api/crmAction/subActionList.
2.5 Lesen, Termin, Löschen
GET /api/crmAction/96001 liest eine Aktivität. Ohne Id ist es die Liste. Query startDate und endDate grenzen den Zeitraum ein.
Toolbar der nächsten Tage, nur offene Wiedervorlagen des angemeldeten Benutzers:
GET /api/crmAction/crmActionListForToolbar
Termin aus der Aktivität: POST /api/crmAction/createAppointment/96001. Antwort { "id": … } ist die Id des Termins. Existiert schon einer: appointment.exist.
Den Termin an das Aktivitätsdatum ziehen: GET /api/crmAction/updateAppointment?id=96001. Antwort { "success": true }.
Löschen ist logisch: DELETE /api/crmAction/
json
{ "crmActions": [96001, 96002] }Response: { "success": "success" }
CSV aller Aktivitäten: GET /api/customer/exportCrmActions. Die Antwort ist die Datei crmActions.csv.
3. Verkaufschance
Ohne opportunityNo vergibt der Nummernkreis aus der Konfiguration die Nummer. Fehlt der Kreis: object.not.set.
probability liegt zwischen 0 und 100. Die Vorschau forecast ist Budget mal Wahrscheinlichkeit geteilt durch 100. Sie wird gelesen, nicht gesendet.
3.1 Felder
| Feld | Bedeutung |
|---|---|
name | Bezeichnung |
opportunityNo | Nummer |
customer | Partner |
status | Stufe, Suchschlüssel name |
statusReason | Begründung des Status |
source, companySource | Herkunft |
products | Freitext der Produkte |
customerBudget | Budget |
probability | Wahrscheinlichkeit 0 bis 100 |
notes | Notiz, wird ins Angebot übernommen |
validFrom, validUntil | Gültigkeit |
isWon | Gewonnen |
user, salesPerson | Betreuer und Verkäufer, per id |
street1, street2, zipcode, city, province, country | Adresse der Chance |
tags | Liste von Tag-Ids oder eine Id-Zeichenkette |
items | Positionen |
isDelete | Logisch gelöscht |
Position CrmOpportunityItem:
| Feld | Bedeutung |
|---|---|
material | Artikel, per id |
variantCode | Variante |
quantity, price | Menge und Preis |
description | Text, wird die Kurzbeschreibung der Angebotsposition |
isDelete | Logisch gelöscht |
Status anlegen: POST /api/domains/opportunityStatus
json
{
"name": "Qualifiziert",
"showInFunnel": true,
"position": 20,
"color": "#2F6FED",
"stagnationEnabled": true,
"stagnationDays": 14
}stagnationDays ist mindestens 1. showInFunnel false blendet die Stufe im Trichter aus.
3.2 Chance mit einer Position
POST /api/crmOpportunity/
json
{
"name": "Nachbestellung Tasche",
"customer": { "customerNo": "KD-1000" },
"status": { "name": "Qualifiziert" },
"customerBudget": 2500,
"probability": 40,
"validFrom": "2026-10-13",
"validUntil": "2026-12-31",
"notes": "Lieferung vor dem 20. Oktober",
"salesPerson": { "id": 501 },
"city": "Berlin",
"zipcode": "10115",
"country": { "code": "DE" },
"items": [
{
"material": { "id": 100100 },
"quantity": 50,
"price": 12.9,
"description": "Tasche schwarz"
}
]
}Response: { "id": 95001 }
Ohne salesPerson.id sucht die Anlage den Verkäufer über Land und PLZ.
3.3 Zwei Positionen und Variante
json
{
"name": "Sortiment Herbst",
"customer": { "customerNo": "KD-1000" },
"status": { "name": "Angebot" },
"probability": 60,
"customerBudget": 1800,
"items": [
{
"material": { "id": 100400 },
"variantCode": "ROT-M",
"quantity": 20,
"price": 8.5
},
{
"material": { "id": 100400 },
"variantCode": "BLAU-L",
"quantity": 15,
"price": 8.5
}
]
}100400 ist der Kopfartikel VAR-4000.
3.4 Status ändern
POST /api/crmOpportunity/changeStatusOfCrmOpportunity
json
{
"crmOpportunityId": 95001,
"status": { "id": 9702 }
}9702 ist die Id des Status Angebot. Alternativ id statt crmOpportunityId und opportunityStatusId statt status.id.
Response
json
{
"id": 95001,
"status": { "id": 9702, "translatedName": "Angebot" }
}Fehlt Chance oder Status: nicht gefunden.
3.5 Angebot erzeugen
POST /api/crmOpportunity/createSalesHead
Die Chance braucht einen Kunden und mindestens eine ungelöschte Position mit Artikel. Die Belegart ist das erste aktive Angebot. Notiz und Positionen werden übernommen. Ein Preis an der Chancenposition ersetzt den berechneten Verkaufspreis.
json
{ "crmOpportunityId": 95001 }Response
json
{
"id": 510200,
"docNumber": "AN-10020",
"docType": { "id": 4101, "name": "Angebot" }
}510200 ist der neue Verkaufsbeleg. Weiterarbeiten unter Auftragsverwaltung.
Ohne Kunde: customer.not.found.error. Ohne Position: crmOpportunity.createSalesHead.noItems. Unbekannte Variante: variant.not.found.
Eine vorhandene Chance an einen vorhandenen Beleg hängen: POST /api/crmOpportunity/addOpportunityToSalesHead
json
{ "crmOpportunityId": 95001, "salesHeadId": 510100 }Response: { "success": true, "message": "" }
Lösen: POST /api/crmOpportunity/removeOpportunityFromSalesHead mit { "salesHeadId": 510100 }.
Dieselbe Chance an alle offenen Belege eines Belegs: POST /api/crmOpportunity/addOpportunityToAllSalesHead mit crmOpportunityId und salesHeadId. Antwort { "success": true }, wenn mindestens ein Beleg getroffen wurde.
Beim Speichern der Chance setzt salesHeadId dieselbe Verknüpfung.
3.6 Person, Löschen, Wiederherstellen
Person zuordnen: POST /api/crmOpportunity/linkToContactPerson
json
{
"contactPersonId": 34001,
"crmOpportunityId": 95001,
"customerId": 30001
}34001 ist die Kontaktperson aus der Ansprechpartner-Anlage. Antwort { "success": true }.
Lösen: POST /api/crmOpportunity/unlinkToContactPerson mit denselben drei Ids.
Löschen ist logisch: DELETE /api/crmOpportunity/ mit { "id": 95001 }. Antwort { "success": true }.
Wiederherstellen: POST /api/crmOpportunity/revert mit { "id": 95001 }.
Verkäufer zu Land und PLZ: GET /api/crmOpportunity/getSalesPerson?countryId=1&zipcode=10115.
4. Pipeline
GET /api/crmOpportunityPipeline/ liefert alle Pipelines mit id, name und opportunityStatuses.
Anlegen: POST /api/crmOpportunityPipeline/
json
{
"name": "Vertrieb",
"opportunityStatuses": [9701, 9702, 9703]
}Response
json
{
"id": 9801,
"data": {
"id": 9801,
"name": "Vertrieb",
"opportunityStatuses": [
{ "id": 9701, "translatedName": "Qualifiziert", "color": "#2F6FED", "position": 20 },
{ "id": 9702, "translatedName": "Angebot", "position": 30 },
{ "id": 9703, "translatedName": "Gewonnen", "position": 40 }
]
}
}opportunityStatuses sind Ids. Eine Stufe einzeln setzen: POST /api/crmOpportunityPipeline/addOpportunityStatus
json
{
"pipeline": { "id": 9801 },
"status": { "id": 9702 }
}Die Antwort enthält pipeline, status und data. Entfernen: POST /api/crmOpportunityPipeline/removeOpportunityStatus mit demselben Körper. Unbekannte Id: nicht gefunden. Fehlende Id: Anfrage ungültig.
5. Schnellerfassung
POST /api/crm/crmMask legt den Partner an oder ändert ihn über customer.id und speichert dazu eine Aktivität und einen Hauptkontakt.
json
{
"customer": {
"name": "Musterladen",
"contactType": { "type": 0 },
"city": "Hamburg",
"country": { "code": "DE" },
"email": "info@musterladen.example"
},
"action": {
"actionText": "Erstkontakt Messe",
"user": { "id": 501 },
"actionKind": 12,
"actionDate": "2026-10-13T14:00:00.000Z"
},
"customerEmployee": {
"email": "info@musterladen.example",
"phone": "+4940123456",
"department": "Einkauf",
"contactPerson": {
"firstname": "Mia",
"surname": "Krüger",
"email": "info@musterladen.example"
}
},
"copyToContactPerson": true
}Kontaktart 0 ist der Interessent. Die Nummer kommt aus dem Nummernkreis der Kontaktart. copyToContactPerson true übernimmt Telefon, E-Mail, Abteilung und Funktion auf die Person. Der Kontakt wird Hauptkontakt.
Response: { "customerId": 30050, "actionId": 96010 }
Vorbelegung der Maske: GET /api/crm/crmMaskDefaultValues. Länderliste: GET /api/crm/countryList.
USt-Id mehrerer Partner prüfen: POST /api/crm/checkCustomerUstId
json
{ "customerIds": [30001, 30050] }Die Antwort trennt success und fails. Fehlen Firmen-USt-Id, Name, USt-Id des Partners, Ort oder PLZ, steht der Partner bei den Fehlern.
Aus einem Interessenten wird ein Kunde über Umwandlung.
6. Kontaktperson
Die Person selbst: POST /api/contactPerson/. Die Zuordnung zum Partner bleibt POST /api/customerEmployee/, siehe Ansprechpartner.
json
{
"firstname": "Lena",
"surname": "Berg",
"email": "einkauf@nordlicht.example",
"phone": "+4930123457",
"birthdate": "1988-04-12"
}Response: { "id": 34001 }
birthdate ist yyyy-MM-dd. Mit Uhrzeit gilt das lange Datumsformat.
Löschen: DELETE /api/contactPerson/ mit { "ids": [34001] }. Antwort { "ids": [34001] }.
vCard mehrerer Partner: POST /api/customer/getDataForVcfFileExport
json
{ "customerIds": [30001] }Die Antwort ist eine Liste von vCards mit Name, Adresse, Telefon und E-Mail.
Import einer vCard-Datei: POST /api/customer/getImportVcfFile als Datei-Upload, Query oder Feld contactType ist die Kontaktart.
7. Weitere Beispiele
7.1 Vom Interessenten zur Chance
- Schnellerfassung mit Kontaktart Interessent, Abschnitt Schnellerfassung.
- Aktivität „Bedarf klären“ an
customerNoder Antwort. - Chance mit derselben Nummer und einer Position.
- Status auf Angebot setzen.
POST /api/crmOpportunity/createSalesHead.
7.2 Chance an eine bestehende Anfrage
Der Beleg 510100 existiert schon.
json
{
"id": 95001,
"salesHeadId": 510100,
"probability": 70,
"notes": "Kunde hat die Menge bestätigt"
}Dieselbe POST /api/crmOpportunity/ ändert die Chance und setzt crmOpportunity am Beleg.
7.3 Aktivität an der Chance
json
{
"actionText": "Angebot besprochen",
"customer": { "customerNo": "KD-1000" },
"user": { "id": 501 },
"actionKind": 12,
"actionDate": "2026-10-14T16:00:00.000Z",
"crmOpportunity": { "id": 95001 },
"progress": 50
}8. Endpoint-Katalog
8.1 Aktivität und Chance
| Methode | Pfad | Bedeutung |
|---|---|---|
GET | /api/crmAction/{id} | Eine Aktivität oder die Liste |
POST | /api/crmAction/ | Anlegen und ändern |
DELETE | /api/crmAction/ | Logisch löschen, Body crmActions |
GET | /api/crmAction/subActionList | Unteraktionen |
GET | /api/crmAction/crmActionListForToolbar | Offene Wiedervorlagen, fünf Tage vor und nach heute |
POST | /api/crmAction/createAppointment/{id} | Termin anlegen |
GET | /api/crmAction/updateAppointment | Termin an das Aktivitätsdatum ziehen, Query id |
GET | /api/crmOpportunity/{id} | Eine Chance oder die Liste |
POST | /api/crmOpportunity/ | Anlegen und ändern |
DELETE | /api/crmOpportunity/ | Logisch löschen, Body id |
POST | /api/crmOpportunity/revert | Wiederherstellen, Body id |
POST | /api/crmOpportunity/changeStatusOfCrmOpportunity | Status setzen |
POST | /api/crmOpportunity/createSalesHead | Angebot aus der Chance |
POST | /api/crmOpportunity/addOpportunityToSalesHead | Chance an einen Beleg |
POST | /api/crmOpportunity/removeOpportunityFromSalesHead | Verknüpfung lösen |
POST | /api/crmOpportunity/addOpportunityToAllSalesHead | Chance an offene Belege |
POST | /api/crmOpportunity/linkToContactPerson | Person zuordnen |
POST | /api/crmOpportunity/unlinkToContactPerson | Person lösen |
GET | /api/crmOpportunity/getSalesPerson | Verkäufer zu Land und PLZ |
GET | /api/crmOpportunity/generateAttrSettings | Attributmaske |
GET | /api/crmOpportunity/getImportMatchingForDynamicCSV | Spaltenzuordnung eines CSV-Imports |
POST | /api/crmOpportunity/importCSV | Chancen importieren |
GET | /api/crmOpportunityPipeline/ | Pipelines |
POST | /api/crmOpportunityPipeline/ | Pipeline speichern |
POST | /api/crmOpportunityPipeline/addOpportunityStatus | Stufe hinzufügen |
POST | /api/crmOpportunityPipeline/removeOpportunityStatus | Stufe entfernen |
8.2 Maske, Person, Import
| Methode | Pfad | Bedeutung |
|---|---|---|
GET | /api/crm/crmMaskDefaultValues | Vorbelegung der Schnellerfassung |
POST | /api/crm/crmMask | Partner, Aktivität und Hauptkontakt |
GET | /api/crm/countryList | Länder |
POST | /api/crm/checkCustomerUstId | USt-Id mehrerer Partner, Body customerIds |
GET | /api/contactPerson/{id} | Eine Person oder die Liste |
POST | /api/contactPerson/ | Person speichern |
DELETE | /api/contactPerson/ | Personen löschen, Body ids |
GET | /api/contactType/{id} | Kontaktart, siehe Kontaktart |
POST | /api/contactType/ | Kontaktart speichern |
GET | /api/contactImport/{id} | Ein Kontaktimport |
POST | /api/contactImport/ | Zuordnung speichern, Körper contactImport und contactImportItems |
DELETE | /api/contactImport/{id} | Import löschen |
POST | /api/contactImport/doContactImport | Import ausführen |
GET | /api/contactImport/getProcessContactImport/{id} | Fortschritt |
GET | /api/contactImport/cancelContactImport/{id} | Import abbrechen |
GET | /api/contactImport/log | Protokoll |
GET | /api/contactImport/contactPropertyNames | Zielfelder |
GET | /api/customer/exportCrmActions | Aktivitäten als crmActions.csv |
POST | /api/customer/getDataForVcfFileExport | vCard, Body customerIds |
POST | /api/customer/getImportVcfFile | vCard-Datei importieren |
POST | /api/customer/crmSaveForConnector | Partner aus dem Konnektor. Körper customers[], Schlüssel ist ourCustomerNumber. Antwort success und fails |
POST | /api/crmIntegration/updateCustomers | Partner zum CRM-System übertragen |
GET | /api/crmIntegration/listCustomers | Übertragbare Partner |
DELETE | /api/crmIntegration/{id} | Übertragungseintrag löschen |
GET | /api/crmIntegrationCustomerTransfer/listCustomersTransfer | Übertragungsprotokoll |
POST | /api/crmIntegrationCustomerTransfer/deleteCustomerTransfer | Protokolleinträge löschen |
POST | /api/crmIntegrationHook/updateCustomer | Eingehender Hook, Partner aktualisieren |
POST | /api/crmIntegrationHook/convertCustomer | Eingehender Hook, Interessent umwandeln |
targetColumn eines Importfelds hat die Form klasse.feld, zum Beispiel customer.name. Der Teil vor dem Punkt ist die Klasse, der Rest das Feld.
9. Häufige Fehler
| Situation | Ursache |
|---|---|
message.followActionUser.empty.error | user.id fehlt oder der Benutzer existiert nicht |
appointment.exist | Zur Aktivität gibt es schon einen Termin |
object.not.set | Kein Nummernkreis für Chancen in der Konfiguration |
customer.not.found.error | Die Chance hat keinen Partner, das Angebot kann nicht entstehen |
crmOpportunity.createSalesHead.noItems | Keine offene Position mit Artikel |
material.not.found.error | Position ohne Artikel |
variant.not.found | variantCode gibt es am Artikel nicht |
edi.salesDocType.not.found.error | Kein aktives Angebot |
| Chance oder Status nicht gefunden | changeStatusOfCrmOpportunity ohne gültige Ids |
| Pipeline nicht gefunden | pipeline.id oder status.id unbekannt |
| Toolbar bleibt leer | Die Aktivität ist erledigt, keine Wiedervorlage oder nicht dem Benutzer zugeordnet |
| Angebot übernimmt den Preis nicht | An der Position ist price leer. Dann gilt der berechnete Verkaufspreis |