---
title: "Tester un agent de bout en bout (API)"
description: "Exécutez des simulations ponctuelles, des lots de scénarios parallèles et des suites de validation de version via l’API ThunderPhone afin de détecter les régressions des agents avant que les clients ne les entendent."
---

<Note>
  Vous préférez le dashboard ? Cette même fonctionnalité est disponible dans **Simulations**
  (`/dashboard/simulations`), y compris la génération de scénarios par IA — voir
  [Simuler un appel](/fr/guides/simulate-a-call). Cette page couvre l’approche
  programmatique.
</Note>

Itérer sur un agent IA implique d’itérer sur son prompt, ses outils
et sa gestion des cas limites. L’**API de simulations** exécute de vrais
appels auprès d’un agent à l’aide d’un prompt de scénario que vous fournissez. Cibler
un agent crée une exécution de bot à bot ; cibler un numéro de téléphone crée une
exécution en boucle SIP. Chaque exécution génère un journal d’appel réel avec
transcription, évaluation et facturation, afin que vous puissiez voir précisément comment l’agent
se comporte et ce qu’il coûte.

Utilisez-la pour :

- Des tests de bon fonctionnement avant le déploiement après chaque modification du prompt
- Des suites de régression intégrées à la CI (branchez le webhook `test-call.completed`
  → faites échouer le build si le score baisse)
- Tester les limites de concurrence sous contrainte

## Exécution unique : un seul scénario

```bash
curl -X POST https://api.thunderphone.com/v1/simulations \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_type":     "agent",
    "target_id":       12,
    "direction":       "outbound",
    "scenario_prompt": "You are a polite caller asking about refund policy for order 12345.",
    "consent_to_charge": true
  }'
```

Champs :

| Champ | Type | Obligatoire | Description |
|-------|------|----------|-------------|
| `target_type` | chaîne | oui | `agent` ou `phone_number` |
| `target_id` | entier | oui | L’identifiant de l’agent (ou l’identifiant du numéro de téléphone) |
| `direction` | chaîne | non | `outbound` (par défaut ; l’appelant de test appelle) ou `inbound` (l’appelant de test répond) |
| `scenario_prompt` | chaîne | non | Définit ce que dit le bot de test |
| `language` / `primary_language` | chaîne | non | Langue de l’appelant de test ; les codes non pris en charge sont rejetés |
| `simulator_product` | chaîne | non | `testing` (par défaut) ou `spark` pour un appelant simulé plus humain, par exemple pour des tests de consultation avant transfert à chaud |
| `consent_to_charge` | booléen | **oui** | Doit être `true`. L’estimation facture l’agent sélectionné et l’appelant simulé à un tarif fixe par minute, en plus de tout segment téléphonique |
| `target_number` | chaîne | non | Remplacement E.164 pour le côté distant ; sinon, le numéro de test de la plateforme est utilisé |

`mode` est en lecture seule et dérivé de `target_type` : `agent` produit
`mode="bot"`, tandis que `phone_number` produit `mode="sip"`.

