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

# Post-call analysis

> Automatic summary, sentiment, and custom data extraction

After every call, Nixflex runs an analysis pass over the transcript. You get a summary, the caller's sentiment, whether the call succeeded, and any custom fields you've defined — automatically. No setup required for the defaults.

## What you get out of the box

Every call record has these fields populated automatically:

| Field              | Type    | Description                                                    |
| ------------------ | ------- | -------------------------------------------------------------- |
| `call_summary`     | string  | 1–2 sentence summary of what happened                          |
| `caller_sentiment` | enum    | `happy`, `neutral`, or `frustrated`                            |
| `call_successful`  | boolean | Did the caller get what they needed?                           |
| `extracted_data`   | object  | Your custom fields (see below). Empty `{}` if none configured. |

These are the field names on the call record returned by [`GET /v1/calls/:id`](/api-reference/calls/get) and [`GET /v1/calls`](/api-reference/calls/list). In the [webhook payload](/advanced/webhooks) the same data is delivered under flat, renamed keys: `summary`, `sentiment`, `successful`, and `extracted`.

## Custom data extraction

Beyond the defaults, you define exactly which fields to pull from each call. Set `data_extraction_fields` on the agent — an **array** of field definitions:

```json theme={null}
{
  "data_extraction_fields": [
    {
      "type": "text",
      "name": "caller_name",
      "description": "The caller's first name",
      "optional": true
    },
    {
      "type": "boolean",
      "name": "wants_callback",
      "description": "Whether the caller asked for a callback"
    },
    {
      "type": "selector",
      "name": "service_requested",
      "description": "Which service the caller asked about",
      "choices": ["check-up", "cleaning", "whitening"]
    },
    {
      "type": "number",
      "name": "party_size",
      "description": "Number of people for a booking"
    }
  ]
}
```

For each call, the agent reads the transcript and fills in what it can. Missing fields come back as `null` — the agent won't invent data.

### Field types

| Type       | Returns               | Use for                                                                       |
| ---------- | --------------------- | ----------------------------------------------------------------------------- |
| `text`     | string                | Names, emails, free-form values. Optional `format_example` guides the format. |
| `selector` | string from `choices` | Categorising into a fixed set of options. Requires `choices`.                 |
| `boolean`  | `true` / `false`      | Yes/no questions (callback wanted, issue resolved).                           |
| `number`   | number                | Quantities, counts, party sizes.                                              |

### Field properties

| Property         | Required      | Notes                                                                    |
| ---------------- | ------------- | ------------------------------------------------------------------------ |
| `type`           | yes           | One of `text`, `selector`, `boolean`, `number`                           |
| `name`           | yes           | Key used in `extracted_data`. Keep it snake\_case.                       |
| `description`    | yes           | What the agent should look for. Be specific — this drives accuracy.      |
| `optional`       | no            | If `true`, the field stays `null` when not mentioned rather than guessed |
| `choices`        | selector only | The allowed values                                                       |
| `format_example` | text only     | Example of the expected format, e.g. `name@example.com`                  |

The result lands in `extracted_data`:

```json theme={null}
{
  "extracted_data": {
    "caller_name": "Amir",
    "wants_callback": true,
    "service_requested": "check-up",
    "party_size": null
  }
}
```

<Note>
  On the API, your custom fields are keyed under `extracted_data`. In the [webhook payload](/advanced/webhooks) the same fields arrive under `extracted`.
</Note>

## When analysis runs

* **Inbound, outbound, and batch calls** — all directions, always.
* **Calls with real conversation** — if the caller spoke fewer than 2 turns or fewer than 10 words total (hang-ups, voicemail), the AI pass is skipped to save cost. Defaults fall back to a short summary and `call_successful: false`.
* **Asynchronously, after the call ends** — by the time your webhook fires (\~60s later), all fields are populated.

## How extraction works under the hood

Analysis runs in two stages:

1. **Base analysis** — always runs. One AI call returns `call_summary`, `caller_sentiment`, `call_successful`.
2. **Custom extraction** — only runs if the agent has `data_extraction_fields`. A second AI call returns your custom fields.

Both stages use the AI and add roughly **\$0.001** to the call cost. It's included in the per-minute price — no extra charge.

## Configuring in the dashboard

Open your agent's **Post-Call Data Extraction** panel. Add fields with the **+ Add** button — pick a type, give it a name and description, and save. Extracted fields are delivered to your webhook after each call. No code required.

## Reading analysis programmatically

Each call object includes the analysis inline — there's no separate endpoint. See [Get call](/api-reference/calls/get) for the full schema, or receive it via [webhook](/advanced/webhooks).
