# Context pack: Błędy i limity zapytań

Source: https://nordvec.com/pl/docs/guides/errors-and-rate-limits
Pack: https://nordvec.com/pl/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. [Błędy i limity zapytań](https://nordvec.com/pl/docs/guides/errors-and-rate-limits) (this guide)
2. [MCP](https://nordvec.com/pl/docs/guides/mcp) (linked from this guide)

---

# Błędy i limity zapytań
Source: https://nordvec.com/pl/docs/guides/errors-and-rate-limits

Jedna struktura błędu zwracana przy każdym nieudanym zapytaniu, nagłówki limitu zapytań oraz jak bezpiecznie ponowić zapis.



Każdy endpoint zwraca błędy w ten sam sposób, więc obsługujesz błędy, limity i ponawianie żądań raz, a następnie używasz tego kodu wszędzie, także przez [MCP](/docs/guides/mcp).

## Struktura odpowiedzi błędu [#struktura-odpowiedzi-błędu]

Każda odpowiedź, która nie jest kodem 2xx, to jeden obiekt JSON:

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

* `code` to błąd na poziomie HTTP, na przykład `UNAUTHORIZED`, `FORBIDDEN`,
  `NOT_FOUND`, `BAD_REQUEST` lub `TOO_MANY_REQUESTS`.
* `data.reason`, jeśli występuje, to dokładniejszy, zrozumiały dla maszyny powód, taki jak
  `auth.key_not_found` lub `rate_limit.exceeded`. Rozgałęziaj kod na podstawie tego pola, a nie na podstawie
  `message`, które jest przeznaczone dla ludzi i może się zmienić.
* `defined` to `true`, gdy operacja wymienia ten błąd w
  [dokumentacji API](/docs/api), oraz `false` dla błędów, które może napotkać każde żądanie
  (uwierzytelnianie, limity, nieznana ścieżka).
* Nieudana walidacja zwraca `BAD_REQUEST` z problemami w
  `data.formErrors` i `data.fieldErrors`.

Każda odpowiedź zawiera również `X-Request-ID`. Cytuj go, gdy kontaktujesz się z pomocą techniczną,
a my odnajdziemy dokładnie to żądanie.

## Najczęstsze kody statusów [#najczęstsze-kody-statusów]

| Status | Kod                     | Co zrobić                                                                      |
| ------ | ----------------------- | ------------------------------------------------------------------------------ |
| `400`  | `BAD_REQUEST`           | Popraw żądanie; `data.fieldErrors` wskazuje pola                               |
| `401`  | `UNAUTHORIZED`          | Wyślij poprawny klucz lub sesję                                                |
| `403`  | `FORBIDDEN`             | Klucz nie ma wymaganego zakresu lub roli dla tej operacji                      |
| `404`  | `NOT_FOUND`             | Zasób nie istnieje lub nie masz do niego dostępu                               |
| `409`  | `CONFLICT`              | Duplikowane żądanie zapisu jest w trakcie przetwarzania; ponów próbę za chwilę |
| `413`  | `PAYLOAD_TOO_LARGE`     | Ciało żądania przekracza 1 MB; podziel przesyłanie zbiorcze na mniejsze partie |
| `422`  | `UNPROCESSABLE_CONTENT` | Żądanie jest poprawnie sformułowane, ale nie może zostać zastosowane           |
| `429`  | `TOO_MANY_REQUESTS`     | Poczekaj na `Retry-After`, a następnie ponów próbę                             |

## Limity żądań [#limity-żądań]

Każda odpowiedź zawiera informacje o limicie, względem którego zostało zliczone żądanie, w dwóch formach:

* nagłówki `X-RateLimit-*`;
* strukturalne pola IETF `RateLimit` (aktualny stan: `r` to liczba pozostałych żądań,
  `t` to sekundy do resetu okna) oraz `RateLimit-Policy`
  (kwota: `q` to limit, `w` to okno w sekundach).

Odpowiedź `429` zawiera również `Retry-After` w sekundach oraz `data.retryAfterMs`. Poczekaj co najmniej tyle czasu przed następnym żądaniem; ponowienie próby wcześniej zostanie zliczone i odrzucone ponownie.

## Bezpieczne ponawianie żądań zapisu [#bezpieczne-ponawianie-żądań-zapisu]

Operacja zapisu, która wymienia nagłówek `Idempotency-Key` w
[dokumentacji API](/docs/api), może być ponawiana bez ryzyka podwójnego wykonania. Wyślij jeden klucz na logiczną operację zapisu i powtarzaj ten sam klucz przy każdej próbie ponowienia:

* ten sam klucz z tym samym ciałem w ciągu 24 godzin odtwarza zapisaną odpowiedź;
* ten sam klucz z innym ciałem jest odrzucany z kodem `422`;
* duplikat, który dotrze, gdy pierwsze żądanie jest jeszcze w trakcie przetwarzania, otrzymuje `409`.

Operacja bez tego nagłówka nie jest idempotentna, więc ponawiaj ją tylko wtedy, gdy wiesz, że pierwsza próba nie została zrealizowana.


---

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

Podłącz agenta AI do swojej bazy wiedzy w przestrzeni roboczej przez Model Context Protocol za pomocą klucza API.



Nordvec obsługuje [Model Context Protocol](https://modelcontextprotocol.io) (MCP), więc agent lub asystent, który komunikuje się w MCP, może odkrywać operacje Twojej przestrzeni roboczej jako narzędzia i wywoływać je natywnie, bez dokumentu OpenAPI do analizy.

Istnieją dwa serwery:

| Serwer       | URL                              | Uwierzytelnianie | Co udostępnia                                                                                                                 |
| ------------ | -------------------------------- | ---------------- | ----------------------------------------------------------------------------------------------------------------------------- |
| Dokumentacja | `https://nordvec.com/api/mcp`    | brak             | Te przewodniki i katalog łączników, dla agenta integrującego się z Nordvec                                                    |
| Baza wiedzy  | `https://nordvec.com/api/v1/mcp` | klucz API        | Dokumenty Twojej przestrzeni roboczej, wyszukiwanie i ingestię: te same operacje co w [API REST](/docs/guides/authentication) |

Oba działają w UE, na tej samej infrastrukturze co reszta API.

## Podłączanie klienta [#podłączanie-klienta]

Skonfiguruj klienta MCP, wskazując na serwer bazy wiedzy z Twoim kluczem API jako tokenem nośnym. Większość klientów przyjmuje blok konfiguracyjny podobny do tego:

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

Serwer jest bezstanowy i obsługuje strumieniowy HTTP: każda wiadomość to jedno `POST` przenoszące jedno żądanie JSON-RPC, a odpowiedź wraca w ciele odpowiedzi. Nie ma sesji do utrzymywania ani strumienia inicjowanego przez serwer, więc `GET` w adresie URL odpowiada `405`, a `POST`, którego `Content-Type` nie jest `application/json`, odpowiada `415` przed odczytaniem ciała.

<Callout type="warn">
  Tylko klucz API może korzystać z serwera bazy wiedzy. Odmowa następuje w przypadku zalogowanej sesji przeglądarki, a każde narzędzie wymaga zakresu klucza, który odpowiada wymaganiom operacji REST, więc klucz stworzony do jednego zadania może wykonać dokładnie to zadanie również przez MCP.
</Callout>

Serwer uwierzytelnia za pomocą statycznego klucza nośnego i nie oferuje odkrywania OAuth. Klient, który pozwala ustawić nagłówki żądań (agenty kodujące, rozszerzenia IDE, Inspektor MCP w trybie nagłówków), łączy się jak pokazano powyżej. Hostowany klient, który obsługuje tylko przepływ autoryzacji OAuth, nie może jeszcze się połączyć.

Klient, który wysyła nagłówek `MCP-Protocol-Version`, otrzymuje odpowiedź w tej wersji, jeśli serwer ją obsługuje (`2025-06-18` i `2024-11-05`), a odmowę z `400`, jeśli nie, więc niezgodność wersji jest raportowana przy pierwszej wiadomości, a nie jako nieprawidłowa odpowiedź później.

## Narzędzia [#narzędzia]

Narzędzia są wyprowadzane z API REST, jedno narzędzie na operację, którą może wywołać klucz API. Nazwa narzędzia to ścieżka kontraktu operacji w formacie snake\_case, z segmentem powtarzającym poprzedni pominiętym. Kolumna zakresu to zakres klucza API, którego narzędzie wymaga:

| Operacja REST                         | Ścieżka kontraktu                    | Narzędzie MCP                      | Zakres         |
| ------------------------------------- | ------------------------------------ | ---------------------------------- | -------------- |
| `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` to autorytatywny katalog: pokazuje klucz tylko te narzędzia, na które pozwalają jego zakresy, a opis każdego narzędzia zawiera nazwę wymaganego zakresu. `inputSchema` narzędzia to schemat żądania operacji, a jeśli operacja zwraca obiekt, jego `outputSchema` to schemat odpowiedzi, a wyniki zawierają `structuredContent` obok tekstu JSON.

Wywołanie narzędzia, na które nie pozwalają zakresy klucza, kończy się błędem narzędzia z nazwą `FORBIDDEN`, taką samą odmową jak w przypadku trasy REST, więc klient przechowujący buforowaną listę z innego klucza dowiaduje się dlaczego, a nie tylko tego, że narzędzie jest niedostępne.

## Ponawianie zapisu [#ponawianie-zapisu]

`document_push` i `document_push_bulk` przyjmują opcjonalny argument `idempotencyKey`,
więc agent lub klient, który ponawia przesyłanie, nie indeksuje
dokumentów dwukrotnie. Prześlij jeden klucz na logiczny zapis, na przykład UUID, i powtarzaj
ten sam klucz z tymi samymi argumentami przy każdym ponowieniu:

* ten sam klucz z tymi samymi argumentami w ciągu 24 godzin zwraca wynik pierwszego wywołania bez ponownego uruchamiania;
* ten sam klucz z innymi argumentami jest odrzucany: wynik narzędzia ma `isError: true` i zawiera nazwę `UNPROCESSABLE_CONTENT`;
* ponowna próba, która nadejdzie, gdy pierwsze wywołanie nadal trwa, jest odrzucana w ten sam sposób, podając nazwę `CONFLICT`; spróbuj ponownie po krótkim opóźnieniu.

Klucz składa się z 1 do 256 drukowalnych znaków ASCII i należy do klucza API, który go wysłał: inny klucz API używający tej samej wartości uruchamia własne zapisywanie. Klucz użyty z nagłówkiem REST `Idempotency-Key` nie jest współdzielony z narzędziem MCP, dlatego wywołanie narzędzia, które go ponownie używa, jest odrzucane z kodem `UNPROCESSABLE_CONTENT`. Wywołanie bez tego argumentu jest wykonywane za każdym razem od nowa, dlatego te narzędzia nie deklarują `idempotentHint`. Zachowanie REST jest opisane w sekcji [bezpieczne ponawianie zapisów](/docs/guides/errors-and-rate-limits).

## Limity i błędy [#limity-i-błędy]

Wywołanie narzędzia korzysta z tego samego limitu szybkości co odpowiadająca mu operacja REST, a każda inna wiadomość na tym samym punkcie końcowym z własnego limitu. Nagłówki `X-RateLimit-*`, odpowiedź `429` z jej `Retry-After` oraz koperta błędu są takie same jak w [API REST](/docs/guides/errors-and-rate-limits), więc klient, który już je obsługuje dla REST, poradzi sobie z nimi tutaj.

Nieudane wywołanie narzędzia zwraca wynik narzędzia MCP z `isError: true`, którego tekst to treść błędu REST (`code`, `message`, `data`); błędy walidacji mają taki sam kształt `fieldErrors`, jaki zwraca API REST. Błąd JSON-RPC jest zarezerwowany dla samego protokołu: nieparsowalne ciało, nieznana metoda lub błąd serwera.

Ciała żądań są ograniczone do 1 MB, tak jak w przypadku tras REST.

## Pierwsza wymiana [#pierwsza-wymiana]

```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"}}}'
```

## Serwer dokumentacji [#serwer-dokumentacji]

Serwer dokumentacji pod adresem `/api/mcp` nie wymaga klucza. Oferuje `list_guides`, `get_guide`, `search_docs` i `list_connectors`, więc agent budujący aplikację na bazie API może bezpośrednio czytać te przewodniki. Jest ograniczany szybkością na adres IP, podobnie jak inne publiczne punkty końcowe.
