Billing-API

Rufen Sie Nutzungs- und Kostendaten Ihres eigenen Workspace in Ihre eigenen Systeme ab, ohne die Konsole zu öffnen. Ein Billing-Schlüssel ist ein nur lesender Anmeldedaten, beschränkt auf einen Workspace - er kann nur Abrechnungsdaten lesen, sonst nichts.

⚠

Ein Billing-Schlüssel kann jede in seinem Workspace protokollierte Anfrage lesen, einschließlich inzwischen gelöschter oder widerrufener Schlüssel, kann aber kein Modell aufrufen und keinen API-Schlüssel erstellen, ändern oder löschen. Wird er anderswo verwendet, liefert das 401 wrong_key_kind.

ℹ

Die Billing-API wird mit einem Admin-Schlüssel (sk-syn-admin-) mit dem Scope billing.read aufgerufen; ohne den Scope antwortet sie mit 403 insufficient_scope. Zuvor ausgestellte Billing-Schlüssel (sk-syn-bill-) funktionieren weiter, neue werden nicht mehr ausgestellt.

Einen Billing-Schlüssel erstellen

  1. Öffnen Sie Konsole → API-Schlüssel → Admin-Schlüssel (Workspace-Admins und Eigentümer). Benennen Sie ihn, wählen Sie den Scope billing.read, beschränken Sie ihn optional auf eine IP-Allowlist oder legen Sie ein Ablaufdatum fest, und kopieren Sie dann den Schlüssel - er beginnt mit sk-syn-admin- und wird nur einmal angezeigt.
  2. Rufen Sie die untenstehenden Endpoints damit als Bearer-Token auf. Widerrufen Sie ihn jederzeit auf derselben Seite - der Widerruf macht ihn sofort ungültig, ohne sonst etwas im Workspace zu beeinflussen.
  3. Ein Schlüssel ist an seinen Ersteller gebunden, es sei denn, er gehört dem Workspace: Ist der Ersteller weder Admin noch Eigentümer des Workspace mehr, funktioniert der Schlüssel nicht mehr und liefert 403 key_owner_not_authorized.

Authentifizierung

Jeder Aufruf benötigt Authorization: Bearer sk-syn-admin-... gegen die untenstehende Basis-URL. Ein Billing-Schlüssel funktioniert nur auf diesen Endpoints, und diese Endpoints akzeptieren nur einen Billing-Schlüssel - jede andere Kombination liefert 401 wrong_key_kind.

Authorization: Bearer sk-syn-admin-...

Basis-URL: https://synthorai.io/api/v1/billing

ℹ

Der Geltungsbereich ist der gesamte Workspace: jeder Inferenzschlüssel darin, auch gelöschte - ihre historischen Zeilen bleiben abfragbar. api_key_id und model können das Ergebnis nur einschränken, nie erweitern; jede Abfrage ist an den eigenen Workspace des Schlüssels gebunden.

ℹ

Jede Abfrage läuft auf der Read-Replica, niemals auf der Primary. Ein Prozess ohne konfigurierte Replica antwortet mit 503 replica_unavailable statt stillschweigend zurückzufallen.

✓

Token-Felder: folgen der OpenAI-Konvention - prompt_tokens ist die Summe der Input-Tokens und enthält bereits jeden Cache-Read und Cache-Write darunter, und completion_tokens enthält bereits reasoning_tokens. Keines von beiden wird zu den Summen hinzugerechnet - es handelt sich um eine Aufschlüsselung, nicht um zusätzliche Tokens.

Der Cache-Read-Anteil von prompt_tokens ist cached_tokens; der Cache-Write-Anteil ist cache_write_tokens, der auf /records-Zeilen je nach TTL weiter in cache_write_5m_tokens und cache_write_1h_tokens aufgeteilt wird.

✓

Geldfelder: cost_usd ist der tatsächlich in Rechnung gestellte Betrag. byok_list_price_usd ist, was eine BYOK-Anfrage zum Listenpreis gekostet hätte - 0 bei einer Nicht-BYOK-Anfrage. Es gibt kein list_price_usd nirgendwo in dieser API.

ℹ

