Dokumentation der API

Fehler und Anfragebegrenzungen

Der Fehlerbody

Jede Ablehnung mit 4xx eines Endpunkts unter /v1 trägt ein strukturiertes Objekt error mit einem stabilen, maschinenlesbaren Code, ausgenommen die unten beschriebenen Antworten 422 und 413.

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

Code und Meldung sind je Art der Ablehnung festgelegt, nie je Aufrufstelle, damit eine Ablehnung nicht verrät, warum eine bestimmte Anfrage abgewiesen wurde. Heute ausgeliefert werden unauthenticated (401), forbidden (403), not_found (404), method_not_allowed (405), content_too_large (413), rate_limited und daily_quota_exceeded (429) sowie quota_unavailable und server_busy (503).

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, und bestehende Codes werden nicht 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 Umschlag error. Jeder seiner Einträge enthält type, loc und msg, nie den Wert, den Sie gesendet haben. Ein Wert eines Pfads oder einer Abfrage mit einem NUL Zeichen, das kein gespeicherter Wert enthalten kann, wird ebenso abgelehnt, genauso ein file_name mit einem solchen Zeichen an POST /v1/tenders/portals/upload.

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

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 Zugang zur API 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. Endpunkte unter /v1 nehmen ausschließlich GET entgegen, mit Ausnahme von POST /v1/citations/resolve, POST /v1/portfolio/import und POST /v1/tenders/portals/upload.
413Der Body der Anfrage ist zu groß. Ein Body umfasst höchstens 1.000.000 Bytes, ein Bestandsimport höchstens 2.000.000. Diese Ablehnung kann ohne Body ankommen.
422Die Anfrage hat die Validierung nicht bestanden. Der Body benennt den Parameter oder das Feld; dies ist die einzige 4xx ohne den Umschlag error.
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 und server_busy unten.

Anfragebegrenzungen

Für jede Anfrage, die ein Schlüssel für die API authentifiziert, gelten zwei Obergrenzen.

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

Jede Antwort unter /v1 nennt die Obergrenzen im Header RateLimit-Policy (siehe unten), sodass ein Client sie lesen kann, bevor er einen Schlüssel hält. Maßgeblich ist der Header, und die Werte in den Beispielen dieser Seite sind Beispiele.

Für eine angemeldete Person gelten stattdessen eigene Obergrenzen, bei jeder Anfrage ihrer Sitzung im Dashboard und unter /v1, gezählt je Person in jeder Kalenderminute. Sie erlauben höchstens 2.190 Lesezugriffe (GET und HEAD) und 60 Schreibzugriffe (jede andere Methode). An den fünf Downloads als PDF und an GET /v1/audit-log.csv zählen die Anfragen einer Person, Lesezugriffe eingeschlossen, zusätzlich gegen eine Obergrenze von 60 je Minute. Der Header RateLimit-Policy nennt nur die Obergrenzen eines Schlüssels, und eine Antwort an eine Person trägt keinen Zustand RateLimit. Unter /v1 wird eine Anfrage über einer Obergrenze mit einer 429 mit dem Code rate_limited, Retry-After und retry_after_seconds abgelehnt, und eine, deren Minute nicht gezählt werden kann, mit einer 503 mit dem Code quota_unavailable, wie bei einem Schlüssel.

Antwortheader

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

Jede Antwort über REST unter /v1 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 Kalendertag in UTC ist.
text
RateLimit-Policy: "key-minute";q=120;w=60, "workspace-day";q=50000;w=86400

Jede Antwort über REST unter /v1 auf eine von einem Schlüssel für die API 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, wobei r die Zahl der im laufenden Fenster verbleibenden Anfragen ist und 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 Unixzeitstempel in Sekunden; t Sekunden nach der Antwort.
text
RateLimit: "key-minute";r=87;t=42

Antworten mit 429 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.

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

429 mit Code rate_limited

Eine Obergrenze je Minute wurde überschritten, die Anfragebegrenzung eines Schlüssels oder eine eigene Obergrenze einer angemeldeten Person. 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 (das Tageskontingent oder das Minutenfenster, das sich die Prozesse der API teilen) war nicht erreichbar, deshalb wurde die Anfrage abgelehnt, statt ungemessen bedient zu werden. Es gibt kein Retry-After; versuchen Sie es mit Backoff erneut. Die Meldung nennt, welche der beiden Prüfungen nicht möglich war.

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

503 mit Code server_busy

Zu viele Abrufe sehr großer Unternehmen oder zu viele Renderaufträge für Dokumente liefen gleichzeitig, deshalb wurde diese Anfrage abgelehnt, bevor Daten gesendet wurden. GET /v1/nodes/{node_id} antwortet so für ein Unternehmen mit sehr vielen Registereinträgen, und die fünf Downloads als PDF antworten so, solange jeder Platz zum Rendern belegt ist, mit der Meldung The server is busy. Retry after the number of seconds in Retry-After. Warten Sie die Sekunden aus Retry-After ab und versuchen Sie es erneut. Die Einträge eines sehr großen Unternehmens lassen sich auch seitenweise über GET /v1/nodes/{node_id}/records lesen; siehe die Referenz der API.

json
{
  "error": {
    "code": "server_busy",
    "message": "Too many large reads are running. Retry after the number of seconds in Retry-After.",
    "retry_after_seconds": 3
  }
}

Hinweise zum erneuten Versuch

  • Bei 429 warten Sie die Sekunden aus Retry-After ab und versuchen es dann erneut.
  • Bei 503 mit server_busy warten Sie die Sekunden aus Retry-After ab und versuchen es dann erneut. Bei jeder anderen 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.