# Lancer et suivre un crawl

> Créer une campagne, lancer un crawl de façon sûre, suivre son avancement et savoir quand ses rapports sont prêts.

## Choisir ou créer une campagne

Les campagnes d’un projet :

```bash
curl "https://api.nessflow.com/v1/projects/$PROJECT_ID/campaigns" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN"
```

Pour un audit hebdomadaire de 500 pages avec rendu JavaScript :

```bash expect=201
curl -X POST "https://api.nessflow.com/v1/projects/$PROJECT_ID/campaigns" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"name": "Audit hebdomadaire", "start_url": "https://exemple.fr/", "max_depth": 5, "max_urls": 500, "javascript_rendering": true, "schedule": {"frequency": "weekly", "day": "monday", "time": "06:00"}}'
```

`name`, `start_url`, `max_depth` et `max_urls` sont requis. Un champ inconnu est refusé (`422`), jamais ignoré : une faute de frappe ne passe pas en silence.

## Lancer le crawl

Lancer un crawl consomme un crawl du quota mensuel de votre offre. L’en-tête `Idempotency-Key` est donc **exigé** : si la réponse se perd et que vous réessayez avec la même clé, l’API rend la première réponse au lieu de lancer un second crawl.

```bash expect=202
curl -X POST "https://api.nessflow.com/v1/campaigns/$CAMPAIGN_ID/crawls" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN" \
  -H "Idempotency-Key: $(uuidgen)"
```

Un seul crawl tourne à la fois par équipe. Si un crawl est déjà en cours, l’API répond `409 crawl.already_running`, avec `active_crawl_id`.

## Suivre l’avancement

```bash
curl "https://api.nessflow.com/v1/crawls/$CRAWL_ID" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN"
```

Trois champs suffisent :

- `active` : `true` tant que le crawl tourne. C’est le serveur qui en décide, y compris pour un crawl resté sans exécutant ;
- `status` : `queued`, `running`, puis `completed`, `failed` ou `stopped` ;
- `stage_plan.settled` : `true` quand **tous** les rapports sont calculés.

`status: completed` arrive avant la fin du post-traitement : attendez `settled` avant de lire les rapports. Plutôt que de sonder, abonnez un webhook à `crawl.completed`.

## Arrêter un crawl

L’arrêt est synchrone, et jamais refusé pour une raison de facturation :

```bash
curl -X POST "https://api.nessflow.com/v1/crawls/$CRAWL_ID/stop" \
  -H "Authorization: Bearer $NESSFLOW_TOKEN"
```