"Fehler" bedeutet hier jede Anfrage, die die API erreicht hat und abgelehnt wurde - ein 4xx wie 402 (unzureichendes Guthaben), 403 oder 429, ebenso wie ein Upstream-Fehler. Ausgeschlossen sind nur Ablehnungen unserer eigenen internen Infrastruktur, genau wie in der Konsole. Abgelehnte Anfragen werden auf jedem Server höchstens einmal pro Key, Statuscode und Minute erfasst; die Zahlen für 402, 403 und 429 sind daher Untergrenzen. Erfolgreiche Anfragen und Abrechnungen sind vollständig.

GET /usage - aggregierte Nutzung

GET /usage

Voraggregierte Zeilen pro Stunde oder Tag - für Rechnungen und Dashboards. Sie stammen aus dem stündlichen Rollup, ergänzt um die seit dessen letztem Import geschriebenen Anfragen, sodass jüngste Buckets nicht einen ganzen Importzyklus hinterherhinken.

ParameterTypBeschreibung
start*stringBeginn des Zeitraums: ein RFC-3339-Zeitstempel oder ein Datum wie 2026-09-01.
endstringEnde des Zeitraums. Standardmäßig jetzt.
granularitystringBucket-Größe: hour oder day. Standardmäßig day.
group_bystringDimensionen zur Aufschlüsselung der Zeilen: api_key, model oder beide (jede Teilmenge). Standardmäßig beide.
api_key_idintegerFiltert auf eine oder mehrere API-Schlüssel-IDs. Wiederholbar; schränkt nur ein, erweitert niemals.
modelstringFiltert auf eine oder mehrere Modell-IDs. Wiederholbar.
limitintegerZeilen pro Seite. Standardmäßig 1000, begrenzt auf 5000.
cursorstringUndurchsichtiger Paginierungs-Cursor, entnommen aus dem meta.next_cursor der vorherigen Seite.

In jeder Zeile erscheinen api_key_id und api_key_name nur, wenn group_by api_key enthält, und model nur, wenn es model enthält. avg_latency_ms kann null sein, wenn ein Bucket keine Latenz-Stichproben hat.

Beispielanfrage

curl "https://synthorai.io/api/v1/billing/usage?start=2026-09-01&end=2026-09-24&granularity=day" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{
  "data": [
    {
      "bucket_start": "2026-09-23T00:00:00Z",
      "bucket_end": "2026-09-24T00:00:00Z",
      "api_key_id": 42,
      "api_key_name": "prod-backend",
      "model": "claude-sonnet-5",
      "requests": 1280,
      "success_requests": 1265,
      "error_requests": 15,
      "errors_4xx": 12,
      "errors_429": 2,
      "errors_5xx": 1,
      "prompt_tokens": 512000,
      "completion_tokens": 98000,
      "cached_tokens": 210000,
      "cache_write_tokens": 8000,
      "reasoning_tokens": 4000,
      "cost_usd": 4.1732,
      "byok_list_price_usd": 0,
      "byok_requests": 0,
      "avg_latency_ms": 812,
      "final": true
    }
  ],
  "meta": {
    "generated_at": "2026-09-24T08:00:00Z",
    "data_complete_until": "2026-09-24T06:00:00Z",
    "timezone": "UTC",
    "currency": "USD",
    "next_cursor": null,
    "has_more": false
  }
}

GET /records - Zeilen pro Anfrage

GET /records

Eine Zeile pro Anfrage, gedacht für die inkrementelle Synchronisierung in Ihre eigene Datenbank. Synchronisieren Sie nach cursor, niemals nach Zeit, und entfernen Sie Duplikate eingehender Zeilen anhand von record_id - siehe unten "Zeitlücken vermeiden" für den Grund.

ParameterTypBeschreibung
cursorstringUndurchsichtiger Synchronisierungs-Cursor (String), entnommen aus dem meta.next_cursor des vorherigen Aufrufs. Geben Sie genau eines von cursor oder start an; er hat keine Zeitraumgrenze.
startstringBeginn des Zeitraums (RFC-3339-Zeitstempel oder Datum). Geben Sie genau eines von cursor oder start an; ein start/end-Zeitraum ist auf 31 Tage begrenzt, während cursor keine Zeitraumgrenze hat.
endstringEnde des Zeitraums. Standardmäßig jetzt.
api_key_idintegerFiltert auf eine oder mehrere API-Schlüssel-IDs. Wiederholbar; schränkt nur ein, erweitert niemals.
modelstringFiltert auf eine oder mehrere Modell-IDs. Wiederholbar.
limitintegerZeilen pro Seite. Standardmäßig 500, begrenzt auf 1000.

