API-Dokumentation

Fehler und Anfragebegrenzungen

Der Fehler-Body

Jede 4xx-Ablehnung eines /v1-Endpunkts trägt ein strukturiertes error-Objekt mit einem stabilen, maschinenlesbaren Code:

json
{ "error": { "code": "not_found", "message": "Resource not found." } }

Code und Meldung sind je Statuscode festgelegt, nie je Aufrufstelle, damit eine Ablehnung nicht verrät, warum eine bestimmte Anfrage abgewiesen wurde. Heute ausgelieferte Codes: invalid_request (400), unauthenticated (401), forbidden (403), not_found (404), method_not_allowed (405), conflict (409), rate_limited (429).

Ablehnungen wegen der Obergrenzen für Anfragen (siehe unten) tragen dieselbe Antwortstruktur plus ein Feld retry_after_seconds:

json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after the number of seconds in Retry-After.",
    "retry_after_seconds": 21
  }
}

Verzweigen Sie auf error.code, nie auf den Meldungstext. Codes sind stabil: Neue Codes können hinzukommen, bestehende Codes werden nie umbenannt.

Eine Ablehnung hat eine andere Form: Eine 422 aus der Anfragevalidierung antwortet mit einem Body, der den beanstandeten Parameter oder das beanstandete Feld benennt, nicht mit dem error-Umschlag.

Die Verwaltungsendpunkte unter /org/api-keys tragen stattdessen eine einzelne detail-Meldung:

json
{ "detail": "API key not found." }

Statuscodes

StatusBedeutung
200Die Anfrage war erfolgreich.
401Die Zugangsdaten fehlten oder wurden nicht akzeptiert. Für jeden Ablehnungsgrund derselbe Body; siehe Authentifizierung.
403Der Vorgang steht Ihrem Arbeitsbereich nicht zur Verfügung. Auf das Anlegen eines Schlüssels ohne freigeschalteten API-Zugang antwortet die API mit 403; siehe Schlüssel und Zugangsverwaltung.
404Die Ressource existiert in Ihrem Arbeitsbereich nicht. Die API unterscheidet nicht zwischen einer Ressource, die es nicht gibt, und einer, die zu einem anderen Arbeitsbereich gehört.
405Die Methode wird nicht unterstützt. /v1-Endpunkte nehmen ausschließlich GET entgegen, mit Ausnahme von POST /v1/citations/resolve.
422Die Anfrage hat die Validierung nicht bestanden. Der Body benennt den Parameter oder das Feld; dies ist die einzige 4xx ohne den error-Umschlag.
429Eine Obergrenze für Anfragen wurde erreicht; siehe unten.
503Die Anfrage konnte nicht sicher bedient werden; versuchen Sie es später erneut. Siehe quota_unavailable unten.

Anfragebegrenzungen

Für jede Anfrage, die ein API-Schlüssel authentifiziert, gelten zwei Obergrenzen:

  • eine Anfragebegrenzung je Schlüssel über ein Fenster von einer Minute und
  • ein Tageskontingent je Arbeitsbereich über alle Schlüssel des Arbeitsbereichs hinweg, das um Mitternacht UTC zurückgesetzt wird.

Die Obergrenzen stehen nicht in dieser Dokumentation: Jede /v1-Antwort nennt sie im Header RateLimit-Policy (siehe unten), sodass ein Client sie lesen kann, bevor er einen Schlüssel hält.

Antwort-Header

Die API veröffentlicht die IETF-RateLimit-Headerfelder (draft-ietf-httpapi-ratelimit-headers, Structured-Fields-Syntax) neben den älteren X-RateLimit-*-Headern. Headernamen sind unabhängig von Groß- und Kleinschreibung.

Jede /v1-REST-Antwort trägt die Policy, unabhängig davon, ob die Anfrage authentifiziert war (Ablehnungen mit 401, 403, 404 und 429 eingeschlossen):

HeaderBedeutung
RateLimit-PolicyDie geltenden Obergrenzen, ein Eintrag je Obergrenze. q ist das Kontingent in Anfragen, w das Fenster in Sekunden. Der Eintrag key-minute ist die Anfragebegrenzung je Schlüssel, der Eintrag workspace-day das Tageskontingent je Arbeitsbereich, dessen Fenster der UTC-Kalendertag ist.
text
RateLimit-Policy: "key-minute";q=120;w=60, "workspace-day";q=50000;w=86400

Jede /v1-REST-Antwort auf eine von einem API-Schlüssel authentifizierte Anfrage trägt zusätzlich den Zustand des Minutenfensters, auch bei Ablehnungen wegen der Obergrenzen für Anfragen:

HeaderBedeutung
RateLimitDer aktuelle Zustand der Policy key-minute: r ist die Zahl der im laufenden Fenster verbleibenden Anfragen, t die Zahl der Sekunden bis zum Zurücksetzen des Fensters.
X-RateLimit-LimitDie Minutenobergrenze für diesen Schlüssel.
X-RateLimit-RemainingIm laufenden Fenster verbleibende Anfragen; entspricht r.
X-RateLimit-ResetWann das laufende Fenster zurückgesetzt wird, als Unix-Zeitstempel in Sekunden; t Sekunden nach der Antwort.
text
RateLimit: "key-minute";r=87;t=42

429-Antworten tragen zusätzlich einen Header Retry-After in Sekunden. Bei einer 429 mit rate_limited entspricht er t; bei einer 429 mit daily_quota_exceeded zählt er bis Mitternacht UTC und hat Vorrang vor t.

MCP-Antworten tragen diese Header nicht: Ein ratenbegrenzter MCP-Tool-Aufruf kommt stattdessen als Tool-Ergebnis zurück, das retry_after_seconds im Ergebniskörper führt; siehe MCP.

429 mit Code rate_limited

Die Anfragebegrenzung je Schlüssel wurde überschritten. Das Fenster ist kurz; warten Sie die Sekunden aus Retry-After ab und versuchen Sie es erneut.

json
{
  "error": {
    "code": "rate_limited",
    "message": "Rate limit exceeded. Retry after the number of seconds in Retry-After.",
    "retry_after_seconds": 21
  }
}

429 mit Code daily_quota_exceeded

Das Tageskontingent des Arbeitsbereichs ist aufgebraucht. Retry-After zählt bis Mitternacht UTC, wenn das Kontingent zurückgesetzt wird.

json
{
  "error": {
    "code": "daily_quota_exceeded",
    "message": "Daily quota exceeded. The quota resets at UTC midnight.",
    "retry_after_seconds": 14580
  }
}

503 mit Code quota_unavailable

Die Verbrauchsmessung war nicht erreichbar, deshalb wurde die Anfrage abgelehnt, statt ungemessen bedient zu werden. Es gibt kein Retry-After; versuchen Sie es mit Backoff erneut.

json
{
  "error": {
    "code": "quota_unavailable",
    "message": "The daily quota could not be verified. The request was refused."
  }
}

Hinweise zum erneuten Versuch

  • Bei 429 warten Sie die Sekunden aus Retry-After ab und versuchen es dann erneut.
  • Bei 503 versuchen Sie es mit exponentiellem Backoff und einer begrenzten Zahl von Versuchen erneut.
  • Takten Sie Ihre Anfragen nach RateLimit (r verbleibende Anfragen, t Sekunden bis zum Zurücksetzen), statt auf Ablehnungen zu reagieren.