> ## Documentation Index
> Fetch the complete documentation index at: https://docs.retriever.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Runs

> Cycle de vie d'un run Retriever : statuts, polling, idempotence, contrats de sortie JSON ou tables, artefacts et exports.

Un run confie une consigne à l'agent Retriever. Il est asynchrone : vous le créez, vous suivez son statut, puis vous lisez ses tables ou sa sortie.

## Cycle de vie

| Statut       | Sens                                                                                                |
| ------------ | --------------------------------------------------------------------------------------------------- |
| `queued`     | Enregistré, en attente d'un worker.                                                                 |
| `running`    | L'agent travaille. `progress.phase` décrit l'activité ; `last_heartbeat_at` date le dernier signal. |
| `recovering` | Le worker a perdu son bail ; un autre va reprendre le run. Traitez-le comme actif.                  |
| `completed`  | Terminé. Lisez `message`, `artifacts` et `output`.                                                  |
| `failed`     | Échec. Lisez `error.code` et `error.message`.                                                       |
| `cancelled`  | Annulé via `POST /v1/runs/{id}/cancel`. Les écritures déjà faites restent.                          |

## Créer un run

`POST /v1/runs` accepte `prompt` (requis), `workspace_id`, `conversation_id` et `output`. Tout autre champ est refusé.

* Sans `workspace_id` ni `conversation_id`, Retriever crée un workspace et une conversation.
* Avec `conversation_id`, le run continue une conversation existante. Un seul run peut être actif par conversation, sinon `409 conversation_busy`.
* La réponse `202` porte `Location` et `Retry-After: 5`.

### Idempotence

Envoyez un en-tête `Idempotency-Key` (non vide) pour pouvoir rejouer la création sans doublon :

* Même clé et même corps : `202` avec le run d'origine.
* Même clé et corps différent : `409 idempotency_conflict`.
* La clé est rattachée à l'utilisateur, pas à la clé API : deux clés API du même utilisateur partagent le même espace de noms.

## Suivre un run

Lisez `GET /v1/runs/{id}` jusqu'à `completed`, `failed` ou `cancelled` :

* Respectez `Retry-After` (15 secondes tant que le run est actif).
* Envoyez `If-None-Match` avec l'`ETag` reçu : l'API répond `304` sans corps si rien n'a changé.

## Choisir la sortie

| `output`                                                           | Résultat                                                          |
| ------------------------------------------------------------------ | ----------------------------------------------------------------- |
| absent                                                             | `message` et `artifacts` (tables vivantes). `output` vaut `null`. |
| `{"type":"json","schema":...}`                                     | Une valeur JSON validée par votre schéma.                         |
| `{"type":"tables","tables":[{"key":"contacts","row_schema":...}]}` | Une copie figée des tables choisies par l'agent, sous vos clés.   |

* Les schémas sont en JSON Schema draft 7, autonomes, validés **sans coercition**.
* Pour `tables`, la liste et chaque `row_schema` sont optionnels. Les clés doivent être uniques.
* Déclarez `["string", "null"]` pour tout champ qui peut manquer : un schéma trop strict empêche la publication et le run échoue.

Une fois le run terminé, `GET /v1/runs/{id}/output` renvoie :

* JSON : `type` vaut `json` et `value` contient la valeur.
* Tables : `type` vaut `tables` et `tables` liste chaque table (`key`, `source_table_id`, `columns`, `row_count`, `links`).

Les lignes figées se lisent avec `GET /v1/runs/{id}/output/tables/{key}/rows`. Elles contiennent `id`, `source_row_id`, `values`, `cells` et `fit`, et ne changent plus.

## Artefacts

`artifacts` liste les tables créées (`created`) ou modifiées (`updated`) par le run :

```json theme={null}
{
  "type": "table",
  "id": "tbl_001",
  "name": "Fintechs FR",
  "effect": "created",
  "links": { "self": "/v1/tables/tbl_001", "rows": "/v1/tables/tbl_001/rows" }
}
```

* Les artefacts pointent vers des tables **vivantes** : leur contenu peut changer après le run.
* La liste peut contenir des tables intermédiaires, ou être vide.
* Pour identifier la table finale sans deviner, utilisez un contrat `output` de type `tables`.

## Exporter

`POST /v1/runs/{id}/exports` avec `table_key` et `format` (`csv` ou `json`) génère l'export pendant la requête. La réponse `201` indique qu'il est prêt ; téléchargez-le avec `GET /v1/runs/{id}/exports/{exportId}`.

* L'export contient les valeurs métier, sans métadonnées de cellules.
* En CSV, les listes d'expériences et de formations sont aplaties en texte. Le JSON garde la structure.
