SLA and escalation
Searches run asynchronously. When automation cannot finish, or when time limits are exceeded, SNH AI escalates withverification.action_required (typically HUMAN_ESCALATION). Some post-research action-required events are non-terminal HITL holds: the search stays IN_PROGRESS so a human can add contacts or terminate it. Organization-level policy controls SLA windows and which escalation sources are enabled.
Related: Errors · Webhook events · Third-party ban
Workflow terminal conditions
Research phase
- No contacts / no actionable contacts / voice-only / research task failed: With
searchConfig.parallelProcessing: true, non-terminalverification.action_requiredwithHUMAN_ESCALATIONandmetadata.escalationSubtypeofPOST_RESEARCH_NO_CONTACTS,POST_RESEARCH_VOICE_ONLY, orPOST_RESEARCH_TASK_FAILED. This includes channel-policy dead ends where contacts exist but every method isCHANNEL_DISABLED(for example email contacts when only fax is allowed). The search remainsIN_PROGRESSfor human contact updates or customer termination. WhenparallelProcessingisfalseor omitted (default), those paths terminalize. - Third-party record detected: non-terminal
verification.action_requiredwithTHIRD_PARTY_RECORD(structured contact details). WithsearchConfig.parallelProcessing: true, the search remainsIN_PROGRESS, storesmetadata.actionRequiredHold.subtype: "POST_RESEARCH_THIRD_PARTY", and waits for a human contact update or customer termination. WhenparallelProcessingisfalseor omitted (default), the path terminalizes (legacy search-wide cancel). - Inbound third-party redirect: when third-party deferral is disabled, emits
verification.action_requiredwithTHIRD_PARTY_RECORDandmetadata.actionRequiredHold.subtype: "INBOUND_THIRD_PARTY". WithsearchConfig.parallelProcessing: true, this is a stay-open hold (pending outbound cancelled for the responding contact thread; other contacts may continue with a no-remaining-work backstop), and automatic SLA reassignment does not terminate the hold. When third-party deferral is enabled, the search storesmetadata.pendingThirdPartyand keeps trying other channels until the deferred emission is due. WhenparallelProcessingisfalseor omitted, inbound third-party paths use legacy search-wide cancel and terminalize. - Banned third-party vendor: When
searchConfig.thirdPartyBancontains the detected vendor code, theTHIRD_PARTY_RECORDwebhook is suppressed and the search continues with manual or outbound handling. Inbound redirects to a banned vendor emit non-terminalHUMAN_ESCALATIONwithmetadata.escalationSubtype: "THIRD_PARTY_BAN"and stop only the responding contact thread whenparallelProcessing: true; otherwise they use legacy search-wide cancel and terminalize. See Third-party ban.
Outbound phase
- Transient retry cap reached: After 3 transient retries per channel (voice/email/fax), the search is reassigned with
HUMAN_ESCALATION - Processing failure: After max retries, the search escalates with
SYSTEM_FAILURE,UPSTREAM_ISSUE, orSLA_REACHED
SLA and automatic reassignment
- Frequency: Checks run every 4 hours (system-level, not configurable)
- Search SLA: Default 24 hours (organization-configurable via
policy.global.searchSlaMinutes) - Reassignment window: Default 48 hours (organization-configurable via
policy.global.reassignmentWindowMinutes) - Weekend adjustment: Deadlines that fall on Saturday/Sunday move to the next Monday (system behavior)
- Trigger: Whichever of SLA or reassignment window is reached first
- Reason code:
HUMAN_ESCALATIONwith metadata - Contact plan: Optionally included when
policy.global.includeContactPlanInEscalationistrue(defaultfalse)
Configuring SLA settings
These settings are configured at the organization level via unified policy (not per API request unless you usesearchConfig.timing):
Per-search overrides: see Search-level configuration (
timing.searchSlaMinutes).
Per-source human escalation (optional)
Disable escalation for specific reasons viapolicy.global.humanEscalation.enabledForSource. Set a source to false to prevent reassignment for that reason. Omitted sources remain enabled.
searchConfig.escalation.disableAutoEscalation=true on a search always suppresses escalation for that search, regardless of this tenant-level setting.
IN_PROGRESS until another condition is met. Use only when you accept that behavior. Existing organizations are unchanged if they do not set this config.
Important notes
- When a workflow is terminalized, no further outbound attempts are made
- Terminal conditions and automatic reassignment are idempotent (no duplicate escalation webhooks)
- Contact plan data in escalation webhooks is opt-in per organization (
includeContactPlanInEscalation)

