Solve+Partner-API

Partner-API v1

Mit der Partner-API lesen freigegebene Software-Anbieter Daten ihrer gemeinsamen Kunden aus SolvePlus (S+): Termine, Schichten, Zeiteinträge, Rapporte, Kunden, Einsatzorte und Personal-Basisdaten. Jeder Zugriff braucht die Zustimmung des Inhabers der jeweiligen Firma.

Basis-URL: https://splus-app.de/api/partner/v1 · Format: JSON (UTF-8) · Zeiten: ISO-8601 in UTC · Fehler: application/problem+json

Die Spezifikation ist im Aufbau: Einzelne Felder können sich noch an die Implementierung angleichen. Ignorieren Sie unbekannte Felder – neue optionale Felder sind keine inkompatible Änderung.

Authentifizierung: OAuth 2.0 mit PKCE

Die API nutzt den Authorization-Code-Flow mit PKCE (Methode S256 ist Pflicht). Sie brauchen eine App im Partnerportal mit Client-ID (spc_…), Client-Secret und exakt hinterlegter https-Redirect-URI.

  1. Verifier und Challenge erzeugen: zufälliger code_verifier (43–128 Zeichen), daraus code_challenge = BASE64URL(SHA256(code_verifier)). Den Verifier geheim halten.
  2. Browser des Inhabers weiterleiten auf /oauth/autorisieren mit state (Schutz vor CSRF – prüfen Sie ihn bei der Rückkehr).
  3. Inhaber meldet sich an und stimmt zu. Er sieht Ihre Firma, den Zweck, die Datenarten, das Hosting-Land und die Scopes. Danach kommt der Browser mit ?code=…&state=… (oder ?error=access_denied) zurück.
  4. Code tauschen: innerhalb von 2 Minuten, einmalig, serverseitig mit Client-Secret und code_verifier.
  5. API aufrufen mit Authorization: Bearer spa_…. Access-Tokens gelten 15 Minuten.
  6. Erneuern mit dem Refresh-Token (30 Tage, rotierend). Speichern Sie jedes Mal das neue Refresh-Token.

Beispiele (curl)


          

          

          

          

          

        

Scopes

Wirksam ist immer die Schnittmenge aus angefordertem Scope, Freigabe der App durch den Betreiber und Zustimmung des Inhabers. Außerdem muss das zugehörige Modul beim Mandanten gebucht sein – sonst antwortet der Endpunkt mit 403 scope_fehlt.

…

Endpunkte

Spezifikation wird geladen …

Pagination

Listen-Endpunkte liefern {"daten": [...], "naechster_cursor": "…" | null}. Übergeben Sie naechster_cursor unverändert als ?cursor=, bis er null ist. limit liegt zwischen 1 und 100 (Standard 50).

Für den Abgleich nur geänderter Daten: ?aenderung_seit=2026-09-01T00:00:00Z. Merken Sie sich den größten geaendert_am-Wert der letzten Seite als Startpunkt für den nächsten Lauf. Besser noch: Webhooks nutzen und nur bei Bedarf abrufen.


        

Rate-Limits und Kontingente

  • Jede Antwort enthält X-RateLimit-Limit und X-RateLimit-Remaining (Anfragen pro Minute).
  • Überschreitung: 429 mit code: rate_limit und Retry-After (Sekunden). Warten, nicht sofort wiederholen.
  • Das Monatskontingent richtet sich nach Ihrem Tarif. Ist es aufgebraucht: 429 kontingent_erschoepft.
  • Auffällige Nutzung (z. B. massenhaftes Abziehen aller Daten, viele Fehler) führt zu Drosselung oder Sperre der App.

Fehler

Fehler kommen als application/problem+json (RFC 9457). Werten Sie code aus, nicht den Text. type verweist auf die passende Zeile dieser Tabelle.


          
codeHTTPBedeutung
invalid_token401Access-Token fehlt, ist abgelaufen, widerrufen oder unbekannt. Mit dem Refresh-Token ein neues holen.
scope_fehlt403Der nötige Scope fehlt – im Token, in der App-Freigabe, in der Zustimmung oder das Modul ist beim Mandanten nicht gebucht.
app_gesperrt403Die App ist gesperrt (Betreiber, Zahlung, Auffälligkeit oder eigener Not-Aus).
partner_gesperrt403Ihr Partnerzugang ist gesperrt oder nicht (mehr) freigegeben.
mandant_nicht_erlaubt403Dieser Mandant ist für die App nicht erreichbar (z. B. Sandbox-App gegen echten Mandanten oder Live noch nicht freigegeben).
mandant_gesperrt503Der Mandant ist vorübergehend gesperrt. Später erneut versuchen.
partner_api_aus503Die Partner-API ist plattformweit abgeschaltet (Not-Aus). Retry-After beachten.
rate_limit429Zu viele Anfragen pro Minute. Retry-After abwarten.
kontingent_erschoepft429Das Monatskontingent Ihres Tarifs ist aufgebraucht.
ip_nicht_erlaubt403Die Anfrage kommt von einer IP außerhalb der IP-Allowlist der App.
nicht_gefunden404Der Datensatz existiert nicht oder ist für diesen Mandanten nicht sichtbar.
validierung422Ungültige Parameter (z. B. limit außerhalb 1–100, aenderung_seit kein ISO-8601, ungültiger Cursor).

