# Context pack: Erreurs et limites de débit

Source: https://nordvec.com/fr/docs/guides/errors-and-rate-limits
Pack: https://nordvec.com/fr/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. [Erreurs et limites de débit](https://nordvec.com/fr/docs/guides/errors-and-rate-limits) (this guide)
2. [MCP](https://nordvec.com/fr/docs/guides/mcp) (linked from this guide)

---

# Erreurs et limites de débit
Source: https://nordvec.com/fr/docs/guides/errors-and-rate-limits

L'enveloppe d'erreur unique que chaque requête échouée retourne, les en-têtes de limite de débit, et comment réessayer une écriture en toute sécurité.



Chaque point de terminaison échoue de la même manière, donc un client gère les erreurs, les limites de débit et les nouvelles tentatives une seule fois et réutilise ce code partout, y compris via [MCP](/docs/guides/mcp).

## L'enveloppe d'erreur [#lenveloppe-derreur]

Chaque réponse non-2xx est un objet JSON unique :

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

* `code` est l'erreur au niveau HTTP, par exemple `UNAUTHORIZED`, `FORBIDDEN`,
  `NOT_FOUND`, `BAD_REQUEST` ou `TOO_MANY_REQUESTS`.
* `data.reason`, lorsqu'il est présent, est une raison plus précise lisible par machine, comme
  `auth.key_not_found` ou `rate_limit.exceeded`. Effectuez une branche sur celui-ci plutôt que sur
  `message`, qui est destiné aux utilisateurs et peut changer.
* `defined` est `true` lorsque l'opération répertorie cette erreur dans la
  [référence de l'API](/docs/api), et `false` pour les erreurs que toute requête peut rencontrer
  (authentification, limites de débit, une route inconnue).
* Un échec de validation répond `BAD_REQUEST` avec les problèmes dans
  `data.formErrors` et `data.fieldErrors`.

Chaque réponse comporte également un `X-Request-ID`. Citez-le lorsque vous contactez
le support, et nous pourrons retrouver cette requête exacte.

## Statuts courants [#statuts-courants]

| Statut | Code                    | Que faire                                                                           |
| ------ | ----------------------- | ----------------------------------------------------------------------------------- |
| `400`  | `BAD_REQUEST`           | Corrigez la requête ; `data.fieldErrors` nomme les champs                           |
| `401`  | `UNAUTHORIZED`          | Envoyez une clé ou une session valide                                               |
| `403`  | `FORBIDDEN`             | La clé ne dispose pas de l'étendue ou du rôle requis par l'opération                |
| `404`  | `NOT_FOUND`             | La ressource n'existe pas, ou vous n'êtes pas autorisé à la voir                    |
| `409`  | `CONFLICT`              | Une écriture en double est toujours en cours ; réessayez sous peu                   |
| `413`  | `PAYLOAD_TOO_LARGE`     | Le corps de la requête dépasse 1 Mo ; divisez un envoi en masse en lots plus petits |
| `422`  | `UNPROCESSABLE_CONTENT` | La requête est bien formée mais ne peut pas être appliquée                          |
| `429`  | `TOO_MANY_REQUESTS`     | Attendez `Retry-After`, puis réessayez                                              |

## Limites de débit [#limites-de-débit]

Chaque réponse indique la limite contre laquelle elle a été comptabilisée, sous deux formes :

* les en-têtes `X-RateLimit-*` ;
* les champs structurés IETF `RateLimit` (état en direct : `r` est le nombre de requêtes
  restantes, `t` le nombre de secondes avant la réinitialisation de la fenêtre) et `RateLimit-Policy`
  (le quota : `q` est la limite, `w` la fenêtre en secondes).

Une réponse `429` comporte également `Retry-After` en secondes et `data.retryAfterMs`. Attendez au moins
ce délai avant la requête suivante ; une nouvelle tentative plus tôt est comptabilisée et
refusée à nouveau.

## Réessayer les écritures en toute sécurité [#réessayer-les-écritures-en-toute-sécurité]

Une opération d'écriture qui répertorie un en-tête `Idempotency-Key` dans la
[référence de l'API](/docs/api) peut être réessayée sans effectuer le travail deux fois. Envoyez
une clé par écriture logique et répétez la même clé à chaque nouvelle tentative :

* la même clé avec le même corps dans les 24 heures rejoue la réponse stockée ;
* la même clé avec un corps différent est refusée avec `422` ;
* un doublon qui arrive alors que la première tentative est toujours en cours reçoit `409`.

Une opération sans cet en-tête n'est pas idempotente, donc ne la réessayez que lorsque vous
savez que la première tentative n'a pas abouti.


---

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

Connectez un agent IA à votre base de connaissances de l'espace de travail via le Model Context Protocol avec une clé API.



Nordvec implémente le [Model Context Protocol](https://modelcontextprotocol.io) (MCP), de sorte qu'un agent ou un assistant parlant MCP peut découvrir les opérations de votre espace de travail en tant qu'outils et les appeler de manière native, sans document OpenAPI pour raisonner dessus.

Il existe deux serveurs :

| Serveur               | URL                              | Authentification | Ce qu'il expose                                                                                                                            |
| --------------------- | -------------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Documentation         | `https://nordvec.com/api/mcp`    | aucune           | Ces guides et le catalogue des connecteurs, pour un agent qui s'intègre à Nordvec                                                          |
| Base de connaissances | `https://nordvec.com/api/v1/mcp` | clé API          | Les documents de votre espace de travail, la recherche et l'ingestion : les mêmes opérations que l'[API REST](/docs/guides/authentication) |

Les deux s'exécutent dans l'UE, sur la même infrastructure que le reste de l'API.

## Connexion d'un client [#connexion-dun-client]

Pointez un client MCP vers le serveur de base de connaissances avec votre clé API comme jeton porteur. La plupart des clients acceptent un bloc de configuration comme celui-ci :

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

Le serveur est un HTTP Streamable sans état : chaque message est une `POST` transportant une requête JSON-RPC, et la réponse revient dans le corps de la réponse. Il n'y a pas de sessions à maintenir et aucun flux initié par le serveur, donc une `GET` sur l'URL répond `405`, et une `POST` dont le `Content-Type` n'est pas `application/json` répond `415` avant que le corps ne soit lu.

<Callout type="warn">
  Seule une clé API peut utiliser le serveur de base de connaissances. Une session de navigateur connectée est refusée, et chaque outil nécessite la portée de clé API correspondant à l'opération REST associée, de sorte qu'une clé créée pour une tâche spécifique peut effectuer exactement cette tâche via MCP également.
</Callout>

Le serveur s'authentifie avec une clé porteuse statique et ne propose pas de découverte OAuth. Un client qui vous permet de définir des en-têtes de requête (agents de codage, extensions d'IDE, l'inspecteur MCP en mode en-tête) se connecte comme indiqué ci-dessus ; un client hébergé ne supportant que le flux d'autorisation OAuth ne peut pas encore se connecter.

Un client qui envoie l'en-tête `MCP-Protocol-Version` reçoit une réponse sous cette version lorsque le serveur la supporte (`2025-06-18` et `2024-11-05`) et est refusé avec `400` lorsqu'il ne la supporte pas, de sorte qu'une incompatibilité de version est signalée dès le premier message plutôt que sous la forme d'une réponse mal formée ultérieurement.

## Outils [#outils]

Les outils sont dérivés de l'API REST, un outil par opération qu'une clé API peut appeler. Le nom d'un outil est le chemin du contrat de l'opération en snake case, avec un segment qui répète le précédent supprimé. La colonne de portée indique la portée de clé API dont l'outil a besoin :

| Opération REST                        | Chemin du contrat                    | Outil MCP                          | Portée         |
| ------------------------------------- | ------------------------------------ | ---------------------------------- | -------------- |
| `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` fait autorité : il n'affiche qu'une clé et les outils que ses portées autorisent, et la description de chaque outil mentionne la portée qu'il requiert. Le `inputSchema` d'un outil est le schéma de requête de l'opération et, lorsque l'opération retourne un objet, son `outputSchema` est le schéma de réponse et les résultats comportent `structuredContent` en plus du texte JSON.

L'appel d'un outil que les portées de la clé n'autorisent pas répond avec une erreur d'outil mentionnant `FORBIDDEN`, le même refus que la route REST, de sorte qu'un client détenant une liste mise en cache d'une autre clé comprend pourquoi plutôt que de constater l'absence de l'outil.

## Nouvelle tentative d'écriture [#nouvelle-tentative-décriture]

`document_push` et `document_push_bulk` acceptent un argument facultatif `idempotencyKey`,
de sorte qu’un agent ou un client qui relance un envoi ne réindexe pas les
documents deux fois. Envoyez une clé par écriture logique, comme un UUID, et répétez
la même clé avec les mêmes arguments à chaque nouvelle tentative :

* la même clé avec les mêmes arguments dans un délai de 24 heures renvoie le résultat du premier appel sans l'exécuter à nouveau;
* la même clé avec des arguments différents est refusée : le résultat de l'outil comporte `isError: true` et nomme `UNPROCESSABLE_CONTENT`;
* une nouvelle tentative qui arrive alors que le premier appel est toujours en cours est refusée de la même manière, en nommant `CONFLICT`; réessayez après un court délai.

Une clé comprend de 1 à 256 caractères ASCII imprimables et appartient à la clé API qui l’a envoyée : une autre clé API utilisant la même valeur exécute sa propre écriture. Une clé utilisée avec l’en-tête REST `Idempotency-Key` n’est pas partagée avec l’outil MCP, donc un appel d’outil qui la réutilise est refusé avec le code `UNPROCESSABLE_CONTENT`. Un appel sans cet argument s’exécute à nouveau à chaque fois, c’est pourquoi ces outils ne déclarent pas `idempotentHint`. Le comportement REST est décrit dans la section [réessayer des écritures en toute sécurité](/docs/guides/errors-and-rate-limits).

## Limites et erreurs [#limites-et-erreurs]

Un appel d'outil utilise le même seau de limitation de débit que l'opération REST correspondante, et chaque autre message sur le point de terminaison utilise son propre seau. Les en-têtes `X-RateLimit-*`, la réponse `429` avec son `Retry-After`, et l'enveloppe d'erreur sont identiques à ceux de l'[API REST](/docs/guides/errors-and-rate-limits), de sorte qu'un client qui les gère déjà pour REST les gère également ici.

Un appel d'outil échoué retourne un résultat d'outil MCP avec `isError: true` dont le texte est le corps d'erreur REST (`code`, `message`, `data`) ; les échecs de validation comportent la même forme `fieldErrors` que celle retournée par l'API REST. Une erreur JSON-RPC est réservée au protocole lui-même : un corps illisible, une méthode inconnue ou une défaillance du serveur.

Les corps de requête sont limités à 1 Mo, la même limite que pour les routes REST.

## Un premier échange [#un-premier-échange]

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

## Le serveur de documentation [#le-serveur-de-documentation]

Le serveur de documentation à l'adresse `/api/mcp` ne nécessite aucune clé. Il propose `list_guides`, `get_guide`, `search_docs` et `list_connectors`, de sorte qu'un agent construisant une application sur l'API peut lire ces guides directement. Il est limité en débit par IP comme les autres points de terminaison publics.
