---
title: "Run a test: score a captured transcript (offline) or run a live synthetic call"
method: POST
path: "/api/tests/run"
tags: ["Testing"]
---

# Run a test: score a captured transcript (offline) or run a live synthetic call

`POST /api/tests/run`

## Request

- Base URL: `https://api.wordis-bond.com`
- URL: `https://api.wordis-bond.com/api/tests/run`
- Auth: HTTP bearer

Three modes, selected by the body:

• **Saved suite** — send only `{ "suiteId": "…" }`. The suite runs as saved: its target, its language, and every scenario (each with its own persona, expected lines and barge-in), one run per scenario, at most 25 scenarios per request. A suite the account does not own returns `404 SUITE_NOT_FOUND`. This is the body to use from CI.

• **Offline scoring** — supply `transcript` (or `turns`) plus a `scenarioGoal`; the judge scores it synchronously and the completed run is returned. Works on every plan; not metered against call minutes.

• **Live synthetic call** — supply `targetAgent` and `goal`. For the hosted demo target (`{transport:"direct", peerId:"wb-demo-dental"}`) the run completes synchronously. For a `direct` (SIP/WebRTC) target the response returns a tokenized `mediaWebSocketUrl` per run for your agent-side harness to dial. For a `sip` target the SIP URI goes in `sipUri` (or in `peerId` as a `sip:` URI). For a `pstn` target a real carrier call is originated (pro+ plans only — starter returns 402).

**Response shape (every live mode).** `data` is the FIRST run the request created — so `data.id`, `data.status` and `data.passed` are always present — and `data.runs` lists every run the request created (one per scenario for a saved suite, `concurrency` for an ad-hoc run). A run that is not yet terminal is `queued`/`running`: poll `GET /api/tests/{id}` for each id in `data.runs` until its status is `completed` or `failed`, and gate on `passed`.

**PSTN destinations must be verified.** A `pstn` run is only placed to a number the account has proven it controls (or a Word Is Bond DID). An unproven destination returns `403 NUMBER_NOT_VERIFIED` and no call is placed. Prove control once with `POST /api/numbers/verify/start` → `POST /api/numbers/verify/confirm`.

## Request body

- union
  - ScoreTranscriptRequest: Score a captured transcript with the judge. Provide `transcript` OR `turns`.
    - `transcript` string
    - `turns` object[]: Per-turn capture; formatted into a transcript when `transcript` is omitted.
      - `role` 'agent' | 'caller'
      - `text` string
    - `scenarioGoal` string: What the conversation was meant to accomplish.
    - `goal` string: Alias for scenarioGoal.
    - `assertions` string[]
    - `suiteId` string, uuid, nullable
    - `language` string
    - `transport` 'pstn' | 'webrtc'
  - SuiteRunRequest: Run one of your saved suites exactly as saved — every scenario, against the suite target. Send ONLY `suiteId` (plus optional `language` / `record`); adding a `targetAgent` or `goal` makes it an ad-hoc run linked to the suite instead.
    - `suiteId` string, uuid, required
    - `language` string: Override the suite language for this run.
    - `record` boolean
    - `recordTargetId` string, uuid
  - LiveRunRequest: Drive a live synthetic caller against a target agent you run.
    - `targetAgent` TargetAgent, required: The voice agent under test (a system YOU control). `direct` = SIP/WebRTC (near-zero cost, all plans); `pstn` = a real carrier call (pro+). The hosted demo target is `{transport:"direct", peerId:"wb-demo-dental"}`.
      - `transport` 'pstn' | 'webrtc' | 'direct' | 'sip', required
      - `toNumber` string: E.164 number to dial (required for a pstn target).
      - `peerId` string: Hosted-agent id (e.g. "wb-demo-dental"), a direct peer label, or — for a `sip` target — the SIP URI.
      - `sipUri` string: For a `sip` target: the agent SIP URI (`sip:` / `sips:`).
    - `goal` string: What the synthetic caller is trying to accomplish.
    - `persona` object
      - `name` string
      - `description` string, required
    - `suiteId` string, uuid, nullable
    - `transport` 'pstn' | 'webrtc'
    - `language` string
    - `concurrency` integer
    - `expected` string[]
    - `bargeIn` boolean
    - `record` boolean: Opt this run into BYOS recording to your own storage (default off). Requires the byosRecording capability (pro/enterprise) and an enabled recording target. The customer-owned pointer comes back in the run’s recording_url and the report.
    - `recordTargetId` string, uuid: Record to THIS target (else the most-recent enabled one).

