Documentation Index
Fetch the complete documentation index at: https://docs.thinnest.ai/llms.txt
Use this file to discover all available pages before exploring further.
Retry & Escalation
When an outbound voice call doesn’t connect — the contact didn’t answer, the line was busy, or it went to voicemail — your campaign can automatically:- Retry the contact later, on a custom schedule (uniform or per-step).
- Escalate to a human via email or webhook once retries are exhausted (or if the contact permanently failed).
Retry on No Answer
Failed outcomes that trigger a retry:no_answer, busy, voicemail.
Per-step interval schedule (recommended)
Instead of a single interval that applies to every retry, you can specify a list of delays — one entry per retry, in order. The first retry runs after the initial attempt fails.| Retry | Delay |
|---|---|
| #1 | 1 hour (60 minutes) |
| #2 | 5 hours (300 minutes) |
| #3 | 24 hours (1440 minutes) |
Uniform mode (legacy)
Older campaigns saved a singleintervalMinutes value applied to every retry, plus a maxAttempts count. Those campaigns continue to work — the backend reads the legacy shape and treats it as the equivalent per-step list.
Persisted shape
In the campaign’sconfig JSONB column:
intervalsMinutes dictates the attempt count.
Behaviour notes
- Retries are scheduled via the same arq deferred-job pipeline used elsewhere in the platform (proven in production).
- If the contact’s wallet has no funds at retry time, the dispatch is skipped and logged — no infinite loop.
- DND / TRAI compliance checks run on every retry, the same as the original attempt.
- A retry that succeeds (caller picks up) ends the chain immediately for that contact.
Escalation
Escalation fires once per contact when the contact has either:- Exhausted every configured retry without picking up, or
- Hit a permanent failure (
invalid_number,error,undelivered, etc.) that retries can’t recover from, or - Failed with retries disabled.
Channels
Both channels are independent. Either or both may be configured per campaign — at least one is required for escalation to fire.A contact in campaign Acme Onboarding Campaign has exhausted its retry attempts and was flagged for escalation.The timestamp is rendered in the timezone configured in your campaign’s Schedule step (defaults toAction: reach out to this contact manually or investigate why retries failed.
Contact John Doe <+919876543210>Last outcome no_answerAttempts 3 Campaign ID 47 Run ID 1029 Timestamp 2026-04-20 13:02:14 IST
Asia/Kolkata if unset). The contact’s phone number is masked to its last 4 digits in the subject; the full number appears in the body.
Webhook
If a webhook URL is set, a JSON payload is POSTed to it with a 10-second timeout:timestamp is always UTC ISO-8601 for machine consumers; timestamp_local and timezone mirror what humans see in the email.
A response with status 2xx is treated as a successful delivery. Non-2xx responses are logged but don’t retry — the platform fires escalation exactly once per contact.
Configuration
In the campaign modal, Advanced Settings → Escalation:config:
email and escalateTo are still read by the backend for backward compatibility.
Counter
Each successful escalation dispatch (at least one channel accepted the call) incrementsescalated_count on the campaign run. You can see this in the campaign results panel and via the API:
End-to-end flow
- Campaign starts → contacts dialed in batches.
- A contact’s first attempt returns
no_answer. - Retry #1 is scheduled for
intervalsMinutes[0]minutes from now. - Retry runs at the scheduled time, returns
busy. - Retry #2 is scheduled for
intervalsMinutes[1]minutes after retry #1. - Retry #2 runs, returns
voicemail. - There are no more retries (list length = 3, this was retry #3 candidate but the schedule only had 3 entries → stop).
- Escalation fires — email is sent + webhook POSTed.
escalated_counton the run goes up by 1.
Best practices
- Use escalating delays (
60, 300, 1440) rather than aggressive uniform delays. Calling someone six times in an hour is a fast way to become spam. - Set both email + webhook so a missed email (filter, vacation) doesn’t mean a missed lead.
- For high-volume campaigns, point the webhook at a real ticketing system (Zendesk, HubSpot, Slack) so escalations land in your team’s queue.
- Use the campaign’s Schedule timezone rather than relying on UTC for the email timestamp — operators reading the email shouldn’t have to do mental math.
Related
- Outbound Campaigns — Campaign basics.
- Contact Management — Importing contacts.