OAuth-Endpunkte (/oauth/token, /oauth/revoke) antworten nach RFC 6749 mit {"error": "invalid_grant"} usw.

Webhooks

Im Partnerportal legen Sie je App Webhooks an (Ziel-URL nur https, Ereignisse wählen). Das Signaturgeheimnis wird nur einmal angezeigt. Wir senden „dünne" Ereignisse – nur Typ und IDs. Die Daten holen Sie anschließend mit einem gültigen Token über die API; dabei greifen Scopes und Zustimmung erneut.

  • Header: X-SPlus-Signatur: t=<Unix-Zeit>,v1=<hex>, X-SPlus-Ereignis, X-SPlus-Zustellung.
  • Signatur: HMAC-SHA256 über "<t>.<roher Body>" mit dem Geheimnis. Vergleich in konstanter Zeit, Zeittoleranz 5 Minuten (Schutz vor Wiedereinspielung).
  • Antworten Sie schnell mit 2xx und verarbeiten Sie asynchron. Andere Antworten oder Zeitüberschreitung gelten als Fehlschlag und werden mit wachsendem Abstand wiederholt.
  • Zustellung „mindestens einmal": Ereignisse können doppelt kommen – anhand der Ereignis-id entdoppeln. Die Reihenfolge ist nicht garantiert; nutzen Sie geaendert_am.

Ereignisse

…


          

Signatur prüfen – PHP


          

Signatur prüfen – Node.js


        

Sicherheitsregeln

  • Tokens sind kurzlebig: Access-Token 15 Minuten, Autorisierungscode 2 Minuten und nur einmal verwendbar.
  • Refresh-Tokens rotieren: Jede Erneuerung liefert ein neues Refresh-Token, das alte wird ungültig. Wird ein bereits ersetztes Refresh-Token erneut benutzt, sperren wir die ganze Token-Kette (Diebstahlschutz) – der Inhaber muss neu zustimmen.
  • Redirect-URIs: nur https und exakter Vergleich (keine Platzhalter, keine zusätzlichen Pfade oder Parameter).
  • Geheimnisse: Client-Secret und Webhook-Geheimnis nur serverseitig, nie in Apps, Browsern oder Repositories. Bei Verdacht sofort neu erzeugen.
  • Widerruf durch den Inhaber jederzeit: Danach antwortet die API mit 401 invalid_token. Löschen Sie dann die Tokens des Mandanten.
  • Datensparsamkeit: nur Scopes anfordern, die Sie brauchen; keine sensiblen Personaldaten über die API.
  • IP-Allowlist (optional je App) und Not-Aus im Partnerportal bei Vorfällen. Melden Sie Sicherheitsvorfälle unverzüglich.
  • Jeder Aufruf wird protokolliert (App, Mandant, Endpunkt, Status, Menge) – ohne Inhalte.

Sandbox, Live und Kosten

  • Sandbox-Pflicht: Jede neue App startet in der Sandbox und erreicht nur Demo-Mandanten mit Testdaten. Die Demo-Firmen-ID steht im Partnerportal.
  • Live-Freigabe: nach einer Mindestzahl erfolgreicher Sandbox-Aufrufe und mit gebuchtem Tarif beantragen; der Betreiber entscheidet. Schreibende Scopes werden gesondert geprüft.
  • Kosten: Die Nutzung ist kostenpflichtig (Tarif je App mit inklusiven Aufrufen, darüber nach Verbrauch). Alle Preise netto zzgl. Umsatzsteuer, nur für Unternehmen. Bei Zahlungsverzug wird die App gesperrt; Daten bleiben erhalten.
  • Rechtliches: Auftragsverarbeitungsvertrag (Art. 28 DSGVO) mit jedem Kunden, benannter Sicherheitskontakt, Angabe des Hosting-Landes.

Zum Partnerportal

Versionierung

Die Hauptversion steht im Pfad (/v1). Innerhalb einer Version kommen nur kompatible Erweiterungen hinzu (neue Endpunkte, neue optionale Felder, neue Ereignisse). Abgekündigte Endpunkte senden Deprecation und Sunset; zwischen Abkündigung und Abschaltung liegen mindestens 6 Monate, und wir informieren Ihren Ansprechpartner per E-Mail. Der Header Idempotency-Key ist für künftige schreibende Endpunkte reserviert.