# API REST

L’API d’IAssistant donne accès à tes assistants, leurs conversations, les demandes reçues, les sources et les questions sans réponse. Elle sert les mêmes outils que le serveur MCP (voir [Brancher un agent IA](/iassistant/docs/guides/agents-ia/)).

La description complète, au format OpenAPI 3.1, est publique :

```
https://app.hgdc.ch/iassistant/api/v1/openapi.json
```

## Adresse et authentification

Toutes les routes commencent par `https://app.hgdc.ch/iassistant/api/v1`. Chaque requête porte une clé d’API :

```sh
curl https://app.hgdc.ch/iassistant/api/v1/assistants \
  -H "Authorization: Bearer hgdc_iassistant_..."
```

Une clé se crée dans la console, page **API et agents IA**, par un admin de l’organisation. Elle ne s’affiche qu’une fois. Elle donne accès à tous les assistants de l’organisation, selon son accès :

| Accès                   | Portée             | Ce qu’elle permet |
| ----------------------- | ------------------ | ----------------- |
| **Lecture**             | `iassistant:read`  | Les routes `GET`  |
| **Lecture et écriture** | `iassistant:write` | Toutes les routes |

Une clé expire après 30 jours, 90 jours, 1 an, ou jamais, selon ton choix. Une clé révoquée ou expirée est refusée tout de suite.

## Routes

`{assistant_id}` vient de `GET /assistants`. Les autres identifiants viennent des listes.

| Méthode  | Route                                                        | Effet                                                                                                          | Accès    |
| -------- | ------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------- | -------- |
| `GET`    | `/assistants`                                                | Liste les assistants                                                                                           | Lecture  |
| `GET`    | `/assistants/{assistant_id}`                                 | Réglages complets d’un assistant                                                                               | Lecture  |
| `PATCH`  | `/assistants/{assistant_id}`                                 | Change le nom, le modèle, la consigne, l’apparence ou les limites                                              | Écriture |
| `POST`   | `/assistants/{assistant_id}/enabled`                         | Active ou coupe la bulle (`{ "enabled": false }`)                                                              | Écriture |
| `GET`    | `/assistants/{assistant_id}/conversations`                   | Conversations, de la plus récente à la plus ancienne (`with_request=true` : seulement celles avec une demande) | Lecture  |
| `GET`    | `/assistants/{assistant_id}/conversations/{conversation_id}` | Une conversation et ses messages                                                                               | Lecture  |
| `GET`    | `/assistants/{assistant_id}/requests`                        | Demandes laissées par les visiteurs                                                                            | Lecture  |
| `DELETE` | `/requests/{request_id}`                                     | Supprime une demande                                                                                           | Écriture |
| `GET`    | `/assistants/{assistant_id}/sources`                         | Sources et état de leur lecture                                                                                | Lecture  |
| `POST`   | `/assistants/{assistant_id}/faqs`                            | Ajoute une question et sa réponse (201)                                                                        | Écriture |
| `POST`   | `/assistants/{assistant_id}/texts`                           | Ajoute un texte (201)                                                                                          | Écriture |
| `POST`   | `/assistants/{assistant_id}/pages`                           | Ajoute des pages du site, 50 au plus (202)                                                                     | Écriture |
| `POST`   | `/assistants/{assistant_id}/sitemaps`                        | Importe un sitemap (202)                                                                                       | Écriture |
| `POST`   | `/assistants/{assistant_id}/recrawl`                         | Relit les pages ; avec `source_id`, une seule source (202)                                                     | Écriture |
| `DELETE` | `/sources/{source_id}`                                       | Supprime une source                                                                                            | Écriture |
| `GET`    | `/assistants/{assistant_id}/unanswered`                      | Questions sans réponse                                                                                         | Lecture  |
| `POST`   | `/unanswered/{question_id}/answer`                           | Répond : la réponse devient une question fréquente (201)                                                       | Écriture |
| `DELETE` | `/unanswered/{question_id}`                                  | Écarte une question                                                                                            | Écriture |
| `GET`    | `/usage`                                                     | Messages et crédits du mois                                                                                    | Lecture  |

Les corps sont en JSON, 256 Kio au plus. Les champs inconnus sont refusés. Les tailles maximales sont celles de la console : voir [Limites et valeurs](/iassistant/docs/reference/limites/).

Origines du site, actions (destinataires des e-mails, webhook), création et suppression d’un assistant restent dans la console.

### Exemple : ajouter une question fréquente

```sh
curl -X POST https://app.hgdc.ch/iassistant/api/v1/assistants/ASSISTANT_ID/faqs \
  -H "Authorization: Bearer hgdc_iassistant_..." \
  -H "Content-Type: application/json" \
  -d '{"question":"Livrez-vous en Valais ?","answer":"Oui, sous 48 heures."}'
```

```json
{ "source_id": "...", "status": "pending" }
```

## Pagination

Les conversations, les demandes et les questions sans réponse arrivent par pages :

```json
{ "data": [ ... ], "next_cursor": "...", "has_more": true }
```

`limit` choisit la taille (1 à 100, 20 par défaut). Pour la page suivante, passe `cursor=<next_cursor>`. Les autres listes renvoient `{ "data": [ ... ] }` en entier.

## Erreurs

Les erreurs suivent le format `application/problem+json` (RFC 9457) :

```json
{ "type": "about:blank", "title": "Not Found", "status": 404, "detail": "Cet assistant n'existe pas." }
```

| Code | Quand                                                                                                                               |
| ---- | ----------------------------------------------------------------------------------------------------------------------------------- |
| 401  | Clé absente, inconnue, révoquée ou expirée. L’en-tête `WWW-Authenticate` indique où lire les métadonnées.                           |
| 403  | La clé n’a que la lecture (`insufficient_scope`). Il manque la portée `iassistant:write`, nommée dans l’en-tête `WWW-Authenticate`. |
| 404  | Route ou ressource introuvable. Un identifiant d’une autre organisation répond aussi 404.                                           |
| 405  | Méthode non prévue sur cette route. L’en-tête `Allow` liste les bonnes.                                                             |
| 413  | Corps trop gros.                                                                                                                    |
| 422  | Corps ou paramètres refusés. `errors` détaille chaque champ.                                                                        |
| 429  | Trop de requêtes. Attends le délai de `Retry-After`.                                                                                |

## Limites de débit

| Quoi                        | Limite                        |
| --------------------------- | ----------------------------- |
| Lectures par clé            | 600 par minute, rafale de 120 |
| Écritures par clé           | 120 par minute, rafale de 30  |
| Appels d’outils MCP par clé | 120 par minute, rafale de 30  |
| Clés refusées, par client   | 20 par tranche de 10 minutes  |

Chaque réponse porte les en-têtes `RateLimit-Policy` et `RateLimit`.
