Mailbox detection
Detect voicemail and other machines on outbound calls, and retry a lead list safely, for example from n8n.
Mailbox detection tells you whether an outbound call reached a person or a machine. Turn it on per call, then read the result from getCall. This guide shows how a workflow tool such as n8n can use it to work through a lead list. SMAO places each call; the retry schedule is yours.
Start a call with detection
Detection is off unless you set mailbox_detection: true:
curl -X POST https://api2.smao.ai/api/v1/calls \
-H "Authorization: Bearer $SMAO_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "assistant_id": "<assistant_id>", "to": "+491701234999", "mailbox_detection": true }'Detection works for assistants whose language is de. For any other
language, including de-CH, the call runs normally and detection reports
skipped with the reason language_not_supported.
Read the result
Poll the call until done is true. The result is in mailbox_detection:
{
"data": {
"id": "65f8fa6f1a9d8e0012ab34cd",
"done": true,
"ended_at": "2026-07-01T10:00:00.000Z",
"mailbox_detection": {
"status": "completed",
"category": "machine-vm",
"reason": "Voicemail instructions permit leaving a message.",
"greeting": "Bitte hinterlassen Sie eine Nachricht nach dem Signalton.",
"decided_at_ms": 10400
}
}
}A machine category (machine-vm, machine-ivr, machine-unavailable) ends
the call. human and uncertain leave the conversation running. See
getCall for every field.
Poll every 5 seconds for the first minute, then every 15 seconds. If a call has no result after 30 minutes, mark the lead for review instead of calling again.
Keep an attempt ledger
For each lead, store its ID, phone number, attempt count, current call ID, processed call IDs, next attempt time, and status. Use a store with atomic updates so one lead never has two active attempts, and so a repeated poll or a restarted workflow never counts an attempt twice.
Reserve the attempt before you create the call, and save the returned call ID right after. Count three attempts in total, not three retries.
Creating a call is not idempotent. Turn off automatic retries on the request that creates the call. If it times out or returns an unclear error, the call may already exist: pause the lead and check before trying again.
Decide once per ended call
| Result | Action |
|---|---|
completed with a machine category, fewer than three attempts | Schedule the next attempt no earlier than the call's ended_at plus two hours. |
completed with a machine category, third attempt | Mark the lead exhausted. |
completed with human or uncertain | Use your qualification analysis (below). |
failed, skipped, missing, or no ended_at | Mark the lead for review. |
Schedule in UTC. Example: a machine answer ending at 10:00 UTC allows the next attempt from 12:00 UTC.
Space calls from the same assistant at least 60 seconds apart. By default each API key can create 60 calls per hour and make 1,000 reads per minute; see Errors & Rate Limits.
Qualification is a separate result
Analyses, CRM actions, and notifications run for every call, including
machine calls, so check the detection result before acting on them. An ended
call can still have an analysis running: wait for your qualification
analysis to complete, and send failed or missing results to review. The
call's success field rates call quality, not whether the lead qualified.
Test the workflow with a few controlled leads before a real campaign, including duplicate runs, restarts, and unclear responses.
Per-assistant usage for a week GET
Returns one breakdown row per assistant that had at least one completed call starting in the selected week. Includes assistants that have since been deleted - their calls still count and the row carries `is_deleted: true`. Duration fields are integer seconds, rated as described for `/statistics/usage`.
Distributor API v1
Manage partners, customer organizations, plans, usage, and billing.