Skip to main content

What are Dispositions?

Dispositions are LLM-powered post-call classifiers. After every call, each disposition defined for your agent runs against the transcript and produces a structured result — either a Free Text response or a Pre-defined value selected from options you configure. Use dispositions to automatically tag call outcomes, score leads, detect escalation needs, verify compliance, and more — without manually reading every transcript.
Dispositions are similar to Extractions but designed for classification rather than data capture. An extraction answers “what did the customer say?”; a disposition answers “what was the outcome?”.

Key Concepts

Categories

Dispositions are organized into categories (e.g., “Lead Quality”, “Compliance”, “Call Outcome”). Every disposition belongs to exactly one category. Categories are set per-disposition via the category field (default: "General").

Answer Types

Each disposition must declare one or both answer types:
TypeFieldDescription
Free Textis_subjective: trueLLM generates a free-text response based on the transcript and question prompt
Pre-definedis_objective: trueLLM selects a value from objective_options based on each option’s condition
You can enable both types on a single disposition to get a natural-language explanation alongside a structured label.

Copy-on-Write Updates

When you update a disposition that is shared using a scoped agent_id, Bolna automatically creates a private copy for that agent instead of modifying the original. This ensures changes to one agent’s dispositions don’t affect others. The API signals this with a 201 response (new resource created) rather than the usual 200 (updated in place). See the Update Disposition reference for full details.

Creating a Disposition

Single Disposition

POST /dispositions/

{
  "agent_id": "agt_abc123",
  "name": "Call Outcome",
  "question": "What was the final outcome of this call? Did the customer agree to a follow-up?",
  "category": "Lead Quality",
  "is_subjective": true,
  "is_objective": true,
  "model": "gpt-4.1-mini",
  "objective_options": [
    {
      "value": "interested",
      "condition": "Customer expressed genuine interest and agreed to a next step"
    },
    {
      "value": "not_interested",
      "condition": "Customer declined or was unresponsive to all proposals"
    },
    {
      "value": "follow_up",
      "condition": "Customer asked to be contacted again at a later time"
    }
  ]
}

Bulk Create (for multiple dispositions at once)

POST /dispositions/bulk

{
  "agent_id": "agt_abc123",
  "dispositions": [
    {
      "name": "Agent Handover Needed",
      "question": "Did the customer explicitly request to speak with a human agent?",
      "category": "Escalation",
      "is_objective": true,
      "objective_options": [
        { "value": "Yes", "condition": "Customer asked to speak with a human or live agent" },
        { "value": "No", "condition": "Customer did not request a human handover" }
      ]
    },
    {
      "name": "Customer Sentiment",
      "question": "Describe the customer's overall tone and satisfaction level during the call.",
      "category": "Quality",
      "is_subjective": true
    }
  ]
}
Bulk creates are atomic — either all dispositions are created and linked, or none are.

Answer Types in Detail

Free Text

The LLM generates an open-ended response based on the question prompt and the transcript. Best for:
  • Summarizing customer concerns or objections
  • Explaining the reasoning behind an outcome
  • Capturing qualitative context
Example:
{
  "name": "Cancellation Reason",
  "question": "If the customer cancelled or declined, what was their stated reason?",
  "is_subjective": true
}
Result:
"subjective": "Customer mentioned they already signed with a competitor last week and were not open to switching."

Pre-defined Options

The LLM selects a value from your objective_options list. Each option has a value (returned in the result) and a condition (instructions for when to select it). Best for:
  • Yes/No classifications
  • Status labels (hot/warm/cold)
  • Compliance checks
Example:
{
  "name": "Appointment Confirmed",
  "question": "Did the customer agree to schedule an appointment?",
  "is_objective": true,
  "objective_options": [
    { "value": "confirmed", "condition": "Customer agreed to a specific date and time" },
    { "value": "tentative", "condition": "Customer expressed interest but did not commit to a time" },
    { "value": "declined", "condition": "Customer did not agree to any appointment" }
  ]
}
Result:
"objective": "confirmed"