Beispielanfrage

curl "https://synthorai.io/api/v1/billing/records?start=2026-09-24T00:00:00Z&limit=500" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{
  "data": [
    {
      "record_id": "rec_8f2a91c4",
      "request_id": "req_9f3c2b1a",
      "recorded_at": "2026-09-24T05:58:31Z",
      "completed_at": "2026-09-24T05:58:29Z",
      "api_key_id": 42,
      "api_key_name": "prod-backend",
      "model": "claude-sonnet-5",
      "status": "success",
      "status_code": 200,
      "prompt_tokens": 812,
      "completion_tokens": 194,
      "cached_tokens": 512,
      "cache_write_tokens": 64,
      "cache_write_5m_tokens": 64,
      "cache_write_1h_tokens": 0,
      "cost_usd": 0.00412,
      "byok_list_price_usd": 0,
      "is_byok": false,
      "is_stream": true,
      "duration_ms": 1340,
      "ttft_ms": 210
    }
  ],
  "meta": {
    "next_cursor": "eyJvIjoiODgxNDA5MCJ9",
    "has_more": false,
    "window_final": true,
    "safe_until": "2026-09-24T05:58:31Z",
    "latest_recorded_at": "2026-09-24T05:58:31Z",
    "data_complete_until": "2026-09-24T05:58:00Z"
  }
}
ParameterBeschreibung
next_cursorCursor für den nächsten Aufruf. Immer vorhanden.
has_moreOb ein sofortiger erneuter Aufruf mit diesem Cursor weitere Zeilen liefern würde.
window_finalNur true, wenn Sie ein end angegeben haben und dieses bei oder vor safe_until liegt - dann ist der angeforderte Zeitraum garantiert vollständig. Andernfalls fehlt es oder ist false.
safe_untilDer neueste recorded_at, den ein Aufrufer als endgültig ansehen kann; jüngere Zeilen werden noch zurückgehalten.
latest_recorded_atDer jüngste recorded_at über alle Zeilen hinweg, endgültig oder nicht.
data_complete_untilDerselbe Wert, den /freshness liefert - wie weit das stündliche Rollup vollständig ist, zum Abgleich mit /usage.
⚠

Zeitbasis: /usage bündelt nach completed_at (wann die Anfrage abgeschlossen wurde). Der start/end-Filter von /records basiert auf recorded_at (wann die Zeile geschrieben wurde, was unter Last hinter dem Abschluss zurückbleiben kann). Um /records mit /usage abzustimmen, bündeln Sie Ihre synchronisierten Zeilen selbst nach completed_at, nicht nach recorded_at.

GET /records/export - gestreamter Export

GET /records/export

Dieselben Filter wie /records, gestreamt als zeilenweise getrenntes JSON (application/x-ndjson) - für einen großen Rückstands-Abgleich statt einer paginierten Liste gedacht. Pro Workspace kann jeweils nur ein Export gestreamt werden; ein zweiter erhält 429 too_many_concurrent_requests.

Beispielanfrage

curl -N "https://synthorai.io/api/v1/billing/records/export?cursor=eyJvIjoiODgxNDAzMiJ9" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{"record_id":"rec_8f2a91c4","request_id":"req_9f3c2b1a","model":"claude-sonnet-5","status":"success","cost_usd":0.00412}
{"record_id":"rec_8f2a91c5","request_id":"req_9f3c2b1b","model":"claude-sonnet-5","status":"success","cost_usd":0.00398}
{"_meta":{"next_cursor":"eyJvIjoiODgxNDA5MSJ9","rows":2,"complete":true,"window_final":true,"generated_at":"2026-09-24T06:00:02Z"}}

Die letzte Zeile des Streams ist ein _meta Objekt:

ParameterBeschreibung
next_cursorCursor für den nächsten Export-Aufruf.
rowsAnzahl der in diesem Stream geschriebenen Datensätze.
completefalse bedeutet, dass der Stream vor dem vollständigen Durchlauf des Zeitraums angehalten hat - setzen Sie mit cursor=next_cursor fort.
window_finalGleiche Bedeutung wie bei /records: nur true, wenn das end des Exports bei oder vor safe_until liegt.
generated_atZeitpunkt, zu dem diese Zeile geschrieben wurde.
stopped_becauseVorhanden, wenn complete false ist: row_cap, scan_cap (der Stream hat seinen maximalen id-Bereich durchlaufen, ohne voll zu werden - häufig bei engem Filter), time_cap, query_error oder window_not_final.