## Response `201`

Offline → the completed run in `data`. Every live mode → `data` is the first run created (`id`, `status`, `passed`, …) plus `runs` (every run the request created; a direct run carries `mediaWebSocketUrl`), `suite` for a saved-suite run, and `concurrency`/`transport` for ad-hoc runs.

- object
  - `data` union, required
    - TestRun
      - `id` string, uuid, required
      - `accountId` string, uuid
      - `suiteId` string, uuid, nullable
      - `status` 'queued' | 'running' | 'completed' | 'failed', required
      - `transport` string
      - `language` string
      - `persona` object, nullable
      - `targetAgent` TargetAgent: The voice agent under test (a system YOU control). `direct` = SIP/WebRTC (near-zero cost, all plans); `pstn` = a real carrier call (pro+). The hosted demo target is `{transport:"direct", peerId:"wb-demo-dental"}`.
        - `transport` 'pstn' | 'webrtc' | 'direct' | 'sip', required
        - `toNumber` string: E.164 number to dial (required for a pstn target).
        - `peerId` string: Hosted-agent id (e.g. "wb-demo-dental"), a direct peer label, or — for a `sip` target — the SIP URI.
        - `sipUri` string: For a `sip` target: the agent SIP URI (`sip:` / `sips:`).
      - `score` integer, nullable
      - `passed` boolean, nullable
      - `scorecard` Scorecard: The judged result. `score` is the 0–100 overall; `layers` carry per-dimension detail.
        - `score` number, required
        - `passed` boolean, required
        - `summary` string
        - `sentiment` number
        - `taskCompletion` number
        - `layers` object[]
          - `name` string
          - `score` number
          - `passed` boolean
          - `rationale` string
          - `assertions` object[]
      - `metrics` RunMetrics
        - `latencyMs` object
          - `p50` number
          - `p95` number
          - `max` number
        - `wer` number, nullable: Script-adherence error across pinned scenario wording, or null if nothing was pinned. This is not transcription word-error rate unless a caller supplies an STT reference transcript.
        - `bargeInCount` integer
        - `turnCount` integer
        - `taskCompletion` number
        - `sentiment` number
      - `transcript` string, nullable
      - `recordingUrl` string, nullable: BYOS recording pointer — a URL into YOUR OWN storage when the run recorded (never wordis-bond storage). Null unless the run opted in with `record: true`. See metrics.recording for the tee state (stored/truncated/failed).
      - `mediaWebSocketUrl` string: Only on a live `direct` run — the tokenized WS your agent-side harness dials.
      - `startedAt` string, date-time, nullable
      - `endedAt` string, date-time, nullable
      - `createdAt` string, date-time
    - object
      - `id` string, uuid, required
      - `accountId` string, uuid
      - `suiteId` string, uuid, nullable
      - `status` 'queued' | 'running' | 'completed' | 'failed', required
      - `transport` string
      - `language` string
      - `persona` object, nullable
      - `targetAgent` TargetAgent: The voice agent under test (a system YOU control). `direct` = SIP/WebRTC (near-zero cost, all plans); `pstn` = a real carrier call (pro+). The hosted demo target is `{transport:"direct", peerId:"wb-demo-dental"}`.
        - `transport` 'pstn' | 'webrtc' | 'direct' | 'sip', required
        - `toNumber` string: E.164 number to dial (required for a pstn target).
        - `peerId` string: Hosted-agent id (e.g. "wb-demo-dental"), a direct peer label, or — for a `sip` target — the SIP URI.
        - `sipUri` string: For a `sip` target: the agent SIP URI (`sip:` / `sips:`).
      - `score` integer, nullable
      - `passed` boolean, nullable
      - `scorecard` Scorecard: The judged result. `score` is the 0–100 overall; `layers` carry per-dimension detail.
        - `score` number, required
        - `passed` boolean, required
        - `summary` string
        - `sentiment` number
        - `taskCompletion` number
        - `layers` object[]
          - `name` string
          - `score` number
          - `passed` boolean
          - `rationale` string
          - `assertions` object[]
      - `metrics` RunMetrics
        - `latencyMs` object
          - `p50` number
          - `p95` number
          - `max` number
        - `wer` number, nullable: Script-adherence error across pinned scenario wording, or null if nothing was pinned. This is not transcription word-error rate unless a caller supplies an STT reference transcript.
        - `bargeInCount` integer
        - `turnCount` integer
        - `taskCompletion` number
        - `sentiment` number
      - `transcript` string, nullable
      - `recordingUrl` string, nullable: BYOS recording pointer — a URL into YOUR OWN storage when the run recorded (never wordis-bond storage). Null unless the run opted in with `record: true`. See metrics.recording for the tee state (stored/truncated/failed).
      - `mediaWebSocketUrl` string: Only on a live `direct` run — the tokenized WS your agent-side harness dials.
      - `startedAt` string, date-time, nullable
      - `endedAt` string, date-time, nullable
      - `createdAt` string, date-time
      - `runs` TestRun[], required
        - `id` string, uuid, required
        - `accountId` string, uuid
        - `suiteId` string, uuid, nullable
        - `status` 'queued' | 'running' | 'completed' | 'failed', required
        - `transport` string
        - `language` string
        - `persona` object, nullable
        - `targetAgent` TargetAgent: The voice agent under test (a system YOU control). `direct` = SIP/WebRTC (near-zero cost, all plans); `pstn` = a real carrier call (pro+). The hosted demo target is `{transport:"direct", peerId:"wb-demo-dental"}`.
          - `transport` 'pstn' | 'webrtc' | 'direct' | 'sip', required
          - `toNumber` string: E.164 number to dial (required for a pstn target).
          - `peerId` string: Hosted-agent id (e.g. "wb-demo-dental"), a direct peer label, or — for a `sip` target — the SIP URI.
          - `sipUri` string: For a `sip` target: the agent SIP URI (`sip:` / `sips:`).
        - `score` integer, nullable
        - `passed` boolean, nullable
        - `scorecard` Scorecard: The judged result. `score` is the 0–100 overall; `layers` carry per-dimension detail.
          - `score` number, required
          - `passed` boolean, required
          - `summary` string
          - `sentiment` number
          - `taskCompletion` number
          - `layers` object[]
            - `name` string
            - `score` number
            - `passed` boolean
            - `rationale` string
            - `assertions` object[]
              - …
        - `metrics` RunMetrics
          - `latencyMs` object
            - `p50` number
            - `p95` number
            - `max` number
          - `wer` number, nullable: Script-adherence error across pinned scenario wording, or null if nothing was pinned. This is not transcription word-error rate unless a caller supplies an STT reference transcript.
          - `bargeInCount` integer
          - `turnCount` integer
          - `taskCompletion` number
          - `sentiment` number
        - `transcript` string, nullable
        - `recordingUrl` string, nullable: BYOS recording pointer — a URL into YOUR OWN storage when the run recorded (never wordis-bond storage). Null unless the run opted in with `record: true`. See metrics.recording for the tee state (stored/truncated/failed).
        - `mediaWebSocketUrl` string: Only on a live `direct` run — the tokenized WS your agent-side harness dials.
        - `startedAt` string, date-time, nullable
        - `endedAt` string, date-time, nullable
        - `createdAt` string, date-time
      - `suite` object: Present on a saved-suite run.
        - `id` string, uuid
        - `name` string
        - `scenarios` integer
      - `concurrency` integer
  - `error` union, required
    - object
    - string

## Other responses

- `401`: Missing, invalid, or revoked credentials.
- `402`: The plan does not permit this action, or the monthly quota is spent with no overage (e.g. a starter plan attempting a PSTN run). Body carries an upgrade hint; see GET /api/billing/plans.
- `403`: `NUMBER_NOT_VERIFIED` — a PSTN test call was requested to a number this account has not proven it controls. No call was placed and nothing was charged. Word Is Bond only tests systems you control. The error body carries a `hint` pointing at POST /api/numbers/verify/start.
- `422`: The request body failed validation.
- `429`: Too many requests, or a concurrency/spend ceiling was hit (e.g. CONCURRENCY_LIMIT: the plan's simultaneous-call allowance is in use). Retry later.
- `503`: A dependency (e.g. the carrier for a PSTN run) is not configured or is unavailable.

---

[API](https://skmtc.dev/wordis-bond/apis/word-is-bond-voice-agent-testing-api.md) · [All operations](https://skmtc.dev/wordis-bond/apis/word-is-bond-voice-agent-testing-api/llms.txt) · [OpenAPI document](https://skmtc.dev/wordis-bond/apis/word-is-bond-voice-agent-testing-api/revisions/66c2d5480d84?raw)
