Create Disposition Test Run
curl --request POST \
--url https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"target": "<string>",
"executionSla": "<string>",
"population": {},
"replayRunId": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs"
payload = {
"target": "<string>",
"executionSla": "<string>",
"population": {},
"replayRunId": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
target: '<string>',
executionSla: '<string>',
population: {},
replayRunId: '<string>'
})
};
fetch('https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'target' => '<string>',
'executionSla' => '<string>',
'population' => [
],
'replayRunId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs"
payload := strings.NewReader("{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "08435e5a-e5b8-4e21-8236-85fbe3149fbf",
"dispositionId": "19c27589-b319-411a-a4b5-17bb55ff68f8",
"target": "draft",
"configurationSource": "draft",
"executionSla": "realtime",
"replaySourceRunId": null,
"definition": {
"name": "Appointment outcome",
"description": "Did the caller book an appointment?",
"timing": "immediate",
"values": [
{
"id": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544",
"key": "booked",
"label": "Appointment booked",
"schema": { "kind": "boolean" },
"source": {
"kind": "variable_extraction",
"variableKey": "appointment_booked",
"execution": { "reasoningEffort": "auto" }
}
}
],
"transformation": {
"version": 1,
"root": { "kind": "value", "valueId": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544" }
},
"postCallWebhook": { "mode": "emit_followup" }
},
"population": { "environment": "production", "requestedSize": 25 },
"status": "queued",
"requestedSize": 25,
"resolvedSize": 0,
"completedSize": 0,
"failedSize": 0,
"evalRunId": null,
"mode": "recent",
"inputSetHash": null,
"definitionHash": "1754d979043d46cca6e46a034a39b234c3299a5a4200241e955bdc18bc9394e4",
"draftRevision": 4,
"dispositionVersionId": null,
"summary": {
"caseCount": 0,
"failedCaseCount": 0,
"producedValueCount": 0,
"totalValueCount": 0
},
"error": null,
"createdAt": "2026-09-10T19:12:44.902Z",
"startedAt": null,
"completedAt": null
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "Invalid request body",
"ext": "{\"errors\":[\"/population/requestedSize: Expected integer to be less or equal to 250\"]}"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This organization already has 3 disposition test runs queued or running — wait for one to finish before starting another"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This disposition has never been published — target the draft instead"
}
]
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "This agent has no completed calls to sample — place a call first, or test the draft after traffic arrives"
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many disposition test runs started for this organization — please wait before starting another."
}
]
}
{
"data": null,
"errors": [
{
"error": "SERVICE_UNAVAILABLE",
"message": "Disposition test run could not be started; retry the request"
}
]
}
Test Runs
Create Disposition Test Run
Run a disposition against completed production calls.
POST
/
v2
/
agents
/
{agent_id}
/
dispositions
/
{disposition_id}
/
runs
Create Disposition Test Run
curl --request POST \
--url https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs \
--header 'Content-Type: application/json' \
--header 'authorization: <authorization>' \
--data '
{
"target": "<string>",
"executionSla": "<string>",
"population": {},
"replayRunId": "<string>"
}
'import requests
url = "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs"
payload = {
"target": "<string>",
"executionSla": "<string>",
"population": {},
"replayRunId": "<string>"
}
headers = {
"authorization": "<authorization>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {authorization: '<authorization>', 'Content-Type': 'application/json'},
body: JSON.stringify({
target: '<string>',
executionSla: '<string>',
population: {},
replayRunId: '<string>'
})
};
fetch('https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'target' => '<string>',
'executionSla' => '<string>',
'population' => [
],
'replayRunId' => '<string>'
]),
CURLOPT_HTTPHEADER => [
"Content-Type: application/json",
"authorization: <authorization>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs"
payload := strings.NewReader("{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("authorization", "<authorization>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs")
.header("authorization", "<authorization>")
.header("Content-Type", "application/json")
.body("{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.bland.ai/v2/agents/{agent_id}/dispositions/{disposition_id}/runs")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["authorization"] = '<authorization>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"target\": \"<string>\",\n \"executionSla\": \"<string>\",\n \"population\": {},\n \"replayRunId\": \"<string>\"\n}"
response = http.request(request)
puts response.read_body{
"data": {
"id": "08435e5a-e5b8-4e21-8236-85fbe3149fbf",
"dispositionId": "19c27589-b319-411a-a4b5-17bb55ff68f8",
"target": "draft",
"configurationSource": "draft",
"executionSla": "realtime",
"replaySourceRunId": null,
"definition": {
"name": "Appointment outcome",
"description": "Did the caller book an appointment?",
"timing": "immediate",
"values": [
{
"id": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544",
"key": "booked",
"label": "Appointment booked",
"schema": { "kind": "boolean" },
"source": {
"kind": "variable_extraction",
"variableKey": "appointment_booked",
"execution": { "reasoningEffort": "auto" }
}
}
],
"transformation": {
"version": 1,
"root": { "kind": "value", "valueId": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544" }
},
"postCallWebhook": { "mode": "emit_followup" }
},
"population": { "environment": "production", "requestedSize": 25 },
"status": "queued",
"requestedSize": 25,
"resolvedSize": 0,
"completedSize": 0,
"failedSize": 0,
"evalRunId": null,
"mode": "recent",
"inputSetHash": null,
"definitionHash": "1754d979043d46cca6e46a034a39b234c3299a5a4200241e955bdc18bc9394e4",
"draftRevision": 4,
"dispositionVersionId": null,
"summary": {
"caseCount": 0,
"failedCaseCount": 0,
"producedValueCount": 0,
"totalValueCount": 0
},
"error": null,
"createdAt": "2026-09-10T19:12:44.902Z",
"startedAt": null,
"completedAt": null
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "Invalid request body",
"ext": "{\"errors\":[\"/population/requestedSize: Expected integer to be less or equal to 250\"]}"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This organization already has 3 disposition test runs queued or running — wait for one to finish before starting another"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This disposition has never been published — target the draft instead"
}
]
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "This agent has no completed calls to sample — place a call first, or test the draft after traffic arrives"
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many disposition test runs started for this organization — please wait before starting another."
}
]
}
{
"data": null,
"errors": [
{
"error": "SERVICE_UNAVAILABLE",
"message": "Disposition test run could not be started; retry the request"
}
]
}
Overview
Dispositions are enabled per organization. If your organization does not have access, these endpoints return
404.queued or running at once.
Requires an admin, owner, operator, or prompter role.
Headers
string
required
Your API key for authentication.
Path Parameters
string
required
The agent’s unique identifier. Must be a UUID; otherwise returns
400 with the message agentId must be a valid UUID. Returns 404 Agent not found if the agent is not in your organization.string
required
The disposition’s unique identifier. Must be a UUID; otherwise returns
400 with the message dispositionId must be a valid UUID. Returns 404 Disposition not found if it does not belong to this agent.Body Parameters
The body takes one of two shapes: a current-definition run (target plus population, with optional executionSla) or a replay (replayRunId alone). Mixing fields from both shapes, or adding unknown fields, returns 400 BAD_REQUEST with the message Invalid request body.
string
Required for a current-definition run.
draft runs the live draft, which is first validated as strictly as publish (every value must pin a runnable judge or extractor version, though an editable pin is allowed); failures return 400 with the message Definition failed validation. published runs the current published version and returns 409 CONFLICT if the disposition has never been published. A definition with no values returns 400 with the message Add at least one value before running a test.string
realtime or queued. Defaults from the definition’s timing: immediate gives realtime, within_24h gives queued.object
Required for a current-definition run. Which completed, non-simulated production calls of this agent to run against. Two shapes:Recent sample:
{ "environment": "production", "requestedSize": 25 }, optionally with "mode": "recent". requestedSize is an integer from 1 to 250; the newest eligible calls are sampled. Returns 400 if the agent has no eligible completed calls to sample.Explicit calls: { "mode": "calls", "callIds": ["..."] }, optionally with "environment": "production". callIds is 1 to 250 unique call UUIDs. Every call must belong to this agent and be completed with non-zero duration, otherwise 400 with the message One or more selected calls are not eligible completed production calls for this agent. Calls that cannot enter dispositions for compliance reasons return 400 listing the offending ids.string
Alternative body:
{ "replayRunId": "..." } with no other fields. Re-executes the frozen call cohort and definition snapshot of a finished run (complete, partial, failed, or cancelled) on this disposition, with configurationSource: "frozen_run". Returns 404 with the message Replay source test run not found if no such run exists, 400 with the message Replay source test run has no frozen call cohort if it recorded no calls, and 409 with the message Replay source frozen inputs are incomplete; run a new test instead if any call lacks a frozen input snapshot.Response
Returns201 on success with the run in queued status. Returns 503 SERVICE_UNAVAILABLE if the run could not be handed to the execution queue; the run is recorded as failed and the request can be retried.
object
The new test run. Same shape as the entries of List Disposition Test Runs; the fields that matter on creation are listed here.
Show test run object
Show test run object
string
Unique identifier for the test run. Pass it as
{run_id} to the run endpoints.string
The disposition this run belongs to.
string
draft or published.string
draft, published, or frozen_run for a replay.string
realtime or queued, as requested or defaulted.string | null
The
replayRunId you passed, or null.object
The frozen definition snapshot this run executes. For a
draft target, structured_extraction sources are frozen the same way publish freezes them.object
{ "environment": "production", "requestedSize" }.string
Always
queued on creation. Later running, then complete, partial, failed, or cancelled.number
The sample size requested, or the number of call ids supplied.
number
Always
0 on creation.number
Always
0 on creation.number
Always
0 on creation.null
Always
null.string
recent or calls.null
Always
null.string
SHA-256 hex digest of the definition snapshot.
number | null
The draft revision executed, or
null for a published target.string | null
The published version executed, or
null for a draft target.object
All zeros on creation:
caseCount, failedCaseCount, producedValueCount, totalValueCount. correctionCount is omitted here and appears on later reads.null
Always
null on creation.string
ISO 8601 timestamp of creation.
null
Always
null on creation.null
Always
null on creation.null | array
null on success, or a list of error objects if the request failed.{
"data": {
"id": "08435e5a-e5b8-4e21-8236-85fbe3149fbf",
"dispositionId": "19c27589-b319-411a-a4b5-17bb55ff68f8",
"target": "draft",
"configurationSource": "draft",
"executionSla": "realtime",
"replaySourceRunId": null,
"definition": {
"name": "Appointment outcome",
"description": "Did the caller book an appointment?",
"timing": "immediate",
"values": [
{
"id": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544",
"key": "booked",
"label": "Appointment booked",
"schema": { "kind": "boolean" },
"source": {
"kind": "variable_extraction",
"variableKey": "appointment_booked",
"execution": { "reasoningEffort": "auto" }
}
}
],
"transformation": {
"version": 1,
"root": { "kind": "value", "valueId": "45ef74d6-b7ba-4ef2-b0a7-6cc4314da544" }
},
"postCallWebhook": { "mode": "emit_followup" }
},
"population": { "environment": "production", "requestedSize": 25 },
"status": "queued",
"requestedSize": 25,
"resolvedSize": 0,
"completedSize": 0,
"failedSize": 0,
"evalRunId": null,
"mode": "recent",
"inputSetHash": null,
"definitionHash": "1754d979043d46cca6e46a034a39b234c3299a5a4200241e955bdc18bc9394e4",
"draftRevision": 4,
"dispositionVersionId": null,
"summary": {
"caseCount": 0,
"failedCaseCount": 0,
"producedValueCount": 0,
"totalValueCount": 0
},
"error": null,
"createdAt": "2026-09-10T19:12:44.902Z",
"startedAt": null,
"completedAt": null
},
"errors": null
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "Invalid request body",
"ext": "{\"errors\":[\"/population/requestedSize: Expected integer to be less or equal to 250\"]}"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This organization already has 3 disposition test runs queued or running — wait for one to finish before starting another"
}
]
}
{
"data": null,
"errors": [
{
"error": "CONFLICT",
"message": "This disposition has never been published — target the draft instead"
}
]
}
{
"data": null,
"errors": [
{
"error": "BAD_REQUEST",
"message": "This agent has no completed calls to sample — place a call first, or test the draft after traffic arrives"
}
]
}
{
"data": null,
"errors": [
{
"error": "TOO_MANY_REQUESTS",
"message": "Too many disposition test runs started for this organization — please wait before starting another."
}
]
}
{
"data": null,
"errors": [
{
"error": "SERVICE_UNAVAILABLE",
"message": "Disposition test run could not be started; retry the request"
}
]
}
Docs for agents: llms.txt
Was this page helpful?