GET /summary - vorläufige Statistiken und Anomalien

GET /summary

Summen, Top-Modelle und Top-Schlüssel nach Kosten sowie eine Fehlerrate für den Zeitraum, plus eine anomalies Liste (high_error_rate, rate_limited, data_not_final, rollup_delayed), jede mit einem Schweregrad info oder warning und einer für Menschen lesbaren Nachricht. Zahlen in einem noch nicht abgeschlossenen Zeitraum können sich noch ändern - siehe unten.

ParameterTypBeschreibung
startstringBeginn des Zeitraums. Standardmäßig 30 Tage vor end.
endstringEnde des Zeitraums. Standardmäßig jetzt.
api_key_idintegerFiltert auf eine oder mehrere API-Schlüssel-IDs. Wiederholbar; schränkt nur ein, erweitert niemals.
modelstringFiltert auf eine oder mehrere Modell-IDs. Wiederholbar.

models_count und keys_count liefern die Summen hinter top_models und top_keys, die höchstens die Top 20 nach Kosten aufführen. Der Zeitraum ist standardmäßig die 30 Tage vor end , wenn start ausgelassen wird.

Beispielanfrage

curl "https://synthorai.io/api/v1/billing/summary?start=2026-09-17&end=2026-09-24" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{
  "data": {
    "totals": { "requests": 48210, "cost_usd": 132.55, "error_rate": 0.021 },
    "models_count": 6,
    "keys_count": 3,
    "top_models": [ { "model": "claude-sonnet-5", "cost_usd": 88.10, "byok_list_price_usd": 0 } ],
    "top_keys": [ { "api_key_id": 42, "api_key_name": "prod-backend", "cost_usd": 61.30, "byok_list_price_usd": 0 } ],
    "anomalies": [
      { "type": "data_not_final", "severity": "info", "message": "The last 2 hours of this range are not yet final." }
    ]
  },
  "meta": {
    "generated_at": "2026-09-24T06:00:02Z",
    "data_complete_until": "2026-09-24T04:00:00Z"
  }
}

GET /freshness - wie vollständig die Daten sind

GET /freshness

Liefert data_complete_until, latest_recorded_at, safe_until und pipeline_lag_seconds - fragen Sie es ab, bevor Sie einen gerade abgerufenen Zeitraum als endgültig behandeln. safe_until ist der neueste recorded_at, den ein Aufrufer als vollständig ansehen kann; jüngere Zeilen können noch eintreffen.

Beispielanfrage

curl "https://synthorai.io/api/v1/billing/freshness" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{
  "data": {
    "data_complete_until": "2026-09-24T04:00:00Z",
    "latest_recorded_at": "2026-09-24T05:58:31Z",
    "safe_until": "2026-09-24T05:58:31Z",
    "pipeline_lag_seconds": 47
  },
  "meta": { "generated_at": "2026-09-24T06:00:02Z" }
}

GET /balance - was der Workspace jetzt ausgeben kann

GET /balance

Liefert das aktuell verfügbare Guthaben des Workspace - denselben Betrag wie in der Konsole. Für regelmäßige Abfragen gebaut: alle 30 bis 60 Sekunden genügt. Es hat ein eigenes Rate-Limit, sodass das Abfragen das Budget der Daten-Endpunkte nicht aufbraucht, und es antwortet auch bei einem Guthaben von null.

Beispielanfrage

curl "https://synthorai.io/api/v1/billing/balance" \
  -H "Authorization: Bearer sk-syn-admin-..."

Beispielantwort

