# Context pack: Fehler und Ratenbegrenzungen

Source: https://nordvec.com/de/docs/guides/errors-and-rate-limits
Pack: https://nordvec.com/de/docs/packs/errors-and-rate-limits

This pack bundles one Nordvec guide with the guides it builds on and the guides it links to, in reading order, so an assistant reading it meets no reference it cannot follow.

## Contents

1. [Fehler und Ratenbegrenzungen](https://nordvec.com/de/docs/guides/errors-and-rate-limits) (this guide)
2. [MCP](https://nordvec.com/de/docs/guides/mcp) (linked from this guide)

---

# Fehler und Ratenbegrenzungen
Source: https://nordvec.com/de/docs/guides/errors-and-rate-limits

Die eine Fehlerhülle, die jede fehlgeschlagene Anfrage zurückgibt, die Ratenbegrenzungs-Header und wie du einen Schreibvorgang sicher wiederholst.



Jeder Endpunkt schlägt auf die gleiche Weise fehl, daher behandelst du Fehler, Ratenlimits und Wiederholungsversuche einmal und verwendest diesen Code überall wieder, auch über [MCP](/docs/guides/mcp).

## Die Fehlerhülle [#die-fehlerhülle]

Jede nicht-2xx-Antwort ist ein JSON-Objekt:

```json
{
  "defined": false,
  "code": "TOO_MANY_REQUESTS",
  "message": "Too many requests",
  "data": { "reason": "rate_limit.exceeded", "retryAfterMs": 12000 }
}
```

* `code` ist der HTTP-Level-Fehler, zum Beispiel `UNAUTHORIZED`, `FORBIDDEN`,
  `NOT_FOUND`, `BAD_REQUEST` oder `TOO_MANY_REQUESTS`.
* `data.reason` ist, falls vorhanden, ein genauerer maschinenlesbarer Grund wie
  `auth.key_not_found` oder `rate_limit.exceeded`. Verzweige darauf statt auf
  `message`, das für Menschen gedacht ist und sich ändern kann.
* `defined` ist `true`, wenn die Operation diesen Fehler in der
  [API-Referenz](/docs/api) auflistet, und `false` für Fehler, die jede Anfrage treffen können
  (Authentifizierung, Ratenlimits, eine unbekannte Route).
* Eine Validierungsfehlermeldung antwortet mit `BAD_REQUEST` und den Problemen in
  `data.formErrors` und `data.fieldErrors`.

Jede Antwort enthält außerdem eine `X-Request-ID`. Gib sie an, wenn du den Support kontaktierst,
damit wir diese genaue Anfrage finden können.

## Häufige Statuscodes [#häufige-statuscodes]

| Status | Code                    | Was zu tun ist                                                                           |
| ------ | ----------------------- | ---------------------------------------------------------------------------------------- |
| `400`  | `BAD_REQUEST`           | Korrigiere die Anfrage; `data.fieldErrors` benennt die Felder                            |
| `401`  | `UNAUTHORIZED`          | Sende einen gültigen Schlüssel oder eine gültige Session                                 |
| `403`  | `FORBIDDEN`             | Der Schlüssel hat nicht den benötigten Scope oder die benötigte Rolle für die Operation  |
| `404`  | `NOT_FOUND`             | Die Ressource existiert nicht oder du darfst sie nicht sehen                             |
| `409`  | `CONFLICT`              | Ein doppelter Schreibvorgang ist noch in Bearbeitung; wiederhole den Versuch kurzfristig |
| `413`  | `PAYLOAD_TOO_LARGE`     | Der Anfragekörper ist über 1 MB groß; teile einen Massen-Push in kleinere Chargen auf    |
| `422`  | `UNPROCESSABLE_CONTENT` | Die Anfrage ist korrekt formuliert, kann aber nicht angewendet werden                    |
| `429`  | `TOO_MANY_REQUESTS`     | Warte `Retry-After`, dann wiederhole den Versuch                                         |

## Ratenlimits [#ratenlimits]

Jede Antwort gibt das Limit an, gegen das sie gezählt wurde, in zwei Formen:

* die `X-RateLimit-*`-Header;
* die IETF-Strukturfelder `RateLimit` (Live-Zustand: `r` sind die verbleibenden Anfragen,
  `t` die Sekunden bis zum Zurücksetzen des Fensters) und `RateLimit-Policy`
  (das Kontingent: `q` ist das Limit, `w` das Fenster in Sekunden).

Eine `429` enthält außerdem `Retry-After` in Sekunden und `data.retryAfterMs`. Warte mindestens so lange,
bevor du die nächste Anfrage sendest; ein früherer Wiederholungsversuch wird gezählt und
abgelehnt.

## Schreibvorgänge sicher wiederholen [#schreibvorgänge-sicher-wiederholen]

Ein Schreibvorgang, der einen `Idempotency-Key`-Header in der
[API-Referenz](/docs/api) auflistet, kann wiederholt werden, ohne die Arbeit doppelt auszuführen. Sende
einen Schlüssel pro logischem Schreibvorgang und wiederhole denselben Schlüssel bei jedem Wiederholungsversuch:

* derselbe Schlüssel mit demselben Body innerhalb von 24 Stunden gibt die gespeicherte Antwort erneut aus;
* derselbe Schlüssel mit einem anderen Body wird mit `422` abgelehnt;
* ein Duplikat, das ankommt, während der erste Vorgang noch läuft, erhält `409`.

Ein Vorgang ohne diesen Header ist nicht idempotent, daher wiederhole ihn nur, wenn du sicher bist,
dass der erste Versuch nicht erfolgreich war.


---

# MCP
Source: https://nordvec.com/de/docs/guides/mcp

Verbinde einen KI-Agenten mit deiner Arbeitsbereich-Wissensdatenbank über das Model Context Protocol mit einem API-Schlüssel.



Nordvec unterstützt das [Model Context Protocol](https://modelcontextprotocol.io)
(MCP), sodass ein Agent oder Assistent, der MCP spricht, die Operationen deines Arbeitsbereichs als Tools erkennen und nativ aufrufen kann, ohne ein OpenAPI-Dokument analysieren zu müssen.

Es gibt zwei Server:

| Server           | URL                              | Auth          | Was er bereitstellt                                                                                                              |
| ---------------- | -------------------------------- | ------------- | -------------------------------------------------------------------------------------------------------------------------------- |
| Dokumentation    | `https://nordvec.com/api/mcp`    | keine         | Diese Anleitungen und der Connector-Katalog für einen Agenten, der sich in Nordvec integriert                                    |
| Wissensdatenbank | `https://nordvec.com/api/v1/mcp` | API-Schlüssel | Die Dokumente, Suche und Ingestion deines Arbeitsbereichs: dieselben Operationen wie die [REST-API](/docs/guides/authentication) |

Beide laufen in der EU auf derselben Infrastruktur wie der Rest der API.

## Einen Client verbinden [#einen-client-verbinden]

Richte einen MCP-Client auf den Wissensdatenbank-Server mit deinem API-Schlüssel als Bearer-Token aus. Die meisten Clients akzeptieren einen Konfigurationsblock wie diesen:

```json
{
  "mcpServers": {
    "nordvec": {
      "url": "https://nordvec.com/api/v1/mcp",
      "headers": {
        "Authorization": "Bearer nv_eu_live_your_api_key"
      }
    }
  }
}
```

Der Server ist zustandsloses Streamable HTTP: Jede Nachricht ist ein `POST`, der eine JSON-RPC-Anfrage trägt, und die Antwort kommt im Antworttext zurück. Es gibt keine Sitzungen zu verwalten und keinen serverinitiierten Stream, sodass ein `GET` an der URL mit `405` antwortet und ein `POST`, dessen `Content-Type` nicht `application/json` ist, mit `415` antwortet, bevor der Body gelesen wird.

<Callout type="warn">
  Nur ein API-Schlüssel kann den Wissensdatenbank-Server nutzen. Eine angemeldete Browsersitzung wird abgelehnt, und jedes Tool benötigt den Schlüsselbereich, den die entsprechende REST-Operation erfordert. Ein Schlüssel, der für eine bestimmte Aufgabe erstellt wurde, kann diese Aufgabe also auch über MCP ausführen.
</Callout>

Der Server authentifiziert mit einem statischen Bearer-Schlüssel und bietet keine OAuth-Erkennung. Ein Client, der dir das Setzen von Request-Headern ermöglicht (KI-Agenten, IDE-Erweiterungen, der MCP-Inspector im Header-Modus), verbindet sich wie oben gezeigt. Ein gehosteter Client, der nur den OAuth-Autorisierungsfluss unterstützt, kann sich noch nicht verbinden.

Ein Client, der den `MCP-Protocol-Version`-Header sendet, erhält eine Antwort unter dieser Version, wenn der Server sie unterstützt (`2025-06-18` und `2024-11-05`), und wird mit `400` abgelehnt, wenn dies nicht der Fall ist. So wird eine Versionsinkompatibilität bereits bei der ersten Nachricht gemeldet, anstatt später als fehlerhafte Antwort.

## Tools [#tools]

Die Tools leiten sich von der REST-API ab, ein Tool pro Operation, die ein API-Schlüssel aufrufen darf. Der Name eines Tools ist der Vertragspfad der Operation in Snake-Case, wobei ein Segment, das sich wiederholt, weggelassen wird. Die Spalte „Scope“ gibt den API-Schlüssel-Scope an, den das Tool benötigt:

| REST-Operation                        | Vertragspfad                         | MCP-Tool                           | Scope          |
| ------------------------------------- | ------------------------------------ | ---------------------------------- | -------------- |
| `POST /documents/search`              | `documents.search`                   | `documents_search`                 | `search:read`  |
| `GET /documents/{id}`                 | `documents.get`                      | `documents_get`                    | `search:read`  |
| `POST /documents/batch`               | `documents.batchGet`                 | `documents_batch_get`              | `search:read`  |
| `GET /documents/list`                 | `documents.list`                     | `documents_list`                   | `search:read`  |
| `POST /documents/push`                | `documentPush.push`                  | `document_push`                    | `index:write`  |
| `POST /documents/push/bulk`           | `documentPush.pushBulk`              | `document_push_bulk`               | `index:write`  |
| `POST /documents/push/permissions`    | `documentPush.pushUpdatePermissions` | `document_push_update_permissions` | `index:write`  |
| `POST /documents/push/delete`         | `documentPush.pushDelete`            | `document_push_delete`             | `index:delete` |
| `GET /documents/push/status`          | `documentPush.pushStatus`            | `document_push_status`             | `index:status` |
| `GET /documents/push/upload`          | `documentPush.pushUploadStatus`      | `document_push_upload_status`      | `index:status` |
| `POST /documents/push/upload/restore` | `documentPush.pushUploadRestore`     | `document_push_upload_restore`     | `index:write`  |
| `GET /analytics/ingestion`            | `analytics.ingestion`                | `analytics_ingestion`              | `index:status` |
| `GET /quota/embedding`                | `quota.embedding`                    | `quota_embedding`                  | `quota:read`   |
| `GET /analytics/usage`                | `analytics.usage`                    | `analytics_usage`                  | `quota:read`   |
| `POST /tenant/audit-log/search`       | `auditLog.list`                      | `audit_log_list`                   | `audit:read`   |
| `GET /tenant/audit-log/catalog`       | `auditLog.catalog`                   | `audit_log_catalog`                | `audit:read`   |

`tools/list` ist der maßgebliche Katalog: Er zeigt nur die Tools an, die die Scopes des Schlüssels zulassen, und die Beschreibung jedes Tools nennt den erforderlichen Scope. Das `inputSchema` eines Tools ist das Anfrageschema der Operation und, falls die Operation ein Objekt zurückgibt, ist sein `outputSchema` das Antwortschema, und die Ergebnisse enthalten `structuredContent` neben dem JSON-Text.

Ein Aufruf eines Tools, das die Scopes des Schlüssels nicht zulassen, antwortet mit einem Tool-Fehler, der `FORBIDDEN` nennt, dieselbe Ablehnung wie bei der REST-Route. So erfährt ein Client mit einem zwischengespeicherten Listing von einem anderen Schlüssel, warum das Tool fehlt, anstatt nur, dass es fehlt.

## Erneuter Schreibversuch [#erneuter-schreibversuch]

`document_push` und `document_push_bulk` akzeptieren ein optionales `idempotencyKey`-Argument, sodass ein Agent oder Client, der einen Push erneut versucht, die Dokumente nicht zweimal indiziert. Sende einen Schlüssel pro logischem Schreibvorgang, z. B. eine UUID, und wiederhole denselben Schlüssel mit denselben Argumenten bei jedem erneuten Versuch:

* derselbe Schlüssel mit denselben Argumenten innerhalb von 24 Stunden gibt das Ergebnis des ersten Aufrufs zurück, ohne ihn erneut auszuführen;
* derselbe Schlüssel mit unterschiedlichen Argumenten wird abgelehnt: Das Tool-Ergebnis hat `isError: true` und nennt `UNPROCESSABLE_CONTENT`;
* ein erneuter Versuch, der eintrifft, während der erste Aufruf noch läuft, wird auf dieselbe Weise abgelehnt und nennt `CONFLICT`; wiederhole ihn nach einer kurzen Verzögerung.

Ein Schlüssel besteht aus 1 bis 256 druckbaren ASCII-Zeichen und gehört zu dem API-Schlüssel, der ihn gesendet hat: Ein anderer API-Schlüssel, der denselben Wert verwendet, führt seinen eigenen Schreibvorgang aus. Ein Schlüssel, der mit dem REST-Header `Idempotency-Key` verwendet wird, wird nicht mit dem MCP-Tool geteilt, daher wird ein Tool-Aufruf, der ihn wiederverwendet, mit `UNPROCESSABLE_CONTENT` abgelehnt. Ein Aufruf ohne das Argument wird jedes Mal erneut ausgeführt, weshalb diese Tools `idempotentHint` nicht deklarieren. Das REST-Verhalten wird unter [Schreibvorgänge sicher wiederholen](/docs/guides/errors-and-rate-limits) beschrieben.

## Limits und Fehler [#limits-und-fehler]

Ein Tool-Aufruf greift auf denselben Rate-Limit-Bucket zu wie die entsprechende REST-Operation und jede andere Nachricht auf dem Endpunkt auf einen eigenen Bucket. Die `X-RateLimit-*`-Header, die `429`-Antwort mit ihrem `Retry-After` und das Fehler-Envelope sind dieselben wie bei der [REST-API](/docs/guides/errors-and-rate-limits). Ein Client, der sie bereits für REST handhabt, kann sie hier also ebenfalls nutzen.

Ein fehlgeschlagener Tool-Aufruf gibt ein MCP-Tool-Ergebnis mit `isError: true` zurück, dessen Text der REST-Fehlerbody ist (`code`, `message`, `data`). Validierungsfehler enthalten dieselbe `fieldErrors`-Struktur, die die REST-API zurückgibt. Ein JSON-RPC-Fehler ist für das Protokoll selbst reserviert: ein nicht analysierbarer Body, eine unbekannte Methode oder ein Serverfehler.

Anfrage-Bodies sind auf 1 MB begrenzt, dieselbe Grenze wie bei den REST-Routen.

## Ein erster Austausch [#ein-erster-austausch]

```bash
# Discover the tools your key can call
curl https://nordvec.com/api/v1/mcp \
  -H "Authorization: Bearer $NORDVEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

# Search the workspace
curl https://nordvec.com/api/v1/mcp \
  -H "Authorization: Bearer $NORDVEC_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"documents_search","arguments":{"query":"data retention policy"}}}'
```

## Der Dokumentationsserver [#der-dokumentationsserver]

Der Dokumentationsserver unter `/api/mcp` benötigt keinen Schlüssel. Er bietet `list_guides`, `get_guide`, `search_docs` und `list_connectors` an, sodass ein Agent, der eine Anwendung auf der API aufbaut, diese Anleitungen direkt lesen kann. Er ist pro IP wie die anderen öffentlichen Endpunkte ratenbegrenzt.
