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

# Calls Overview

> Understand how individual calls work in Truedy — statuses, directions, and the call lifecycle

A **call** in Truedy represents a single conversation between one of your AI agents and a person. Every time your agent speaks with someone — whether you initiated the call, someone called in, or they connected through a browser widget — Truedy creates a call object that records everything: the transcript, the recording, timing metadata, and the final outcome.

This guide explains the call data model, the lifecycle a call moves through, and how to retrieve call data via the API.

***

## Call Directions

Truedy supports three call directions, each representing a different way a conversation is initiated.

<Columns>
  <Card title="Outbound" icon="phone-arrow-up-right">
    Your agent places a call to a contact's phone number. Used for proactive outreach, follow-ups, appointment reminders, and campaigns.
  </Card>

  <Card title="Inbound" icon="phone-arrow-down-left">
    A contact dials one of your Truedy phone numbers and the call is routed to the configured agent. Used for support lines, hotlines, and always-on reception.
  </Card>

  <Card title="WebRTC" icon="globe">
    A contact connects through a browser-based widget embedded on your website or app. No phone number required on either side — audio is transmitted over the internet.
  </Card>
</Columns>

***

## The Call Lifecycle

Every call moves through a defined sequence of statuses from creation to completion. Understanding this lifecycle helps you build reliable integrations and interpret webhook payloads correctly.

```
queued → ringing → in-progress → ended
                              ↘ failed
```

<Steps>
  <Step title="queued">
    The call has been created in Truedy's system and is waiting to be dialled. For outbound calls, this is the initial state after you call `POST /calls`. The call will transition out of this state within seconds under normal conditions.
  </Step>

  <Step title="ringing">
    Truedy has initiated the connection and is waiting for the recipient to answer. For inbound and WebRTC calls, this state is brief or may be skipped entirely.
  </Step>

  <Step title="in-progress">
    The call has been answered and the agent is actively speaking with the contact. Transcription and recording begin at this point.
  </Step>

  <Step title="ended">
    The call completed normally. The transcript, recording URL, duration, and outcome are now available on the call object.
  </Step>

  <Step title="failed">
    The call could not be connected or was interrupted before completion. Check the `failure_reason` field for details (e.g. `no-answer`, `busy`, `invalid-number`, `agent-error`).
  </Step>
</Steps>

<Note>
  WebRTC calls skip the `ringing` state entirely and move directly from `queued` to `in-progress` once the browser widget establishes the connection.
</Note>

***

## Call Status Reference

| Status        | Meaning                                       | Terminal? |
| ------------- | --------------------------------------------- | --------- |
| `queued`      | Call created, waiting to be dialled           | No        |
| `ringing`     | Dialling the recipient, awaiting answer       | No        |
| `in-progress` | Active conversation underway                  | No        |
| `ended`       | Call completed successfully                   | Yes       |
| `failed`      | Call could not connect or was interrupted     | Yes       |
| `cancelled`   | Call was cancelled before it could be dialled | Yes       |

<Tip>
  Only `ended`, `failed`, and `cancelled` are terminal statuses. Once a call reaches one of these states, it will never transition again. Use this to know when it is safe to process a call's transcript or recording.
</Tip>

***

## The Call Object

When you retrieve a call from the API, you receive a call object with the following fields:

| Field              | Type    | Description                                                                          |
| ------------------ | ------- | ------------------------------------------------------------------------------------ |
| `id`               | string  | Unique identifier for the call (UUID)                                                |
| `status`           | string  | Current call status (see table above)                                                |
| `direction`        | string  | `outbound`, `inbound`, or `webrtc`                                                   |
| `agent_id`         | string  | The agent that handled this call                                                     |
| `phone_number`     | string  | The E.164 phone number dialled or that called in. `null` for WebRTC calls            |
| `from_number`      | string  | The Truedy number the call was placed from (outbound) or received on (inbound)       |
| `duration_seconds` | integer | Total call duration from answer to hangup. `null` if the call never connected        |
| `transcript`       | array   | Ordered array of `{speaker, text, timestamp}` objects. Available after the call ends |
| `recording_url`    | string  | Signed URL to the call recording audio file. Time-limited — download promptly        |
| `cost_cents`       | integer | The cost of this call in USD cents                                                   |
| `outcome`          | string  | Post-call analysis outcome label (e.g. `interested`, `not-interested`, `voicemail`)  |
| `variables`        | object  | Template variables that were passed when the call was created                        |
| `failure_reason`   | string  | Machine-readable reason the call failed. Present only when `status` is `failed`      |
| `started_at`       | string  | ISO 8601 timestamp when the call moved to `in-progress`                              |
| `ended_at`         | string  | ISO 8601 timestamp when the call reached a terminal status                           |
| `created_at`       | string  | ISO 8601 timestamp when the call object was created                                  |