{
  "data": {
    "available_usd": 1284.37,
    "debt_usd": 0,
    "source": "live",
    "voucher": null,
    "scheduled_credits": [
      { "amount_usd": 250, "release_at": "2026-10-01T00:00:00Z" }
    ],
    "scheduled_credit_total_usd": 250
  },
  "meta": { "generated_at": "2026-09-24T06:00:02Z", "currency": "USD" }
}
ParameterBeschreibung
available_usdDas allgemeine Guthaben, gegen das Anfragen gerade abgerechnet werden. Nie unter 0. Es kann kurz steigen, wenn laufende Anfragen abgerechnet werden; für Ausgaben /usage oder /records verwenden.
debt_usdDer offene Betrag: Nutzung über das aufgeladene Guthaben hinaus. 0, wenn nichts offen ist. Eine Aufladung begleicht ihn zuerst; nur der Rest wird zu available_usd.
sourcelive: aus dem Echtzeit-Ledger gelesen. delayed: das Ledger war nicht erreichbar, der Wert stammt aus einer Datenbankkopie, die bis zu etwa 30 Sekunden hinterherhinken kann.
voucherAktionsguthaben nur für Bildgenerierung (applies_to), für die aufgeführten Modellmuster und bis expires_at; andere Anfragen nutzen nur available_usd, und es ist nicht darin enthalten. null, wenn keines vorhanden ist; active ist nach Ablauf false.
scheduled_creditsBereits vereinbarte Gutschriften in Tranchen (amount_usd, release_at); jede wird innerhalb von etwa 10 Minuten nach release_at dem Guthaben zugeschlagen, nicht früher. scheduled_credit_total_usd ist ihre Summe.

Fehler

Jeder Fehler ist {"error": {"type", "message", "hint"}}:

{
  "error": {
    "type": "range_too_large",
    "message": "the requested range exceeds this endpoint's cap",
    "hint": "narrow start/end to at most 31 days, or sync /records with a cursor instead"
  }
}
TypHTTP-StatusBedeutung
invalid_parameter400Ein Query-Parameter fehlt, ist fehlerhaft oder außerhalb des gültigen Bereichs.
range_too_large400Der angeforderte Zeitraum oder das id-Fenster ist größer als vom Endpoint erlaubt; der hint nennt die betroffene Grenze.
start_too_recent400Ein start/end-Fenster beginnt nach safe_until, wo seine Startgrenze noch nicht feststeht. Nach der Zeit im Retry-After-Header erneut versuchen oder per cursor synchronisieren.
wrong_key_kind401Die Anmeldedaten sind kein Billing-Schlüssel, oder ein Billing-Schlüssel wurde außerhalb dieser Endpoints verwendet.
authentication_error401Der Schlüssel fehlt, ist ungültig, abgelaufen oder wird durch seine IP-Allowlist blockiert.
key_owner_not_authorized403Der Ersteller dieses Schlüssels ist weder Admin noch Eigentümer des Workspace mehr. Ein Schlüssel, der Abrechnungsdaten liest, funktioniert nur, solange sein Ersteller diese Rolle hat, es sei denn, der Schlüssel gehört dem Workspace; ein Admin oder der Eigentümer muss einen neuen erstellen.
rate_limited429Mehr als 60 Anfragen pro Minute auf diesem Workspace. Versuchen Sie es nach der im Header Retry-After angegebenen Zeit erneut.
too_many_concurrent_requests429Mehr als 3 gleichzeitige Anfragen in diesem Workspace, oder ein anderer Export läuft bereits.
replica_unavailable503Für diesen Prozess ist keine Read-Replica konfiguriert; die API fällt niemals auf die Primary zurück.
query_timeout503Die Abfrage hat das 10-Sekunden-Statement-Timeout oder die 15-Sekunden-Frist überschritten. Schränken Sie den Zeitraum ein und versuchen Sie es erneut.
internal_error500Ein unerwarteter Serverfehler. Versuchen Sie es erneut und melden Sie es, falls das Problem weiter besteht.

Rate-Limits und Obergrenzen

SchutzmaßnahmeWert
Rate-Limit60 Anfragen pro Minute pro Workspace, ein gleitendes Zeitfenster, das über alle Instanzen hinweg geteilt wird.
Nebenläufigkeit3 gleichzeitige Anfragen pro Workspace auf jedem Server und ein Export-Stream pro Workspace auf jedem Server.
Guthaben-Abfrage/balance: 60 Anfragen pro Minute und 2 gleichzeitig pro Workspace, getrennt von den anderen Endpunkten gezählt.
Zeitraumgrenzen/usage: 31 Tage bei Granularität hour, 366 Tage bei day. /summary: bis zu 366 Tage. /records und der Export: bis zu 31 Tage.
Seitengrenzen/usage liefert bis zu 5.000 Zeilen pro Seite, /records bis zu 1.000. Der Export streamt Seiten zu 2.000 und stoppt bei 1.000.000 Zeilen - fortsetzbar mit cursor. Er stoppt außerdem nach 2.000.000 durchlaufenen Datensatz-ids (stopped_because=scan_cap) und drosselt sich passend zur Datenbank; mit cursor fortsetzen.
CachingJede Antwort trägt Cache-Control: no-store.

