Per-call post-call actions
Choose where one specific call's results are sent, and which variables are extracted, at dial time, without changing the agent's own configuration.
An agent has post-call actions you configure once: the email that receives the call report, the webhook that receives the call data, and the variables extracted from the conversation. Sometimes one agent dials on behalf of many downstream systems, and each call's result belongs somewhere different: a different webhook per customer, a different set of variables per campaign, or a report emailed to the person who asked for the call.
Send __post_call_actions when you start the call and that call's results go
where you say, without touching the agent's own settings and without affecting
any other call in flight.
It works on a single dispatched call and on a web call session.
What it changes
The value is exactly the post_call_actions object you send when you
create an agent: an email action,
a webhook action, or both. Email and webhook are the only actions a call can
carry.
The actions you send replace the agent's configured post-call actions for that one call. They are not added to them. For the call you dialed:
- only the deliveries you sent fire. The agent's own post-call actions (email, webhook, Slack, HubSpot, Salesforce, Sheets, WhatsApp, Workflow and the rest configured on the agent) do not run for this call.
- only the variables you sent are extracted from the conversation. The agent's own extracted variables are not.
Everything else about the agent (its prompt, voice, languages, tools) is unchanged, and so is the saved agent.
Dialing one call
Add __post_call_actions to the dispatch request.
{
"agent_id": 158910,
"to_number": "+15551234567",
"__post_call_actions": {
"webhook": {
"enabled": true,
"url": "https://hooks.acmecrm.io/omnidim/calls",
"include": ["summary", "extracted_variables"],
"extracted_variables": [
{ "key": "appointment_date", "prompt": "The date the customer agreed to, in YYYY-MM-DD." },
{ "key": "callback_requested", "prompt": "true if the customer asked to be called back, else false." }
]
},
"email": {
"enabled": true,
"recipients": ["demo@example.com"],
"include": ["summary", "sentiment", "fullConversation"]
}
}
}The response tells you what will run:
{
"success": true,
"requestId": 91422,
"status": "dispatched",
"custom_variables_count": 0,
"languages_applied": [],
"languages_ignored": [],
"post_call_actions_applied": ["email", "webhook"],
"post_call_actions_ignored": []
}You can also put __post_call_actions inside call_context if that suits
your integration better. It behaves the same way, and it is never passed to the
agent as a context variable.
The webhook receives the normal post-call payload, the same one an agent's own
webhook receives. The variables you sent appear under
call_report.extracted_variables:
{
"call_status": "completed",
"call_report": {
"summary": "The customer booked an appointment for October 3.",
"extracted_variables": {
"appointment_date": "2026-10-03",
"callback_requested": false
}
}
}When something is rejected
A webhook URL must be a publicly reachable endpoint. Local, private network and cloud-internal addresses cannot receive your call data, so they are rejected. This is the same check the agent's own webhook setting uses.
{
"agent_id": 158910,
"to_number": "+15551234567",
"__post_call_actions": {
"webhook": {
"enabled": true,
"url": "http://localhost:8000/hook"
},
"email": {
"enabled": true,
"recipients": ["demo@example.com"],
"include": ["summary"]
}
}
}The webhook is dropped, the email still runs:
{
"success": true,
"requestId": 91423,
"status": "dispatched",
"custom_variables_count": 0,
"languages_applied": [],
"languages_ignored": [],
"post_call_actions_applied": ["email"],
"post_call_actions_ignored": [
{
"channel": "webhook",
"code": "invalid_url",
"message": "Webhook URL must point to an address reachable from the internet. Local and private network addresses cannot receive your call data. If you are testing locally, use a tunnel URL instead."
}
]
}Each ignored item carries a code:
| Code | Meaning |
|---|---|
invalid_url | The webhook URL is missing, is not http:// or https://, looks like a placeholder, or is not reachable from the internet. |
disabled | The action was sent without "enabled": true. |
no_recipients | The email action has no recipient addresses. |
unsupported_channel | A channel other than email or webhook, such as slack. Those need an integration set up on the agent. |
duplicate_variable | The same variable key was sent on both actions with different prompts. The first one wins and the later one is dropped. The same key with the same prompt is fine. |
unsupported_route | The key was sent on a route that does not honor it. See Campaigns. |
invalid_directive | __post_call_actions is not an object with email and/or webhook: a string, list, number, null or an empty object. channel is null, and the agent's own post-call actions run. |
The two response fields appear only when you sent __post_call_actions. A
request without it gets the usual response.
Starting a web call
Send it with the session's custom variables when you create the session.
{
"agent_id": 158910,
"type": "voice",
"custom_variables": {
"name": "Rahul",
"__post_call_actions": {
"webhook": {
"enabled": true,
"url": "https://hooks.acmecrm.io/omnidim/web-calls",
"include": ["summary", "extracted_variables"],
"extracted_variables": [
{ "key": "product_interest", "prompt": "The product the visitor asked about." }
]
}
}
}
}The key is removed before your other variables reach the agent, so name is
passed through and __post_call_actions is not. The response carries the same
two fields alongside the session:
{
"session_id": 4521,
"token": "sess_51gF2qw8LxNz0vY4mT7Ka3RjD9pBcE6HuWiQnZsX0oM",
"expires_at": "2026-10-01T12:15:00Z",
"ws_url": "wss://live.omnidim.io/chat/start_voice_chat?request_token=sess_51gF2qw8LxNz0vY4mT7Ka3RjD9pBcE6HuWiQnZsX0oM",
"post_call_actions_applied": ["webhook"],
"post_call_actions_ignored": []
}Campaigns
Bulk campaigns do not support per-call post-call actions. A campaign's calls use the agent's own post-call actions.
If a contact sent to the bulk create or add-contact endpoints carries
__post_call_actions, the key is removed from that contact, the contacts are
still added, and the response tells you it was not used:
{
"post_call_actions_ignored": [
{
"channel": null,
"code": "unsupported_route",
"message": "__post_call_actions is honoured only on /api/v1/calls/dispatch and /api/v1/sessions/create; it was ignored for these contacts."
}
]
}A __post_call_actions column in a CSV upload is not supported either.
Parameter
Prop
Type
trigger_call_statuses decides which call outcomes fire an action. Leave it
out to use the default, completed and voicemail_detected. See
Create agent for every field.