La réponse est un [objet d’exécution de simulation](/api-reference/test-calls#test-call-run-object)
avec `status="queued"`. Interrogez-le jusqu’à ce que `status` devienne `completed` ou
`failed` ; une fois `call_id` défini, chargez la transcription via
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Lots : scénarios parallèles

Exécutez N scénarios simultanément — utile pour les suites de régression qui
couvrent chaque cas limite connu en parallèle :

```bash
curl -X POST https://api.thunderphone.com/v1/simulations/batches \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "target_type":     "agent",
    "target_id":       12,
    "direction":       "outbound",
    "run_count":       5,
    "stagger_seconds": 2,
    "scenario_prompts": [
      "Ask about refund policy.",
      "Ask for hours of operation.",
      "Complain about a delayed shipment.",
      "Ask to speak with a human.",
      "Ask an unrelated trivia question."
    ],
    "consent_to_charge": true
  }'
```

La réponse contient une liste `run_ids` d’identifiants d’exécutions enfants. Récupérez
l’état du lot :

```bash
curl https://api.thunderphone.com/v1/simulations/batches/{batch_id} \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

`run_count` est limité à 20 ; `stagger_seconds` espace les lancements
afin d’éviter de surcharger l’agent (0 à 60 s).

## L’intégrer à la CI

Créez une suite de validation des versions sur la page **Simulations**
(`/dashboard/simulations`) — choisissez l’agent, ajoutez des scénarios manuellement ou
cliquez sur **Générer des scénarios avec l’IA** pour les rédiger à partir du
prompt de l’agent (avec une passe facultative sur les cas limites), puis regroupez-les dans
une suite. Une suite fige ses scénarios et son agent, ainsi qu’un taux de réussite minimum et une
règle facultative exigeant zéro échec critique. Les exécutions réussies deviennent la référence
acceptée ; les transitions ultérieures de réussite à échec sont renvoyées comme régressions.

Utilisez une [clé API d’organisation](/api-reference/developer-api-keys) dans la CI.
Ce script déclenche la suite, interroge son état jusqu’à la fin de l’évaluation et de la comparaison,
puis se termine avec un code différent de zéro sauf si le verdict est `pass` :

```bash
#!/usr/bin/env bash
set -euo pipefail

: "${THUNDERPHONE_API_KEY:?Set THUNDERPHONE_API_KEY}"
: "${THUNDERPHONE_ORG_ID:?Set THUNDERPHONE_ORG_ID}"
: "${THUNDERPHONE_SUITE_ID:?Set THUNDERPHONE_SUITE_ID}"

base="https://api.thunderphone.com/v1/orgs/${THUNDERPHONE_ORG_ID}/suites/${THUNDERPHONE_SUITE_ID}"
auth="Authorization: Bearer ${THUNDERPHONE_API_KEY}"

run_id="$(curl --fail --silent --show-error -X POST "${base}/run" \
  -H "$auth" -H "Content-Type: application/json" -d '{}' | jq -r '.id')"

deadline=$((SECONDS + 1800))
while (( SECONDS < deadline )); do
  result="$(curl --fail --silent --show-error \
    "${base}/runs/${run_id}" -H "$auth")"
  status="$(jq -r '.status' <<<"$result")"
  if [[ "$status" == "completed" ]]; then
    jq . <<<"$result"
    [[ "$(jq -r '.verdict' <<<"$result")" == "pass" ]]
    exit
  fi
  sleep 10
done

echo "ThunderPhone suite timed out" >&2
exit 1
```

`POST /v1/orgs/{org_id}/suites/{suite_id}/run` renvoie `202` avec l’identifiant
d’exécution. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` renvoie
`status`, `verdict`, `pass_rate`, `critical_failure_count` et la liste de
régressions `regressions` de la référence. Les deux points de terminaison associent l’organisation
de l’URL à celle de la clé API.

## Exécuter une suite selon une planification

Ouvrez l’onglet **Simuler** de l’agent, sélectionnez **Suites de validation des versions**, puis créez ou
modifiez une suite. Activez **Exécuter selon une planification**, choisissez la **Fréquence** et le
**Fuseau horaire**, puis définissez les paramètres **Minute après l’heure**, **Heure locale** ou **Jour**
comme indiqué. Sélectionnez **Enregistrer la suite**. Décochez **Exécuter selon une planification** pour supprimer la
planification du tableau de bord.

### Via l’API

Utilisez PATCH sur la suite pour ajouter ou remplacer sa planification. Consultez [Suites (validations
des versions)](/api-reference/test-scenarios#suites-release-gates) pour obtenir l’objet
suite complet et les points de terminaison.

```bash
curl -X PATCH https://api.thunderphone.com/v1/suites/{suite_id} \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": {
      "enabled": true,
      "frequency": "daily",
      "timezone": "America/Chicago",
      "hour": 6,
      "minute": 30
    }
  }'
```

`frequency` peut être `hourly`, `daily` ou `weekly`. Utilisez un fuseau horaire IANA.
Les planifications horaires utilisent `minute` ; les planifications quotidiennes utilisent `hour` et `minute` ;
les planifications hebdomadaires utilisent également `weekday`, où lundi correspond à `0` et dimanche à `6`.
La réponse de la suite inclut `next_run_at` et `last_run_at`.

Les heures suivent les changements d’heure saisonniers du fuseau horaire sélectionné. Les exécutions planifiées
apparaissent dans l’historique des exécutions de la suite et utilisent son agent, ses scénarios,
ses critères et sa référence acceptée actuels. Chaque appel de test généré émet
`test-call.completed` ; il n’existe pas de webhook de fin au niveau de la suite. Les appels planifiés
sont facturés au même tarif de simulation que les exécutions manuelles de suite et enregistrent
`trigger: "schedule"` sur l’exécution de la suite.

Pour suspendre une planification sans modifier ses horaires, utilisez PATCH sur l’objet de planification existant complet
avec `"enabled": false`. `frequency` est obligatoire ; les champs de fuseau horaire et d’heure omis sont réinitialisés
à leurs valeurs par défaut, incluez donc les valeurs existantes. Envoyez `"schedule": null` pour supprimer la planification.

## Modèles

### Corpus de régression par prompt

Maintenez un fichier JSON de tuples `{name, scenario_prompt, expected_outcome}`. À chaque modification du prompt, exécutez l’ensemble complet par lot ; comparez les transcriptions et les évaluations avec l’exécution précédente.

### Test de validation par version

Un lot unique de cinq scénarios de parcours nominal à exécuter après chaque déploiement. Sensible à la latence, conservez donc `stagger_seconds: 0`.

### Évaluation comparative de la latence

Exécutez des scénarios identiques sur différents niveaux de produit (`spark`, `bolt`, `storm-base`). Comparez les scores `call.graded` et les valeurs `duration_seconds` de chaque journal d’appel obtenu.

---

## Étapes suivantes

<CardGroup cols={2}>
  <Card title="Référence des appels de test" icon="flask" href="/api-reference/test-calls">
    Chaque paramètre de requête, code d’état et format de lot.
  </Card>
  <Card title="Évaluation par IA" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Évaluez automatiquement chaque exécution de test pour suivre la qualité dans le temps.
  </Card>
  <Card title="Signalements de problèmes" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Signalez des tests spécifiques pour une révision humaine.
  </Card>
  <Card title="Webhook test-call.completed" icon="bolt" href="/fr/webhooks/events">
    Envoyez les résultats vers votre CI / Slack / PagerDuty.
  </Card>
</CardGroup>
