Skip to main content

Post-Call Actions

Decide what a voice agent does on its own after each call: update the caller's contact, create a task or a support ticket, email a team member, send an approved WhatsApp template, or add a row to a Google Sheet, based on the answers the call analysis collected.

Overview

After a call ends, call analysis writes a summary, the caller's sentiment, the outcome and the answers your agent's analysis_variables ask for (for example star_rating, callback_requested). Post-call actions act on those answers automatically.

Each agent has an ordered list of rules. A rule is a set of conditions (all must pass) and one or more actions. A rule with no conditions runs after every analysed call.

ExampleConditionActions
Low rating follow-upstar_rating is at most 2Create a task for the manager, email the owner
Callback requestedcallback_requested is yesCreate a task to call back within 4 hours
Ask for a reviewstar_rating is at least 4Send your approved WhatsApp template with your review link
Keep a lognoneAdd a row to a Google Sheet
Remember answersnoneSave the rating and comment on the caller's contact

Actions run in the background shortly after the analysis finishes. Each action runs at most once per call, its status is recorded per call, and temporary failures are retried with backoff.

Authentication

Authorization: Bearer cm_your_api_key

Reading rules, options, recipes, test results and run history needs the bots:read scope. Creating, changing or deleting rules, and the on/off switches, need bots:write.

All paths below are under https://api.callmissed.com/api/v1/bots/{bot_id}/post-call.

Recipes

curl https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/recipes \
  -H "Authorization: Bearer cm_your_api_key"

Ready-made rules, already filled in from this agent's own analysis variables. Each recipe has a key, a plain-language title and description, available (with unavailable_reason when not), needs (the blanks you still choose) and the rule it would save.

Recipe keyWhat it doesneeds
low_rating_followupLow rating: create a follow-up task and email youtask_assignee, notify_user
callback_taskCaller asked for a callback: create a callback tasktask_assignee
happy_review_whatsappHigh rating: send an approved WhatsApp templatewhatsapp_template
save_to_sheetAdd a row for every call to a Google Sheetsheet
save_on_contactSave answers on the caller's contactcontact_fields
issue_ticketCaller reported a problem: open a high-priority ticketnone

Save one with its blanks filled:

curl -X POST https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/rules/from-recipe \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "recipe": "low_rating_followup",
        "fills": { "assignee_user_id": "6f1c…", "notify_user_id": "6f1c…" } }'
fills fieldUsed by
assignee_user_idThe team member who gets the task or ticket
notify_user_idThe team member who gets the email. Omit for the workspace owner
template_id, template_variablesThe approved WhatsApp template, and the text for each of its inputs
integration_id, spreadsheet_id, sheetThe Google Sheets connection, spreadsheet and tab
contact_field_ids{answer name: contact field id}. Answers left out get a new contact field
nameOptional new rule name

Building blocks

curl https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/options \
  -H "Authorization: Bearer cm_your_api_key"

Returns everything a rule can use for this agent: variables (its analysis variables with their types), call_fields, operators per type, tokens for text, team, contact_fields, sendable whatsapp_templates with their inputs, and shared Google sheets. Use these ids; a rule that names anything else is refused.

Rules

MethodPathWhat it does
GET/rulesThe agent's rules, in order
POST/rulesAdd a rule
PATCH/rules/{rule_id}Change a rule; only the fields sent change. {"enabled": false} pauses it
DELETE/rules/{rule_id}Delete a rule. What it already did stays in the history
GET / PUT/settings{"enabled": true}: the agent-wide switch for all its rules
curl -X POST https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/rules \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Low rating follow-up",
    "conditions": [ { "field": "star_rating", "op": "lte", "value": 2 } ],
    "actions": [
      { "type": "create_task",
        "config": { "title": "Low rating ({{star_rating}}) from {{caller_number}}",
                    "description": "{{summary}}", "due_in_hours": 24 } },
      { "type": "notify",
        "config": { "subject": "Low rating from {{caller_number}}", "message": "{{feedback_comment}}" } }
    ]
  }'

A rule is checked when it is saved: every condition must name one of the agent's analysis variables (or a call field) with an operator that suits its type, every {{token}} must exist, and every team member, contact field, template and spreadsheet must belong to your workspace. A problem returns 422 with a message saying what to fix.

LimitValue
Rules per agent20
Conditions per rule10
Actions per rule1 to 5

Conditions

{ "field": "...", "op": "...", "value": ... }. field is one of the agent's analysis variable names, or call.sentiment, call.disposition, call.goal_met or call.direction.

Field typeOperators
numbereq, ne, lt, lte, gt, gte, between (value: [low, high]), is_empty, is_not_empty
booleanis_true, is_false, is_empty
enumis, in (value is a list of options), is_empty, is_not_empty
stringcontains, is, is_empty, is_not_empty

An unanswered variable never matches a comparison, only is_empty. If a variable is later removed from the agent, conditions on it stop matching.

Actions

{ "type": "...", "config": { ... } }. Text fields take {{tokens}}: any analysis variable, plus summary, sentiment, disposition, goal_met, caller_number, contact_name, agent_name, call_date, call_time, call_duration, call_direction and call_link.

typeconfigNotes
set_contact_fieldsfields: [{field_def_id or create_field: {label, field_type}, value}], create_contact (default true)Writes custom fields on the contact with the caller's number, creating the contact if needed. Only when the number is verified: outbound calls and WhatsApp calls always are; inbound phone calls only when the agent trusts caller ID
create_tasktitle, description, assignee_user_id, due_in_hours (0-720)Linked to the caller's contact when there is one
create_ticketsubject, description, priority (low, normal, high, urgent), assignee_user_idYour ticket routing rules apply
notifyuser_id (omit for the workspace owner), subject, messageAn email to an active member of your workspace
send_whatsapp_templatetemplate_id, variables: {input key: text}An approved template without a media header, from a connected number on its WhatsApp account
append_sheet_rowintegration_id, spreadsheet_id, sheet, columns: [{header, value}] (1-30)Missing header cells are added to the tab first

WhatsApp consent. A message is never sent to a number that opted out of your WhatsApp messages or is on your do-not-contact list. A marketing template is sent only to contacts who agreed to receive WhatsApp messages. The action is recorded as skipped, with the reason, when either applies. WhatsApp messages are billed as usual.

Test a rule

curl -X POST https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/dry-run \
  -H "Authorization: Bearer cm_your_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "session_id": "…" }'

Runs the agent's saved rules (or one rule_id, or an unsaved rule) against a past call of this agent. For each rule: matched, each condition with the call's actual value and passed, and for each action a plain-language would and a blocked_reason when it would be held back. Nothing is sent, saved or created. GET /recent-calls?limit=20 (1-50) lists the agent's latest analysed calls to pick from. A call without a finished analysis returns 409.

Run history

curl "https://api.callmissed.com/api/v1/bots/{bot_id}/post-call/runs?session_id=…" \
  -H "Authorization: Bearer cm_your_api_key"

One entry per action per call, newest first (limit 1-100, default 50; offset 0-10000): rule_name, action_type, status (pending, running, succeeded, failed, skipped), attempts, error (why it failed or was skipped) and result (for example task_id, ticket_id, contact_id, send_id).

From an AI assistant

The Account MCP server can set all of this up: list_post_call_recipes, get_post_call_options, create_post_call_rule_from_recipe, create_post_call_rule, update_post_call_rule, toggle_post_call_rule, set_post_call_actions_enabled, delete_post_call_rule, list_post_call_recent_calls, dry_run_post_call_rule and list_post_call_action_runs. The post_call_actions playbook (get_playbook) walks an assistant through interviewing you first.