Wird nie zurückgegeben: channel_id, upstream_request_id, usage_raw, other, content, ip_address, user_agent, cost_detail.

Zeitlücken vermeiden

Anfragen werden nach ihrem Abschluss asynchron in das Log geschrieben (normalerweise Sekunden, bei Rückstand länger), und das stündliche Rollup, aus dem /usage und /summary lesen, wird in Batches eingespielt. Die jüngsten Stunden sind immer etwas unvollständig. /usage und /summary ergänzen außerdem die seit dem letzten Import geschriebenen Anfragen (meta.live_tail ist true); liegt der Rollup dafür zu weit zurück, ist meta.live_tail false und die jüngsten Buckets sind unvollständig.

data_complete_until ist der frühere der beiden folgenden Zeitpunkte: der Wasserstand des stündlichen Rollups minus der aktuellen Pipeline-Verzögerung, oder die älteste noch nicht eingerollte Anfrage - minus einer Sicherheitsmarge von 30 Minuten, abgerundet auf die volle Stunde.

ℹ

Ein finaler Bucket ist stabil, mit einer Ausnahme: der tägliche Abgleichsjob kann eine Stunde innerhalb von 48 Stunden noch korrigieren, falls er eine Abweichung findet. /records ist immer die Quelle der Wahrheit für die genauen Zahlen einer Anfrage.

Jede Zeile von /usage trägt ein final -Flag: true , das gilt, sobald sein Bucket vor oder bei data_complete_until (Wert von /freshness) endet. Ein finaler Bucket ändert sich nie wieder.

  • Aggregate: upserten Sie jede Zeile anhand von (bucket_start, api_key_id, model) in Ihren eigenen Speicher, und holen Sie jeden Bucket erneut ab, solange er noch final: false ist. Leiten Sie niemals ein Delta ab, indem Sie eine alte Summe von einer neuen abziehen.
  • Rohdaten-Zeilen: synchronisieren Sie nach cursor, niemals nach Zeit. Bewahren Sie next_cursor auf und setzen Sie beim nächsten Aufruf dort fort, und entfernen Sie Duplikate eingehender Zeilen anhand von record_id (eine stabile, undurchsichtige id pro Zeile), falls eine wiederholte Seite dieselbe Zeile erneut liefert. Zeilen, die jünger als etwa 5 Minuten sind, werden zurückgehalten - safe_until ist die Zeit der neuesten protokollierten Zeile minus 5 Minuten - sodass eine noch in Arbeit befindliche Zeile niemals an einer bereits ausgegebenen Cursor-Position vorbeirutschen kann und nichts in eine Lücke fällt. Zum Zählen von Anfragen zählen Sie eindeutige request_id.
  • Begrenztes Fenster: wenn Sie einen start/end-Zeitraum abfragen, statt nach cursor zu synchronisieren, behandeln Sie ihn erst als vollständig, wenn window_final true ist (das ist nur der Fall, wenn Sie ein end angegeben haben und dieses bei oder vor safe_until liegt). Ist window_final false, rufen Sie später mit demselben Zeitraum erneut auf, oder wechseln Sie zur Synchronisierung per cursor. Ein Fenster muss spätestens bei safe_until beginnen; ein späterer Beginn liefert 400 start_too_recent mit Retry-After-Header.

Empfohlene Integration

  • Nächtliche Abrechnung: rufen Sie /usage einmal täglich mit granularity=day auf, und holen Sie jeden Bucket erneut ab, der bei Ihrem letzten Lauf noch final: false war.
  • Details pro Anfrage: rufen Sie /records stündlich mit cursor auf den zuletzt gespeicherten next_cursor gesetzt auf, paginieren Sie weiter, solange has_more true ist, und entfernen Sie Duplikate eingehender Zeilen anhand von record_id.
  • Dashboards: rufen Sie für den sichtbaren Zeitraum /summary auf, statt /records selbst zu aggregieren - er enthält bereits die Anomalienliste.

Müssen Sie reguläre API-Schlüssel programmatisch erstellen oder verwalten, statt Abrechnungsdaten zu lesen? Siehe Admin-Schlüssel.