Skip to content
VaakyoDocs
Navigation
Open console →

Agents

Analytics tab

The Analytics tab turns on post-call analysis: a short summary of each call and typed fields pulled from its transcript, saved on the call, included in exports and sent in the call.completed webhook.

Fields

All fields live under analytics in the agent object.

FieldTypeDefaultWhat it does
summarizebooleanfalseWrites a two-to-four sentence summary in English: who called, what they wanted and how it ended. Saved in the call’s summary.
extractionslist of extraction fields[]Typed values to pull out of every call, saved in the call’s extracted. Up to 50.
extraction_promptstring""The older, free-form way: plain-language instructions; the model returns JSON as it sees fit. Prefer extractions.
{
  "analytics": {
    "summarize": true,
    "extractions": [
      {
        "key": "lead_status",
        "label": "Lead status",
        "type": "choice",
        "description": "How ready the caller is to buy or book",
        "choices": [
          {"value": "hot", "when": "wants to buy, book or start now"},
          {"value": "warm", "when": "interested, but not now"},
          {"value": "cold", "when": "not interested"}
        ]
      },
      {"key": "budget_inr", "label": "Budget", "type": "number", "description": "The budget the caller mentioned, in rupees"},
      {"key": "appointment_date", "label": "Date", "type": "date", "description": "The date of the booked appointment"},
      {"key": "wants_callback", "label": "Callback", "type": "boolean", "description": "Whether the caller asked to be called back"}
    ]
  }
}

Extraction fields

Each field is one value you want from every call.

PropertyTypeRequiredWhat it is
keystringyesThe key in extracted: lowercase letters, digits and _, starting with a letter, up to 40 characters. Unique within the agent.
labelstringnoA readable name for the console and exports.
typestringno (default text)text, number, boolean, choice, date or list.
descriptionstringnoWhat to extract and how, in plain language. This is what the model reads, so be specific.
choiceslistfor choiceAt least two {value, when} pairs. value is what’s saved; when tells the model when to pick it.

What each type returns:

TypeReturnsExample
texta string"Rohan Mehta"
numbera number ("4,000" becomes 4000)4000
booleantrue or falsetrue
choiceexactly one of the values"hot"
dateYYYY-MM-DD; “tomorrow” or “next Friday” are resolved against the call’s date"2026-10-02"
lista list of strings["full body checkup", "dental cleaning"]

Anything the call didn’t cover is null. Vaakyo never invents a value: the model is told to use null rather than guess, and every answer is checked again against its type (a number that isn’t one, a choice that isn’t in the list, or a malformed date all become null).

Why fields instead of a prompt

All fields are filled in one model call whose answer must match a JSON schema built from them. So:

  • every call of an agent has the same keys and types, ready for spreadsheets, CRMs and filters;
  • adding a field doesn’t add a model call or more latency;
  • choice fields give you clean categories (hot/warm/cold) instead of free text to normalise later.

Templates

The console’s Add from template menu adds ready-made sets of fields that you can then edit: lead qualification (status, budget, timeline, decision maker), appointment (name, booked, date, time, service), call outcome (outcome, sentiment, callback time) and handover to a person (needs a person, reason).

Testing

In the console, the Test card runs the summary and fields on screen, saved or not, on one of the agent’s recent calls or on a transcript you paste. Nothing is saved.

Over the API:

curl -X POST https://api.vaakyo.com/api/v1/agents/$AGENT_ID/analytics/test \
  -H "X-API-Key: $VAAKYO_API_KEY" -H "Content-Type: application/json" \
  -d '{"call_id": "'$CALL_ID'"}'
{
  "summary": "Rohan Mehta called to book a full body checkup for the next day at 5 PM.",
  "extracted": {"lead_status": "hot", "budget_inr": 4000, "appointment_date": "2026-10-02", "wants_callback": false},
  "errors": [],
  "latency_ms": 1840,
  "tokens": {"input": 612, "output": 48}
}

Send transcript instead of call_id to test on any text, and analytics to try settings you haven’t saved.

When it runs

Analytics runs once, right after the call ends and is saved:

  1. the call ends, is charged and gets its final status (call.ended is sent);
  2. the summary, the fields and any free-form extraction run;
  3. the results are saved on the call;
  4. call.completed is sent with the full call record, including summary and extracted.

So if you wait for call.completed, the results are already in it. If you poll GET /api/v1/calls/{id}, summary and extracted may still be empty for a few seconds after the status turns final.

Analytics is skipped when the transcript has no caller or agent turns. It uses the agent’s llm.model with temperature 0. Its tokens are not counted in the call’s usage. If it fails, extracted stays as it was and the call is otherwise unaffected.

Re-running on past calls

Changed the fields? Run the agent’s current analytics on a finished call again and save the result. In the console, open the call and choose Re-run analytics. Over the API:

curl -X POST https://api.vaakyo.com/api/v1/calls/$CALL_ID/analyze -H "X-API-Key: $VAAKYO_API_KEY"

The response is the updated call. Webhooks are not sent again.

Reading the results

From the API:

curl https://api.vaakyo.com/api/v1/calls/$CALL_ID -H "X-API-Key: $VAAKYO_API_KEY"
{
  "id": "00b1d622a8f04f4f8f3a3c2d9e5b7a11",
  "status": "completed",
  "summary": "Rohan Mehta called City Clinic to book a follow-up visit on 2 October at 12:00.",
  "extracted": {"lead_status": "hot", "budget_inr": 4000, "appointment_date": "2026-10-02", "wants_callback": false},
  "...": "..."
}

From a webhook: data.call.summary and data.call.extracted in the call.completed event. See Webhook events.

In bulk: the calls CSV export has a summary column and one extracted.<key> column per field. See Exporting calls.

Esc