Skip to content

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 ​

ObjektRolle
CrmActionTelefonat, Aufgabe, Termin, Wiedervorlage
CrmOpportunityVerkaufschance mit Positionen und Status
CrmOpportunityPipelineReihenfolge der Status in der Pipeline
OpportunityStatusStufe der Chance
ContactPersonPerson, 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 ​

ZielSuchschlüssel
KundecustomerNo
Aktionsart, Status, Priorität, Grund, Chancenstatusname
Landcode, sonst name
Artikel an einer neuen Chancenpositionid. 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 }
}
SituationHTTPKörper
Datensatz nicht gefundenoft 404{ "error": "…" }
Aktivität ohne BenutzerFachlicher Fehlermessage.followActionUser.empty.error
Chance ohne NummernkreisFachlicher Fehlerobject.not.set
Angebot ohne PositionenFachlicher FehlercrmOpportunity.createSalesHead.noItems
Fehlende Anmeldung401—

2. Aktivität ​

ActionKind.type:

typeBedeutung
0Termin
1Task
2Wiedervorlage. Die Toolbar zeigt nur diese Art
3Ereignis

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 ​

FeldBedeutung
actionTextKurztext
actionTextLongLangtext
customerPartner
userZuständiger Benutzer, Pflicht, per id
userDelegatedToWeitergegeben an
actionKindTermin, Task, Wiedervorlage, Ereignis
actionTypeArt, zum Beispiel Anruf
actionStatusOffen oder erledigt
actionPriorityPriorität
actionReasonGrund
actionDate, endDateBeginn und Ende
customerEmployeeAnsprechpartner am Partner, per id
isInboundEingehend
progressFortschritt 0 bis 100
isPinnedAngepinnt
isInformUserDie Benutzer in usersToBeInformed erhalten eine Mail
usersToBeInformedListe { "id": … }
mainActionÜbergeordnete Aktivität. Die Hauptaktion bekommt hasSubActions
crmOpportunityZugehörige Chance
createAppointmentTermin soll entstehen
isDeleteLogisch 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 ​

FeldBedeutung
nameBezeichnung
opportunityNoNummer
customerPartner
statusStufe, Suchschlüssel name
statusReasonBegründung des Status
source, companySourceHerkunft
productsFreitext der Produkte
customerBudgetBudget
probabilityWahrscheinlichkeit 0 bis 100
notesNotiz, wird ins Angebot übernommen
validFrom, validUntilGültigkeit
isWonGewonnen
user, salesPersonBetreuer und Verkäufer, per id
street1, street2, zipcode, city, province, countryAdresse der Chance
tagsListe von Tag-Ids oder eine Id-Zeichenkette
itemsPositionen
isDeleteLogisch gelöscht

Position CrmOpportunityItem:

FeldBedeutung
materialArtikel, per id
variantCodeVariante
quantity, priceMenge und Preis
descriptionText, wird die Kurzbeschreibung der Angebotsposition
isDeleteLogisch 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 ​

  1. Schnellerfassung mit Kontaktart Interessent, Abschnitt Schnellerfassung.
  2. Aktivität „Bedarf klären“ an customerNo der Antwort.
  3. Chance mit derselben Nummer und einer Position.
  4. Status auf Angebot setzen.
  5. 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 ​

MethodePfadBedeutung
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/subActionListUnteraktionen
GET/api/crmAction/crmActionListForToolbarOffene Wiedervorlagen, fünf Tage vor und nach heute
POST/api/crmAction/createAppointment/{id}Termin anlegen
GET/api/crmAction/updateAppointmentTermin 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/revertWiederherstellen, Body id
POST/api/crmOpportunity/changeStatusOfCrmOpportunityStatus setzen
POST/api/crmOpportunity/createSalesHeadAngebot aus der Chance
POST/api/crmOpportunity/addOpportunityToSalesHeadChance an einen Beleg
POST/api/crmOpportunity/removeOpportunityFromSalesHeadVerknüpfung lösen
POST/api/crmOpportunity/addOpportunityToAllSalesHeadChance an offene Belege
POST/api/crmOpportunity/linkToContactPersonPerson zuordnen
POST/api/crmOpportunity/unlinkToContactPersonPerson lösen
GET/api/crmOpportunity/getSalesPersonVerkäufer zu Land und PLZ
GET/api/crmOpportunity/generateAttrSettingsAttributmaske
GET/api/crmOpportunity/getImportMatchingForDynamicCSVSpaltenzuordnung eines CSV-Imports
POST/api/crmOpportunity/importCSVChancen importieren
GET/api/crmOpportunityPipeline/Pipelines
POST/api/crmOpportunityPipeline/Pipeline speichern
POST/api/crmOpportunityPipeline/addOpportunityStatusStufe hinzufügen
POST/api/crmOpportunityPipeline/removeOpportunityStatusStufe entfernen

8.2 Maske, Person, Import ​

MethodePfadBedeutung
GET/api/crm/crmMaskDefaultValuesVorbelegung der Schnellerfassung
POST/api/crm/crmMaskPartner, Aktivität und Hauptkontakt
GET/api/crm/countryListLänder
POST/api/crm/checkCustomerUstIdUSt-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/doContactImportImport ausführen
GET/api/contactImport/getProcessContactImport/{id}Fortschritt
GET/api/contactImport/cancelContactImport/{id}Import abbrechen
GET/api/contactImport/logProtokoll
GET/api/contactImport/contactPropertyNamesZielfelder
GET/api/customer/exportCrmActionsAktivitäten als crmActions.csv
POST/api/customer/getDataForVcfFileExportvCard, Body customerIds
POST/api/customer/getImportVcfFilevCard-Datei importieren
POST/api/customer/crmSaveForConnectorPartner aus dem Konnektor. Körper customers[], Schlüssel ist ourCustomerNumber. Antwort success und fails
POST/api/crmIntegration/updateCustomersPartner 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/deleteCustomerTransferProtokolleinträge löschen
POST/api/crmIntegrationHook/updateCustomerEingehender Hook, Partner aktualisieren
POST/api/crmIntegrationHook/convertCustomerEingehender 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 ​

SituationUrsache
message.followActionUser.empty.erroruser.id fehlt oder der Benutzer existiert nicht
appointment.existZur Aktivität gibt es schon einen Termin
object.not.setKein Nummernkreis für Chancen in der Konfiguration
customer.not.found.errorDie Chance hat keinen Partner, das Angebot kann nicht entstehen
crmOpportunity.createSalesHead.noItemsKeine offene Position mit Artikel
material.not.found.errorPosition ohne Artikel
variant.not.foundvariantCode gibt es am Artikel nicht
edi.salesDocType.not.found.errorKein aktives Angebot
Chance oder Status nicht gefundenchangeStatusOfCrmOpportunity ohne gültige Ids
Pipeline nicht gefundenpipeline.id oder status.id unbekannt
Toolbar bleibt leerDie Aktivität ist erledigt, keine Wiedervorlage oder nicht dem Benutzer zugeordnet
Angebot übernimmt den Preis nichtAn der Position ist price leer. Dann gilt der berechnete Verkaufspreis

Nur für reybex-Partner. Nicht für Endkunden bestimmt.