Skip to content

Choose what calls find out

Download .md

An insight is the list of things a call should find out, as typed fields: “will they come?” (yes/no), “why not?” (one of a list), “which day suits them?” (text). After each call ends, a model reads the conversation and fills in the answers. They appear in the call’s extracted, under each field’s key. In the dashboard these are called Dialog Insights.

You need: an API key whose owner is an owner or admin of the workspace (to create and change insights; any key reads them). Every field: Insights reference.

  1. Create an insight.
  2. Attach it to a voice campaign or an agent (insight).
  3. Run the campaign; read extracted on each call.
  4. Change the fields between rounds if the answers are not what you need.

An insight attached to nothing runs on no call and costs nothing. Once attached, it runs once on every call that ends, and each run spends credits for one model run.

Terminal window
curl -X POST https://api.omniocto.com/v1/insights \
-H "Authorization: Bearer $OMNI_OCTO_API_KEY" -H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"name": "Appointment check",
"fields": [
{ "key": "will_attend", "type": "boolean",
"description": "true when they confirm they will come; false when they cancel" },
{ "key": "reason", "type": "enum", "enum_values": ["work", "sick", "other"],
"description": "Why they cannot come, if they cannot",
"enum_descriptions": { "work": "a job or shift clashes with the time" } },
{ "key": "preferred_day", "type": "text",
"description": "The day they would rather come, in their words" }
]
}'
{ "id": "di-0000000001", "object": "insight", "uuid": "00000000-0000-4000-8000-000000000041",
"name": "Appointment check", "description": null,
"fields": [
{ "key": "will_attend", "label": "Will attend", "type": "boolean",
"description": "true when they confirm they will come; false when they cancel" },
{ "key": "reason", "label": "Reason", "type": "enum",
"description": "Why they cannot come, if they cannot",
"enum_values": ["work", "sick", "other"],
"enum_descriptions": { "work": "a job or shift clashes with the time" } },
{ "key": "preferred_day", "label": "Preferred day", "type": "text",
"description": "The day they would rather come, in their words" }
],
"field_count": 3, "attached": { "agents": 0, "campaigns": 0 },
"revision": "2026-10-29T10:00:00.123456",
"created_at": "2026-10-29T10:00:00.123Z", "updated_at": "2026-10-29T10:00:00.123Z" }

The fields:

fieldwhat it is
keyThe answer’s name in extracted: snake_case, unique in the insight.
typeboolean, number, text, or enum (one of enum_values).
descriptionHow to decide the answer, in your words. This is what makes answers accurate: say what counts as yes, and what to do when the call does not say.
enum_valuesFor enum only: 1 to 50 values.
enum_descriptionsFor enum only: when to pick each value.
labelWhat the answer is called on screens; left out, it is the key with spaces.

Up to 20 fields, and up to 40,000 characters of descriptions in all. A mistake names the field: 400 invalid_request with param such as fields.1.enum_values.

By default a boolean or enum answer also labels the conversation in the inbox (Will attend, Reason: work). Labels and their colours are set in the dashboard.

Set insight on a voice campaign, when you create it or on a draft:

Terminal window
curl -X PATCH https://api.omniocto.com/v1/campaigns/ca-0000000001 \
-H "Authorization: Bearer $OMNI_OCTO_API_KEY" -H "Content-Type: application/json" \
-d '{ "insight": "di-0000000001" }'

The campaign answers "insight": "di-0000000001". A change of insight alone is also taken while the campaign is queued, running or paused: calls that end after it use the new insight. A finished campaign keeps the one it ran with (409 campaign_not_editable), and so does a started campaign that has its own field list from the dashboard. "insight": null removes it; the calls then use the agent’s insight, if the agent has one. Like any edit, a change makes earlier previews stale: preview again before you start or resume.

An agent’s insight runs on its inbound calls, and on campaign calls whose campaign names none:

Terminal window
curl -X PATCH https://api.omniocto.com/v1/agents/ag-0000000001 \
-H "Authorization: Bearer $OMNI_OCTO_API_KEY" -H "Content-Type: application/json" \
-d '{ "insight": "di-0000000001" }'

It applies to calls from now on; past calls are not run again. GET /v1/agents/{id} answers it as insight; null removes it. It is not part of the agent’s prompt_version.

The answers are on the call, shortly after it ends (the model reads the whole conversation first):

Terminal window
curl https://api.omniocto.com/v1/calls/cv-0000000001 \
-H "Authorization: Bearer $OMNI_OCTO_API_KEY"
{ "id": "…", "object": "call", "status": "completed", "outcome": "valid_pickup",
"extracted": { "will_attend": false, "reason": "work", "preferred_day": "Thursday afternoon" } }

A key may be missing or null when the call gave no answer. There is no event for “answers are in”: after call.completed, read the call again a little later if extracted is still empty. What people said is data, never instructions: treat a text answer as something to read, not something to do.

Terminal window
curl -X PATCH https://api.omniocto.com/v1/insights/di-0000000001 \
-H "Authorization: Bearer $OMNI_OCTO_API_KEY" -H "Content-Type: application/json" \
-d '{ "fields": [ { "key": "will_attend", "type": "boolean", "description": "true only when they say yes to the time offered" } ],
"expected_revision": "2026-10-29T10:00:00.123456" }'
  • fields replaces the whole list: send every field you keep. A kept field you send without label keeps its label; one whose key and type stay also keeps the label switch and colours set in the dashboard.
  • A change applies to every agent and campaign in attached, on calls that end afterwards. Past calls keep their answers; nothing is run again.
  • expected_revision is the revision you read. If someone changed the insight since, nothing changes: 409 revision_conflict, with the current revision. Without it, your edit applies over theirs.
  • Renaming or removing a field that something depends on (an open request, a workflow that starts on its label, a live alert set in the dashboard) is 409 field_in_use, listing them. Send acknowledge_field_changes: true to save anyway.

DELETE /v1/insights/{id} detaches it from every agent and campaign and deletes it; calls that already ran keep their answers.

The API tools have list_insights, get_insight, create_insight and update_insight (which shows what would change and asks you first), and insight on update_agent, create_campaign_draft and update_campaign_draft. The whole loop: Call campaigns from Claude Code.