Die Partner-API
Kunden und Lizenzen automatisch mit Ihrem CRM abgleichen: Schlüssel, Aufrufe, Antworten und Fehlercodes.
1. Wofür die API da ist
Mit der API gleichen Sie Ihre Kunden und deren Lizenzen automatisch mit Ihrem CRM ab. Alles, was die API kann, geht auch von Hand im Partnerportal.
Zuordnungen veröffentlichen und Schlüssel verwalten erledigt eine angemeldete Person im Portal. Diese Aufrufe nehmen keinen Schlüssel an.
2. Schlüssel und Anmeldung
Erstellen Sie im Partnerportal einen API-Schlüssel. Er wird direkt nach dem Erstellen angezeigt und lässt sich danach nicht erneut anzeigen.
Sie können mehrere Schlüssel gleichzeitig nutzen. Zum Austauschen erstellen Sie einen neuen, stellen Ihr System um und widerrufen den alten. Ein widerrufener Schlüssel ist sofort ungültig.
Senden Sie den Schlüssel im Header x-provider-key oder als Authorization: Bearer mf_…. Die Basisadresse ist https://app.flow.jumoca.de/v1/provider, Anfragen und Antworten sind JSON. Die Anzahl der Anfragen pro Minute ist begrenzt und gilt für alle Ihre Schlüssel zusammen.
Ein GET auf die Basisadresse liefert den Überblick: Ihre Schlüssel, Kunden, veröffentlichten Zuordnungen und die Zahl der berechneten Lizenzen. Dort stehen auch die IDs Ihrer Kunden.
curl https://app.flow.jumoca.de/v1/provider \
-H "x-provider-key: mf_..." 3. Domains prüfen
POST /customers/check prüft eine Liste von Domains. Statt einer Domain können Sie auch eine E-Mail-Adresse senden, dann zählt der Teil nach dem @. Die Prüfung legt nichts an.
curl -X POST https://app.flow.jumoca.de/v1/provider/customers/check \
-H "x-provider-key: mf_..." \
-H "content-type: application/json" \
-d '{ "domains": ["beispiel.de", "beispiel-gruppe.de", "gmail.com"] }' Jedes Ergebnis hat einen Status. found heißt, hinter der Domain steht eine Microsoft-365-Organisation. not_found heißt, dort steht keine, bei diesem Kunden kann sich also noch niemand anmelden. invalid ist keine gültige Domain und own_tenant eine Domain Ihrer eigenen Organisation, die sich nicht hinzufügen lässt.
sameAs nennt die anderen Domains derselben Anfrage, die zur selben Organisation gehören. Sie gehören in einen gemeinsamen Eintrag.
{
"results": [
{ "domain": "beispiel.de", "status": "found", "sameAs": ["beispiel-gruppe.de"] },
{ "domain": "beispiel-gruppe.de", "status": "found", "sameAs": ["beispiel.de"] },
{ "domain": "gmail.com", "status": "not_found", "sameAs": [] }
]
} 4. Kunden anlegen und aktualisieren
POST /customers legt Kunden an oder aktualisiert vorhandene. Sie können einen einzelnen Kunden senden oder eine Liste. domains nennt mindestens eine Domain des Kunden, reference ist Ihre eigene Kennung, meist die Nummer aus dem CRM, und seats die Zahl der Lizenzen.
Mit seats kaufen Sie Lizenzen. Ohne seats behält ein vorhandener Kunde seine Lizenzen, und ein neuer erhält keine. Dieselbe Liste noch einmal zu senden, ändert nichts.
curl -X POST https://app.flow.jumoca.de/v1/provider/customers \
-H "x-provider-key: mf_..." \
-H "content-type: application/json" \
-d '{
"customers": [
{ "domains": ["beispiel.de", "beispiel-gruppe.de"], "reference": "CRM-4417", "seats": 5 },
{ "domains": ["muster-gmbh.de"], "reference": "CRM-4418", "seats": 2 }
]
}' Die Antwort zählt neu angelegte Kunden unter added und alle übrigen unter unchanged, auch wenn sich ihre Lizenzen geändert haben.
{
"added": 1,
"unchanged": 1,
"warnings": [{ "domain": "muster-gmbh.de", "reason": "tenant_not_resolvable" }]
} 5. Warnungen
Eine fehlerhafte Domain hält den Rest der Liste nicht auf. Jede Domain, die nicht wie gesendet übernommen wird, steht unter warnings mit einem Grund.
tenant_not_resolvable: Hinter der Domain steht noch keine Microsoft-365-Organisation, oder sie ist ungültig. Gültige Domains speichern wir und prüfen sie regelmäßig erneut. Sobald sich die Organisation findet, wird der Kunde aktiv.
own_tenant: Die Domain wird nicht übernommen.
multiple_organisations: Die Domains eines Eintrags gehören zu mehreren Organisationen. Die erste in Ihrer Liste bekommt die Lizenzen, die anderen keine. Setzen Sie deren Lizenzen mit dem Aufruf aus dem nächsten Abschnitt.
store_failed: Der Eintrag ließ sich nicht speichern. Senden Sie ihn noch einmal.
6. Lizenzen eines Kunden setzen
PUT /customers/{id}/seats setzt die Zahl der Lizenzen eines Kunden.
curl -X PUT https://app.flow.jumoca.de/v1/provider/customers/{id}/seats \
-H "x-provider-key: mf_..." \
-H "content-type: application/json" \
-d '{ "seats": 8 }' Die Antwort ist der Kunde, wie er jetzt steht. status ist active, pending_resolution, solange sich keine Organisation findet, oder removed.
{
"id": "66f1...",
"domains": ["beispiel.de", "beispiel-gruppe.de"],
"reference": "CRM-4417",
"status": "active",
"seats": 8,
"removalScheduledAt": null,
"addedAt": "2026-09-02T08:14:03.000Z"
} 7. Kunden entfernen
DELETE /customers/{id} entfernt einen Kunden und antwortet mit 204. Sein Zugang endet nicht sofort, removalScheduledAt nennt das Datum. Wenn Sie den Kunden vorher erneut mit POST /customers senden, wird die Entfernung aufgehoben.
curl -X DELETE https://app.flow.jumoca.de/v1/provider/customers/{id} \
-H "x-provider-key: mf_..." 8. Fehler
Fehler kommen mit einem HTTP-Status und einem festen Code im Body.
400 invalid_json oder invalid_body: Die Anfrage ist kein gültiges JSON oder hat nicht das beschriebene Format. details.issues nennt die betroffenen Stellen.
401 unauthorized: Der Schlüssel fehlt, ist falsch oder widerrufen, oder der Aufruf verlangt eine angemeldete Person.
403 account_closed: Ihr Konto ist geschlossen.
404 customer_not_found: Einen Kunden mit dieser ID gibt es nicht.
429 rate_limited: Das Anfragelimit ist erreicht. Versuchen Sie es nach den Sekunden in details.retryAfterSeconds erneut.
503 billing_sync_failed: Die Abrechnung ließ sich nicht aktualisieren, und es hat sich nichts geändert. Senden Sie den Aufruf später noch einmal.
{ "error": { "code": "customer_not_found", "message": "Customer not found" } }