# Context pack: Virheet ja rajojen ylitykset

Source: https://nordvec.com/fi/docs/guides/errors-and-rate-limits
Pack: https://nordvec.com/fi/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. [Virheet ja rajojen ylitykset](https://nordvec.com/fi/docs/guides/errors-and-rate-limits) (this guide)
2. [MCP](https://nordvec.com/fi/docs/guides/mcp) (linked from this guide)

---

# Virheet ja rajojen ylitykset
Source: https://nordvec.com/fi/docs/guides/errors-and-rate-limits

Yksi virhekuori, jonka jokainen epäonnistunut pyyntö palauttaa, rajojen ylitystiedot otsikoissa ja kuinka kirjoitus voidaan yrittää uudelleen turvallisesti.



Jokainen päätepiste epäonnistuu samalla tavalla, joten asiakas käsittelee virheet, rajoitukset ja uusintayritykset kerran ja käyttää samaa koodia kaikkialla, myös [MCP:n](/docs/guides/mcp) yli.

## Virhekuori [#virhekuori]

Jokainen ei-2xx-vastaus on yksi JSON-objekti:

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

* `code` on HTTP-tason virhe, esimerkiksi `UNAUTHORIZED`, `FORBIDDEN`,
  `NOT_FOUND`, `BAD_REQUEST` tai `TOO_MANY_REQUESTS`.
* `data.reason`, kun se on olemassa, on tarkempi koneellisesti luettava syy, kuten
  `auth.key_not_found` tai `rate_limit.exceeded`. Haaraa sen perusteella eikä `message`:n perusteella,
  joka on tarkoitettu ihmisille ja voi muuttua.
* `defined` on `true`, kun toiminto luettelee kyseisen virheen
  [API-viitteessä](/docs/api), ja `false` virheille, joita mikä tahansa pyyntö voi kohdata
  (todennus, rajoitukset, tuntematon reitti).
* Validointivirhe vastaa `BAD_REQUEST`:llä, ja ongelmat ovat
  `data.formErrors`:ssä ja `data.fieldErrors`:ssä.

Jokainen vastaus sisältää myös `X-Request-ID`:n. Mainitse se, kun otat yhteyttä
tukeen, niin löydämme kyseisen pyynnön tarkasti.

## Yleiset tilakoodit [#yleiset-tilakoodit]

| Tilakoodi | Koodi                   | Toimenpide                                                            |
| --------- | ----------------------- | --------------------------------------------------------------------- |
| `400`     | `BAD_REQUEST`           | Korjaa pyyntö; `data.fieldErrors` nimeää kentät                       |
| `401`     | `UNAUTHORIZED`          | Lähetä kelvollinen avain tai istunto                                  |
| `403`     | `FORBIDDEN`             | Avaimella ei ole vaadittua käyttöoikeutta tai roolia toimintoa varten |
| `404`     | `NOT_FOUND`             | Resurssia ei ole olemassa, tai sinulla ei ole oikeutta nähdä sitä     |
| `409`     | `CONFLICT`              | Kaksoiskirjoitus on vielä kesken; yritä uudelleen pian                |
| `413`     | `PAYLOAD_TOO_LARGE`     | Pyynnön runko on yli 1 Mt; jaa massapush pienempiin eriin             |
| `429`     | `TOO_MANY_REQUESTS`     | Odota `Retry-After`, sitten yritä uudelleen                           |
| `422`     | `UNPROCESSABLE_CONTENT` | Pyyntö on hyvin muodostettu, mutta sitä ei voida soveltaa             |

## Rajoitukset [#rajoitukset]

Jokainen vastaus ilmoittaa rajoituksen, jota vastaan se laskettiin, kahdessa muodossa:

* `X-RateLimit-*`-otsikot;
* IETF:n strukturoidut kentät `RateLimit` (reaaliaikainen tila: `r` on jäljellä olevat pyynnöt,
  `t` sekuntia ikkunan nollaukseen) ja `RateLimit-Policy`
  (kiintiö: `q` on rajoitus, `w` ikkuna sekunteina).

`429` sisältää myös `Retry-After` sekunteina ja `data.retryAfterMs`. Odota vähintään niin kauan ennen seuraavaa pyyntöä;
aiempi uusintayritys lasketaan ja evätään uudelleen.

## Kirjoitusten turvallinen uusinta [#kirjoitusten-turvallinen-uusinta]

Kirjoitustoiminto, joka luettelee `Idempotency-Key`-otsikon
[API-viitteessä](/docs/api), voidaan uusia ilman, että työ tehdään kahdesti. Lähetä yksi avain loogista kirjoitusta kohden ja toista sama avain jokaisella uusintakerralla:

* sama avain samalla rungolla 24 tunnin sisällä toistaa tallennetun vastauksen;
* sama avain eri rungolla evätään `422`:llä;
* kaksoiskappale, joka saapuu, kun ensimmäinen on vielä käynnissä, saa `409`:n.

Toimintoa, jolla ei ole otsikkoa, ei ole idempotentti, joten yritä sitä uudelleen vain, kun tiedät, että ensimmäinen yritys ei onnistunut.


---

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

Yhdistä tekoälyagentti työtilasi tietopohjaan Model Context Protocolin kautta API-avaimella.



Nordvec toteuttaa [Model Context Protocolia](https://modelcontextprotocol.io) (MCP), joten MCP:tä puhuva agentti tai avustaja voi löytää työtilasi toiminnot työkaluina ja kutsua niitä natiivisti ilman OpenAPI-dokumenttia pääteltäväksi.

Palvelimia on kaksi:

| Palvelin      | URL                              | Tunnistautuminen | Mitä se paljastaa                                                                                      |
| ------------- | -------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------ |
| Dokumentaatio | `https://nordvec.com/api/mcp`    | ei mitään        | Nämä oppaat ja liittimien katalogi, agentille joka integroituu Nordveciin                              |
| Tietopohja    | `https://nordvec.com/api/v1/mcp` | API-avain        | Työtilasi dokumentit, haku ja tuonti: samat toiminnot kuin [REST API:ssa](/docs/guides/authentication) |

Molemmat toimivat EU:ssa, samalla infrastruktuurilla kuin muukin API.

## Asiakkaan yhdistäminen [#asiakkaan-yhdistäminen]

Ohjaa MCP-asiakas tietopohjapalvelimeen API-avaimellasi kantajana (bearer token). Useimmat asiakkaat ottavat vastaan määrityslohkon kuten tämän:

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

Palvelin on tilaton Streamable HTTP: jokainen viesti on yksi `POST`, joka kuljettaa yhtä JSON-RPC-pyyntöä, ja vastaus tulee takaisin vastauksen rungossa. Istuntoja ei säilytetä eikä palvelin aloita virtaa, joten `GET` URL-osoitteessa vastaa `405`, ja `POST`, jonka `Content-Type` ei ole `application/json`, vastaa `415` ennen kuin runkoa luetaan.

<Callout type="warn">
  Vain API-avain voi käyttää tietopohjapalvelinta. Kirjautunut selaimen istunto hylätään, ja jokainen työkalu vaatii saman avaimen käyttöoikeuden kuin vastaava REST-toiminto, joten yhdelle tehtävälle luotu avain voi tehdä täsmälleen saman tehtävän myös MCP:n kautta.
</Callout>

Palvelin tunnistaa staattisella kantaja-avaimella eikä tarjoa OAuth-hakua. Asiakas, jonka avulla voit asettaa pyyntöotsakkeita (koodaavat agentit, IDE-laajennukset, MCP Inspector otsaketilassa), yhdistää kuten yllä on esitetty. Isännöity asiakas, joka tukee vain OAuth-tunnistautumisvirtaa, ei voi vielä yhdistää.

Asiakas, joka lähettää `MCP-Protocol-Version`-otsakkeen, saa vastauksen kyseisessä versiossa, jos palvelin tukee sitä (`2025-06-18` ja `2024-11-05`), ja hylätään `400`-virheellä, jos ei tue, joten versioiden epäsopivuus raportoidaan ensimmäisessä viestissä eikä myöhemmin muodottomana vastauksena.

## Työkalut [#työkalut]

Työkalut johdetaan REST API:sta, yksi työkalu kutakin API-avaimella kutsuttavaa toimintoa kohti. Työkalun nimi on toiminnon sopimuksen polku snake case -muodossa, ja toistuva segmentti pudotetaan. Käyttöoikeus-sarakkeessa on API-avaimen käyttöoikeus, jota työkalu tarvitsee:

| REST-toiminto                         | Sopimuksen polku                     | MCP-työkalu                        | Vaadittu käyttöoikeus |
| ------------------------------------- | ------------------------------------ | ---------------------------------- | --------------------- |
| `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` on virallinen katalogi: se näyttää avaimen vain niille työkaluille, joiden käyttöoikeudet se sallii, ja jokaisen työkalun kuvaus nimeää vaaditun käyttöoikeuden. Työkalun `inputSchema` on toiminnon pyynnön skeema ja, jos toiminto palauttaa objektin, sen `outputSchema` on vastauksen skeema ja tulokset sisältävät `structuredContent`-kentän JSON-tekstin rinnalla.

Työkalun kutsuminen avaimen käyttöoikeuksien ulkopuolelta vastaa työkaluvirheellä, joka nimeää `FORBIDDEN`, sama hylkäys kuin REST-reitillä, joten asiakas, jolla on välimuistissa listaus toisesta avaimesta, oppii syyn eikä vain sitä, että työkalu puuttuu.

## Uudelleenyritys kirjoitukselle [#uudelleenyritys-kirjoitukselle]

`document_push` ja `document_push_bulk` ottavat valinnaisen `idempotencyKey`-argumentin, joten agentti tai asiakasohjelma, joka yrittää uudelleen push-toimintoa, ei indeksoi dokumentteja kahdesti. Lähetä yksi avain loogista kirjoitusta kohden, kuten UUID, ja toista sama avain samoilla argumenteilla jokaisella uudelleenyrityksellä:

* sama avain samoilla argumenteilla 24 tunnin sisällä palauttaa ensimmäisen kutsun tuloksen suorittamatta sitä uudelleen;
* sama avain eri argumenteilla hylätään: työkalun tulos on `isError: true` ja nimet `UNPROCESSABLE_CONTENT`;
* uudelleenkutsu, joka saapuu ensimmäisen kutsun ollessa vielä käynnissä, hylätään samalla tavalla nimeämällä `CONFLICT`; yritä uudelleen lyhyen viiveen jälkeen.

Avain on 1–256 tulostettavaa ASCII-merkkiä ja kuuluu sille API-avaimelle, joka sen lähetti: toinen API-avain, joka käyttää samaa arvoa, suorittaa oman kirjoituksensa. REST `Idempotency-Key` -otsaketta käyttävää avainta ei jaeta MCP-työkalun kanssa, joten työkalukutsu, joka käyttää sitä uudelleen, hylätään `UNPROCESSABLE_CONTENT`-virheellä. Kutsu ilman argumenttia suoritetaan joka kerta uudelleen, minkä vuoksi nämä työkalut eivät ilmoita `idempotentHint`. REST-käyttäytymistä kuvataan tarkemmin kohdassa [kirjoitusten turvallinen uusiminen](/docs/guides/errors-and-rate-limits).

## Rajoitukset ja virheet [#rajoitukset-ja-virheet]

Työkalukutsu käyttää samaa nopeusrajoituksen säiliötä kuin vastaava REST-toiminto, ja jokainen muu viesti päätepisteen omassa säiliössä. `X-RateLimit-*`-otsakkeet, `429`-vastaus `Retry-After`-kentällään ja virhekuori ovat samat kuin [REST API:ssa](/docs/guides/errors-and-rate-limits), joten asiakas, joka jo käsittelee niitä RESTissä, käsittelee ne täälläkin.

Epäonnistunut työkalukutsu palauttaa MCP-työkalutuloksen, jossa on `isError: true` ja jonka teksti on REST-virheen runko (`code`, `message`, `data`). Validointivirheet sisältävät saman `fieldErrors`-muodon kuin REST API. JSON-RPC-virhe on varattu protokollalle itselleen: jäsennysvirhe, tuntematon metodi tai palvelinvika.

Pyyntöjen rungot on rajattu 1 Mt:n kokoon, sama yläraja kuin REST-reiteillä.

## Ensimmäinen vaihto [#ensimmäinen-vaihto]

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

## Dokumentaatiopalvelin [#dokumentaatiopalvelin]

Dokumentaatiopalvelin osoitteessa `/api/mcp` ei tarvitse avainta. Se tarjoaa `list_guides`, `get_guide`, `search_docs` ja `list_connectors`, joten API:n päälle sovellusta rakentava agentti voi lukea nämä oppaat suoraan. Se on nopeusrajoitettu IP-osoitteen mukaan kuten muutkin julkiset päätepisteet.
