Zum Inhalt springen

Daten synchron halten

Viele Integrationen spiegeln Benutzer, Kursteilnahmen oder Kurse in ein anderes System, zum Beispiel eine HR-Software oder ein Berichtswesen. Wiederholt komplette Listen herunterzuladen ist langsam und verbraucht unnötig Durchsatzkontingent: Die meisten Objekte haben sich seit dem letzten Lauf gar nicht geändert.

Zwei Mechanismen ersetzen diese Vollabrufe:

  • Webhooks schicken Ihnen ein Event, sobald etwas passiert, zum Beispiel wenn eine Kursteilnahme abgeschlossen wird.
  • Delta-Abfragen holen genau die Objekte, die sich seit einem Zeitpunkt geändert haben, über den unten beschriebenen Filter updated_after.

Der empfohlene Sync-Weg ist Webhooks plus Delta-Abfragen: Reagieren Sie auf Events, sobald sie eintreffen, und nutzen Sie eine Delta-Abfrage für den Erstimport und als regelmäßigen Abgleich. Kein Push-Kanal ist gegen verpasste Zustellungen gefeit, und Webhook-Events gibt es derzeit für Benutzer und Kursteilnahmen; Änderungen an Kursen, Gruppen und den übrigen Ressourcen fängt Ihre Delta-Abfrage auf. Reines Polling mit Delta-Abfragen ist der Fallback, wenn Ihr System keine Webhooks empfangen kann.

Benutzer, Gruppen, Kurse, Kurskategorien und Kursteilnahmen tragen den Zeitstempel updated_at, und ihre Listen-Endpunkte akzeptieren den Query-Parameter updated_after: Die Antwort enthält dann nur Objekte, deren updated_at zum angegebenen Zeitpunkt oder später liegt (der Zeitpunkt selbst zählt mit). Kombinieren Sie ihn mit ordering=updated_at, um die ältesten Änderungen zuerst zu erhalten:

Terminal-Fenster
curl "https://api.schulungstool.de/v1/users/?updated_after=2026-01-15T12:00:00&ordering=updated_at" \
-H "Authorization: Token <API-Schlüssel>"

Zeitstempel sind deutsche Zeit ohne UTC-Offset, genau wie die API sie zurückgibt; ein ISO-8601-Wert mit Offset (zum Beispiel ...Z) wird automatisch umgerechnet. Siehe Datums- und Zeitangaben.

Eine bewusste Ausnahme: Kursbewertungen sind anonym, und präzise Zeitstempel ließen sich mit dem completed_at der Kursteilnahmen desselben Kurses abgleichen. Kursbewertungen tragen deshalb weder Zeitstempel noch einen updated_after-Filter. Sie sind ein kleiner Datenbestand; aktualisieren Sie sie bei Bedarf per Vollabruf mit Upsert über die id.

  1. Einmaliger Vollabruf: Rufen Sie die komplette Liste mit ordering=updated_at ab und blättern Sie durch alle Seiten. Merken Sie sich das updated_at des letzten Objekts als Cursor, unverändert aus der Antwort kopiert.
  2. Jeder Sync-Lauf: Fragen Sie die erste Seite von ?updated_after=<Cursor>&ordering=updated_at ab.
  3. Verarbeiten Sie die Ergebnisse und aktualisieren Sie per id (Upsert): Weil die Grenze inklusiv ist, taucht das Objekt am Cursor erneut auf; mit der id als Schlüssel ist das unschädlich.
  4. Setzen Sie den Cursor auf das updated_at des letzten Objekts der Seite und wiederholen Sie ab Schritt 2, bis eine Antwort weniger als 25 Ergebnisse enthält (die Seitengröße, siehe Paginierung und Sortierung).
  5. Seltener Randfall: Teilen sich alle 25 Objekte einer Seite dasselbe updated_at (zum Beispiel nach einem Massenimport), würde der Cursor nicht weiterwandern. Blättern Sie dann mit page=2, page=3, … derselben Abfrage weiter, bis sich der Zeitstempel ändert, und machen Sie mit Schritt 4 weiter.

Dass Sie immer wieder die erste Seite mit wachsendem Cursor abfragen (statt einmal durch page=1..n zu blättern), macht die Schleife robust: Objekte, die sich während des Abgleichs ändern, wandern ans Ende der Sortierung und werden von einer der nächsten Abfragen erfasst - nichts wird übersprungen.

Wenn es auf absolute Vollständigkeit ankommt, starten Sie jeden Lauf mit einem um eine Stunde zurückgesetzten Cursor; weil Sie per id upserten, ist die Überlappung unschädlich. Das deckt zwei seltene Fälle ab: Zeitstempel aus der doppelten Stunde beim Ende der Sommerzeit (eine Nacht pro Jahr) und Änderungen, die erst mit dem Commit einer längeren Transaktion sichtbar wurden, nachdem Ihr vorheriger Lauf deren Zeitstempel schon passiert hatte.

updated_at ändert sich, sobald sich ein Feld des Objekts ändert, das die API zurückgibt - egal ob die Änderung im Admin-Bereich, durch einen Lernenden oder über die API passiert. Zwei Details sind wissenswert:

  • Gruppenmitgliedschaften aktualisieren updated_at sowohl des betroffenen Benutzers als auch der Gruppe; Mitgliedschaftsänderungen tauchen also in Delta-Abfragen auf /v1/users/ und /v1/groups/ auf.
  • Reine Aktivität zählt nicht: last_active ändert sich, ohne updated_at zu aktualisieren. Ein Benutzer, der sich nur anmeldet, erscheint nicht in Ihrem Delta.

Gelöschte Objekte verschwinden einfach aus den Listen; eine Delta-Abfrage kann sie nicht melden. Abonnieren Sie für Benutzer und Kursteilnahmen die Webhook-Events user.deleted und participation.deleted. Für die übrigen Ressourcen, oder als Sicherheitsnetz, gleichen Sie regelmäßig ab (zum Beispiel einmal pro Nacht): Rufen Sie alle id-Werte der vollen Liste ab und entfernen Sie lokale Datensätze, deren id nicht mehr existiert. Eine Detail-Abfrage zu einem gelöschten Objekt liefert 404. Beachten Sie: Das Löschen eines Benutzers oder einer Gruppe entfernt das Objekt auch aus den Mitgliederlisten der Gegenseite, ohne deren updated_at zu ändern; auch diesen Fall fängt der Abgleich auf.

Mit eingerichteten Webhooks reicht ein Abgleich pro Stunde oder pro Nacht in der Regel aus. Ohne Webhooks ist eine Delta-Abfrage für beide Seiten günstig; ein Abgleich alle paar Minuten ist unproblematisch. Wählen Sie das längste Intervall, das für Ihren Anwendungsfall akzeptabel ist, und behalten Sie die Durchsatzbegrenzung im Blick, wenn über Ihr Konto mehrere Integrationen laufen.