Zum Hauptinhalt springen
Die Data API ist eine reine Lese-Schnittstelle über Daten, die aus einer vorgelagerten Pipeline synchronisiert werden. Zu verstehen, wie und wann dieser Sync passiert, ist essenziell, um eine korrekte Polling- oder inkrementelle Sync-Integration zu bauen.
Der Sync-Takt ist eine Eigenschaft der vorgelagerten Pipeline, nicht etwas, das die API konfiguriert oder offenlegt — sie hat keinen eigenen, maschinell erzwungenen Zeitplan, gegen den man das prüfen könnte. Gehe nicht von einem festen Aktualisierungsintervall aus — prüfe stattdessen immer last_sync_at (siehe unten).

TRUNCATE + Reload-Semantik

Bei jedem Sync-Lauf wird jede Tabelle vollständig gelöscht und komplett neu geladen — es gibt kein inkrementelles Update auf Zeilenebene innerhalb der Tabelle. Das hat zwei direkte Konsequenzen für Integratoren:
  1. Kein partieller Sync. Eine Tabelle wird entweder vollständig durch den neuesten Sync ersetzt, oder gar nicht berührt. Es gibt keinen Mechanismus, um “nur die Zeilen zu synchronisieren, die sich geändert haben” innerhalb einer einzelnen Tabelle — GET /v1/changes (unten) sagt dir, welche Tabellen sich geändert haben, nicht welche Zeilen.
  2. Schema-Änderungen sind für kumulative Tabellen immer ein Breaking Change. Bei Tabellen, die über mehrere Reloads hinweg Historie ansammeln (zum Beispiel contract_ends), kann eine Schema-Änderung nicht additiv angewendet werden — TRUNCATE + Reload ersetzt immer den gesamten Tabelleninhalt, es gibt also keine Möglichkeit, alte Zeilen in-place in eine neue Form zu migrieren. Jede Schema-Änderung an einer solchen Tabelle wird als Breaking Change behandelt, der eine neue API-Version erfordert, wobei sowohl die alte als auch die neue Tabellenform während eines Deprecation-Fensters parallel synchronisiert werden.

Wann last_sync_at gesetzt wird

last_sync_at wird nur gesetzt, wenn ein Sync für diese Tabelle erfolgreich abgeschlossen wird — es bleibt NULL, bis der erste erfolgreiche Sync stattfindet, und ein fehlgeschlagener oder noch laufender Sync treibt es nicht voran. Das bedeutet:
  • Eine Tabelle ohne bisherigen erfolgreichen Sync erscheint niemals in GET /v1/changes, unabhängig davon, wie kürzlich ein Sync versucht wurde.
  • last_sync_at spiegelt den Abschluss auf Tabellenebene wider, nicht den Änderungszeitpunkt einer einzelnen Zeile innerhalb dieser Tabelle.

Was GET /v1/changes tatsächlich prüft

GET /v1/changes?since=<timestamp> liefert eine Tabelle nur zurück, wenn sie einen erfolgreichen Sync mit last_sync_at > since abgeschlossen hat — ein strikter Größer-als-Vergleich, kein >=. Der ETag-Response-Header wird aus dem Maximum von last_sync_at über alle synchronisierten Tabellen eines Kunden sowie aus since (nach UTC umgerechnet) und dem Filter category gebildet. Ein ETag aus einer Abfrage mit anderem since oder anderer category passt daher nie. Polling mit If-None-Match erlaubt dir daher, einen Request komplett zu überspringen, wenn seit deinem letzten Poll nichts synchronisiert wurde (siehe Delta Sync für das vollständige Polling-Muster).
since darf nicht älter als 120 Tage sein — ältere Werte werden mit einem 400-Fehler abgelehnt. Diese Grenze ist in der OpenAPI-Parameterbeschreibung des Endpunkts dokumentiert (siehe Tab API-Referenz). Es ist eine Schutzmaßnahme gegen fehlerhafte Clients, keine Datenaufbewahrungsgrenze — behandle sie als feste betriebliche Einschränkung, nicht als einstellbaren Parameter.

Praktische Auswirkungen für deine Integration

  • Poll /v1/changes, statt einen Zeitplan zu raten. Da es kein dokumentiertes, erzwungenes Sync-Intervall gibt, baue deine Integration so, dass sie auf das reagiert, was /v1/changes meldet, statt anzunehmen, dass Daten zu einer festen Tageszeit aktualisiert werden.
  • Eine geänderte Tabelle bedeutet “alles für diese Tabelle neu abrufen”, nicht “hier sind die Diffs”. Änderungserkennung auf Zeilenebene existiert noch nicht — wenn eine Tabelle in /v1/changes erscheint, ist der sicherste Weg ein vollständiger erneuter Abruf dieser Category oder dieses Raw-Endpunkts.
  • Behandle last_sync_at als Aktualitätssignal, nicht als Änderungsprotokoll. Es sagt dir, dass die Tabelle zu diesem Zeitpunkt erfolgreich neu geladen wurde; es sagt dir nicht, welche Zeilen sich von der vorherigen Version unterscheiden.