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

# Uji agen secara end-to-end (API)

> Jalankan skenario yang telah ditentukan melalui agen Anda dengan API test-calls agar regresi terdeteksi sebelum didengar pelanggan.

<Note>
  Lebih memilih dashboard? Kemampuan yang sama tersedia di **Simulations**
  (`/dashboard/simulations`), termasuk pembuatan skenario AI — lihat
  [Simulasikan panggilan](/id/guides/simulate-a-call). Halaman ini membahas
  jalur terprogram.
</Note>

Mengiterasi agen AI berarti mengiterasi Prompt, alatnya,
dan cara agen menangani kasus tepi. **test-calls API** menjalankan panggilan nyata
(bot-ke-bot atau loopback SIP) terhadap agen menggunakan Prompt skenario
yang Anda berikan — setiap eksekusi menghasilkan log panggilan nyata dengan
transkrip, penilaian, dan penagihan, sehingga Anda dapat melihat secara tepat bagaimana agen
berperilaku dan berapa biayanya.

Gunakan untuk:

* Pengujian smoke sebelum deployment setelah setiap pengeditan Prompt
* Rangkaian regresi yang terhubung ke CI (hubungkan webhook `test-call.completed`
  → gagalkan build jika skor menurun)
* Pengujian stres batas konkurensi

## Sekali jalan: satu eksekusi

```bash theme={null}
curl -X POST https://api.thunderphone.com/v1/test-calls \
  -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
  }'
```

Kolom:

| Kolom               | Tipe    | Wajib  | Deskripsi                                                           |
| ------------------- | ------- | ------ | ------------------------------------------------------------------- |
| `target_type`       | string  | ya     | `agent` atau `phone_number`                                         |
| `target_id`         | integer | ya     | ID agen (atau ID nomor telepon)                                     |
| `direction`         | string  | ya     | `outbound` (bot melakukan panggilan) atau `inbound` (bot menjawab)  |
| `scenario_prompt`   | string  | tidak  | Menentukan apa yang dikatakan bot pengujian                         |
| `mode`              | string  | tidak  | `bot` (bot-ke-bot, default) atau `sip` (loopback SIP)               |
| `consent_to_charge` | boolean | **ya** | Harus bernilai `true`. Panggilan pengujian berbiaya 2× tarif normal |
| `target_number`     | string  | tidak  | Penggantian untuk ID penelepon bot (E.164)                          |

Respons berupa [objek eksekusi panggilan pengujian](/api-reference/test-calls#test-call-run-object)
dengan `status="queued"`. Poll hingga `status` menjadi `completed` atau
`failed`; setelah `call_id` ditetapkan, muat transkrip melalui
[`GET /v1/calls/{call_id}/transcript`](/api-reference/calls#get-transcript).

## Batch: skenario paralel

Jalankan N skenario secara bersamaan — berguna untuk rangkaian regresi yang
menguji setiap kasus tepi yang diketahui secara paralel:

```bash theme={null}
curl -X POST https://api.thunderphone.com/v1/test-call-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
  }'
```

Respons memuat daftar `run_ids` berisi ID eksekusi anak. Ambil status
batch:

```bash theme={null}
curl https://api.thunderphone.com/v1/test-call-batches/{batch_id} \
  -H "Authorization: Bearer sk_live_YOUR_API_KEY"
```

`run_count` dibatasi hingga 20; `stagger_seconds` memberi jeda antar pembuatan
eksekusi agar agen tidak menerima beban berlebihan (0–60 dtk).

## Hubungkan ke CI

Buat rangkaian gerbang rilis di halaman **Simulasi**
(`/dashboard/simulations`) — pilih agen, tambahkan skenario secara manual atau
klik **Buat skenario dengan AI** untuk menyusunnya dari
Prompt agen (dengan opsi pemeriksaan kasus tepi), lalu kelompokkan ke dalam rangkaian.
Sebuah rangkaian mengunci skenario dan agennya, beserta tingkat kelulusan minimum dan
opsi aturan tanpa kegagalan kritis. Proses yang lulus menjadi baseline yang diterima;
transisi lulus→gagal berikutnya dikembalikan sebagai regresi.

Gunakan [kunci API organisasi](/api-reference/developer-api-keys) di CI.
Skrip ini memicu rangkaian, melakukan polling hingga penilaian dan perbandingan
selesai, lalu keluar dengan nilai bukan nol kecuali putusannya adalah `pass`:

```bash theme={null}
#!/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` mengembalikan `202` dengan
ID proses. `GET /v1/orgs/{org_id}/suites/{suite_id}/runs/{run_id}` mengembalikan
`status`, `verdict`, `pass_rate`, `critical_failure_count`, dan daftar baseline
`regressions`. Kedua endpoint mengikat organisasi pada URL
ke organisasi milik kunci API.

## Pola

### Korpus regresi per Prompt

Pertahankan file JSON berisi tuple `{name, scenario_prompt, expected_outcome}`.
Pada setiap perubahan Prompt, jalankan seluruh set sebagai batch; bandingkan
transkrip dan nilai dengan proses sebelumnya.

### Uji asap per rilis

Satu batch berisi lima skenario jalur sukses yang Anda jalankan setelah setiap
deploy. Sensitif terhadap latensi, jadi pertahankan `stagger_seconds: 0`.

### Benchmarking latensi

Jalankan skenario yang identik terhadap tingkat produk yang berbeda (`spark`,
`bolt`, `storm-base`). Bandingkan skor `call.graded` dan
`duration_seconds` dari setiap log panggilan yang dihasilkan.

***

## Langkah berikutnya

<CardGroup cols={2}>
  <Card title="Referensi panggilan pengujian" icon="flask" href="/api-reference/test-calls">
    Setiap parameter kueri, kode status, dan bentuk batch.
  </Card>

  <Card title="Penilaian AI" icon="chart-line" href="/api-reference/calls#ai-call-grading">
    Nilai otomatis setiap proses pengujian untuk melacak kualitas dari waktu ke waktu.
  </Card>

  <Card title="Laporan masalah" icon="triangle-exclamation" href="/api-reference/issue-reports">
    Tandai pengujian tertentu untuk ditinjau manusia.
  </Card>

  <Card title="Webhook test-call.completed" icon="bolt" href="/id/webhooks/events">
    Alirkan hasil ke CI / Slack / PagerDuty Anda.
  </Card>
</CardGroup>