Nested Options

objective_options support recursive nesting via sub_options for hierarchical classifications:
{
  "value": "interested",
  "condition": "Customer showed interest in the product",
  "sub_options": [
    { "value": "high_intent", "condition": "Customer asked about pricing or next steps" },
    { "value": "low_intent", "condition": "Customer was politely interested but non-committal" }
  ]
}

Managing Dispositions

List Dispositions for an Agent

GET /dispositions/?agent_id=agt_abc123
Returns all dispositions linked to the specified agent.

Update a Disposition

PUT /dispositions/{disposition_id}
Include agent_id in the request body to use scoped (copy-on-write) mode:
{
  "agent_id": "agt_abc123",
  "question": "Updated: Did the customer agree to a demo or a follow-up call?",
  "objective_options": [
    { "value": "demo", "condition": "Customer agreed to a product demo" },
    { "value": "follow_up", "condition": "Customer agreed to a follow-up call" },
    { "value": "declined", "condition": "Customer declined both options" }
  ]
}
If the disposition you’re updating is shared with other agents, the API will return 201 instead of 200 — this means a new copy was created and linked to your agent. Your original agent behavior is preserved and isolated from other agents.

Delete a Disposition

DELETE /dispositions/{disposition_id}
You can only delete dispositions you own. Admins can delete any disposition.

Disposition Output Format

After each call, disposition results are stored in the execution record under the dispositions key, organized by category:
{
  "dispositions": {
    "Lead Quality": {
      "Call Outcome": {
        "subjective": "Customer expressed strong interest and asked about enterprise pricing options.",
        "objective": "interested"
      }
    },
    "Escalation": {
      "Agent Handover Needed": {
        "subjective": "",
        "objective": "No"
      }
    },
    "Compliance": {
      "Disclaimer Read": {
        "subjective": null,
        "objective": "Yes"
      }
    }
  }
}

Field Reference

FieldTypeDescription
subjectivestring | nullFree Text LLM response. "" if no relevant information found; null if not configured (is_subjective: false)
objectivestring | nullSelected Pre-defined value. null if objective_options not configured or no condition matched

Accessing Disposition Results

Fetch any execution by ID to see its disposition results:
GET /executions/{execution_id}
The dispositions key is included in the execution response alongside transcript, extracted_data, and other post-call data.
If you’ve configured a post-call webhook, disposition results are included in the same execution payload delivered to your endpoint after every call.See Webhooks for payload details.
Open any call record from the Call History tab to view disposition results alongside the transcript and call summary.

Common Use Cases

Use CaseDispositionType
Lead scoringHot / warm / cold classificationPre-defined
Escalation detectionAgent handover requested?Pre-defined (Yes/No)
Appointment trackingCall confirmed, rescheduled, or declined?Pre-defined
Cancellation analysisWhy did the customer cancel?Free Text
Compliance auditingWas the required disclaimer read?Pre-defined (Yes/No)
Sentiment summaryDescribe the customer’s tone and satisfactionFree Text
Objection captureWhat objections did the customer raise?Free Text

Best Practices

  1. One concern per disposition — Keep each disposition focused on a single question. Split “was the customer satisfied AND did they agree to a follow-up?” into two separate dispositions.
  2. Write clear conditions — Objective option conditions should be mutually exclusive and cover all expected outcomes (including an “unknown” fallback if needed).
  3. Use both types together — Enabling both Free Text (is_subjective) and Pre-defined (is_objective) gives you a structured label for automation plus a human-readable explanation for review.
  4. Use categories to group related dispositions — Group escalation, compliance, and lead quality into their own categories to keep execution results readable.
  5. Scope updates with agent_id — Always pass agent_id when updating dispositions via the API to avoid unintentionally modifying a shared disposition.

Next Steps

Dispositions API

Manage dispositions programmatically

Using Extractions

Capture structured data fields from calls

Webhooks

Receive disposition results in real-time

Executions API

Fetch disposition results from past calls