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

# Dial decisions in a campaign

> How a pre-call function cancels a dial or defers a contact, and what happens to the attempt.

# Dial decisions in a campaign

A pre-call function can answer "do not call this person" or "call back later" **before** the number is dialed. The phone never rings, no connection minute is spent, and the contact attempt is not burned.

This is configured on your side rather than in the cabinet: your system returns the decision in the function response, and you map it into the reserved variables.

| Variable               | Values                                                       |
| ---------------------- | ------------------------------------------------------------ |
| `call_decision`        | `proceed` — dial, `cancel` — do not call, `retry` — postpone |
| `call_decision_reason` | reason text, up to 200 characters                            |
| `call_retry_after`     | seconds, or an ISO-8601 instant                              |

Such a card is marked **"This function decides what to do with the call"**, and the form carries a hint listing the values.

What happens to the contact:

| Decision  | Dial     | Contact attempt | History record                                                                                 | Webhook                   |
| --------- | -------- | --------------- | ---------------------------------------------------------------------------------------------- | ------------------------- |
| `proceed` | goes out | spent           | normal                                                                                         | normal                    |
| `cancel`  | not sent | **not spent**   | a zero-duration session, status "not connected", reason `cancelled_by_function`, and your text | `call_ended` is delivered |
| `retry`   | not sent | not spent       | **none at all**                                                                                | **none**                  |

Where to see the result:

* on the campaign page, in the outcome breakdown — the row **"Cancelled by function"**;
* in the same place under holds — **"Deferred by a pre-call function"** for contacts awaiting another attempt;
* in the call history of a cancelled contact — a zero-duration record with the reason your system returned.

A deferred contact deliberately has no history record: your system may answer "later" ten times for one person, and ten empty calls would be noise. The durable trace is the dialer's contact-attempt row.

Retry timing: your `call_retry_after`, otherwise the interval from the campaign retry policy. A value below 60 seconds is raised to 60 — otherwise dialing would turn into a loop of requests to you. A retry later than the campaign end closes the contact as exhausted.

<Note>
  **The decision only works in campaigns.** On inbound calls, web calls, and calls placed from the cabinet or the public API it is ignored: the events show "the decision does not apply outside a campaign dial" and the call proceeds as usual. Refusing an inbound call is expressed in the flow: a condition and a transition to an end node.
</Note>

**An unknown value and a failure both mean "dial".** A typo in the field yields `proceed` with a warning in the event; a timeout or an error on your service does not cancel the dial either. The rule is deliberate: a missed call costs more than incomplete context.

**If your system breaks** and starts cancelling everything, the campaign pauses itself — so a whole list is not "processed" without a single call. By default the guard fires when all of the last 20 decisions were cancellations. Resuming is manual, once the cause is understood.