***

## Example: A Completed Call Object

```json theme={null}
{
  "id": "call_01hx3k9p2qw7v8n4m6j5r0y1tz",
  "status": "ended",
  "direction": "outbound",
  "agent_id": "agent_01hx2a7b3cd4ef5gh6ij7kl8mn",
  "phone_number": "+14155551234",
  "from_number": "+18005559876",
  "duration_seconds": 183,
  "cost_cents": 92,
  "outcome": "interested",
  "variables": {
    "first_name": "Sarah",
    "appointment_date": "April 10th"
  },
  "transcript": [
    {
      "speaker": "agent",
      "text": "Hi Sarah, this is Aria calling from Bright Dental. I'm reaching out about your appointment on April 10th.",
      "timestamp": 1.2
    },
    {
      "speaker": "contact",
      "text": "Oh hi, yes I remember. Is everything still on?",
      "timestamp": 7.4
    },
    {
      "speaker": "agent",
      "text": "Absolutely, everything is confirmed for 2pm. Just wanted to make sure you didn't have any questions.",
      "timestamp": 11.9
    }
  ],
  "recording_url": "https://recordings.truedy.ai/call_01hx3k9p2qw7v8n4m6j5r0y1tz.mp3?token=eyJ...&expires=1712620800",
  "failure_reason": null,
  "started_at": "2024-04-05T14:22:01Z",
  "ended_at": "2024-04-05T14:25:04Z",
  "created_at": "2024-04-05T14:21:58Z"
}
```

***

## Retrieving a Call

Use `GET /calls/{id}` to fetch the current state of any call by its ID.

<CodeGroup>
  ```bash curl theme={null}
  curl https://api.truedy.ai/api/public/v1/calls/call_01hx3k9p2qw7v8n4m6j5r0y1tz \
    -H "Authorization: Bearer YOUR_API_KEY"
  ```

  ```python Python theme={null}
  import requests

  response = requests.get(
      "https://api.truedy.ai/api/public/v1/calls/call_01hx3k9p2qw7v8n4m6j5r0y1tz",
      headers={"Authorization": "Bearer YOUR_API_KEY"},
  )

  call = response.json()
  print(call["status"])         # "ended"
  print(call["duration_seconds"])  # 183
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch(
    "https://api.truedy.ai/api/public/v1/calls/call_01hx3k9p2qw7v8n4m6j5r0y1tz",
    {
      headers: { Authorization: "Bearer YOUR_API_KEY" },
    }
  );

  const call = await response.json();
  console.log(call.status);           // "ended"
  console.log(call.duration_seconds); // 183
  ```
</CodeGroup>

The response is a single call object as shown in the example above.

***

## Polling vs. Webhooks

After creating a call, you have two options for tracking when it completes:

**Polling** — repeatedly call `GET /calls/{id}` until the status reaches a terminal state. Simple to implement but inefficient at scale.

**Webhooks** — register a webhook endpoint and Truedy will push a `call.ended` or `call.analyzed` event to your server the moment the call finishes. This is the recommended approach for production integrations.

<Note>
  For any integration that processes more than a handful of calls per day, webhooks are strongly preferred over polling. See the [Webhooks Overview](/guides/webhooks-overview) guide for setup instructions.
</Note>

***

## Next Steps

<Columns>
  <Card title="Making Outbound Calls" icon="phone-arrow-up-right" href="/guides/making-outbound-calls">
    Place individual outbound calls via the API
  </Card>

  <Card title="Setting Up Inbound Calls" icon="phone-arrow-down-left" href="/guides/setting-up-inbound-calls">
    Route incoming callers to your agents
  </Card>

  <Card title="WebRTC Widget" icon="globe" href="/guides/webrtc-custom-widget">
    Embed a browser-based voice widget
  </Card>

  <Card title="Call Management" icon="list" href="/guides/call-management">
    List, filter, and export call records
  </Card>
</Columns>
