SearchConfigDto Schema
SearchConfigDto captures per-search policy overrides. Omitted fields fall back to tenant policy, then system defaults. All top-level sections are optional, with one conditional requirement: research.skipResearch=true requires at least one outbound.contactHints[] entry with email, phone, fax, or a thirdPartyVendor.
It can be supplied in two places on a create-order request:
searchTypes[i].searchConfig — per-search overrides. When present (even as an empty {}), it fully replaces any request-level defaultSearchConfig for that search.
defaultSearchConfig — order-level default applied to every created search whose per-search searchConfig is absent.
Merge semantics are whole-object replace, not section-wise merge. If you set searchTypes[0].searchConfig = { channels: { email: true } }, only the channels override is applied for that search; timing, outbound, etc. revert to tenant/system defaults — they are not inherited from defaultSearchConfig.
Supported Fields
Most integrations only need one or two sections at a time. The tables below list every supported field by level so you can scan the shape first, then jump to examples.
Top-Level searchConfig
| Field | Type | Rules and behavior |
|---|
thirdPartyBan | string[] | Canonical third-party vendor codes banned for this search. Accepted values are listed in the Third-Party Vendor Reference, excluding UNKNOWN. Values are trimmed, uppercased, deduplicated, and capped at 50 entries. Ban matching suppresses third-party routing/webhooks and lets manual/outbound handling continue. See Third-party ban. |
channels | object | Outbound channel enablement, preferred channel, and destination allow/block lists. |
timing | object | SLA, outbound follow-up window, and business-hours overrides. |
outbound | object | Attempt caps, terminal-inbound auto-cancel, third-party deferral, and pre-known contact hints. |
research | object | Automated research controls. |
inbound | object | Verified inbound auto-complete and manual-review controls. |
escalation | object | Automatic escalation controls and third-party event suppression. |
notifications | object | Per-search notification suppression, raw inbound inclusion, and webhook routing overrides. |
channels
| Field | Type | Rules and behavior |
|---|
email | boolean | Enable or disable email outbound for this search. Tenant and organization safety rules may still suppress email. |
voice | boolean | Enable or disable voice outbound for this search. Tenant and organization safety rules may still suppress voice. |
fax | boolean | Enable or disable fax outbound for this search. Tenant and organization safety rules may still suppress fax. |
preferredChannel | EMAIL, VOICE, or FAX | First-attempt channel preference. It orders enabled channels as preferred first, then remaining enabled channels. It does not enable a disabled channel. |
blockedDestinations | string[] | Email addresses, phone numbers, or fax numbers to never attempt. Emails are lowercased; phone/fax values are reduced to digits with trailing 10-digit matching for US numbers. Max 100 entries. Mutually exclusive with allowedDestinations. |
allowedDestinations | string[] | Destination allowlist; every other destination is suppressed. Uses the same normalization as blockedDestinations. Max 100 entries. Mutually exclusive with blockedDestinations. |
timing
| Field | Type | Rules and behavior |
|---|
searchSlaMinutes | number | Maximum minutes before the search should be completed or escalated. Minimum 1. |
outboundWindowMinutes | number | Minimum minutes between outbound follow-up attempts to the same destination. Minimum 1. |
businessHours | object | Custom outbound window. See timing.businessHours below. |
timing.businessHours
| Field | Type | Rules and behavior |
|---|
timezone | string | IANA timezone identifier, such as America/Chicago. Validated with Intl.DateTimeFormat. |
startTime | string | Window start in HH:mm 24-hour format. Must be strictly earlier than endTime. |
endTime | string | Window end in HH:mm 24-hour format. Must be strictly later than startTime. |
allowedDays | number[] | Days of the week permitted for outbound. 0 = Sunday through 6 = Saturday. Each value must be in 0–6. |
outbound
| Field | Type | Rules and behavior |
|---|
maxAttemptsPerMethod | number | Maximum attempts per channel type, per contact. Range 1–20. |
maxTotalAttempts | number | Hard cap on total attempts across all channels per contact. Applied in addition to maxAttemptsPerMethod. Range 1–50. |
cancelOutboundOnTerminalInbound | boolean | Auto-cancel remaining outbound attempts when a terminal inbound response is received. A pending third-party task always cancels outbound regardless of this value. |
thirdPartyDeferral | boolean | Defer third-party vendor outbound and try direct channels first. thirdPartyBan takes precedence when the detected vendor is banned. |
thirdPartyDeferralHours | number | Hours to defer third-party outbound when thirdPartyDeferral is enabled. Range 1–720. |
contactHints | ContactHint[] | Pre-known contacts used to seed outbound. Max 50 hints. Required when research.skipResearch=true. |
| Field | Type | Rules and behavior |
|---|
name | string | Optional display name. |
title | string | Optional job title. |
department | string | Optional department or team. |
email | string | Contact email. Each hint must include at least one of email, phone, or fax, or a thirdPartyVendor. |
phone | string | Contact phone number. Each hint must include at least one of email, phone, or fax, or a thirdPartyVendor. |
fax | string | Contact fax number. Each hint must include at least one of email, phone, or fax, or a thirdPartyVendor. |
thirdPartyVendor | canonical vendor code or UNKNOWN | Marks the hint as a known third-party verification vendor. The seeded contact is flagged usesThirdParty=true and routes via the third-party path. Cannot also appear in this search’s thirdPartyBan. |
thirdPartyCode | string | Optional employer/account code at the vendor; maps to the seeded method’s thirdPartyId. Requires thirdPartyVendor. |
priority | HIGH, NORMAL, or LOW | Attempt ordering priority. Omitted value defaults to NORMAL. Hints use canonical confidence values: HIGH = 0.99, NORMAL = 0.95, LOW = 0.90. |
When research.skipResearch=true, contactHints are the sole outbound seed and the research agent is not invoked. When research.skipResearch=false, hints are merged on top of researched contacts per history item and deduplicated by normalized destination. Third-party hints are deduplicated against researched contacts (and one another) by canonical vendor code and thirdPartyCode. By default a third-party contact takes precedence over direct outbound and cancels remaining attempts; use escalation.disableThirdPartyEvent to fall through to any direct destinations on the hint.
research
| Field | Type | Rules and behavior |
|---|
skipResearch | boolean | When true, bypasses the research agent and seeds the contact plan exclusively from outbound.contactHints. Requests with skipResearch=true must include at least one hint with email, phone, fax, or a thirdPartyVendor. |
inbound
| Field | Type | Rules and behavior |
|---|
autoCompleteOnVerification | boolean | Automatically mark the search COMPLETED when a terminal verification response is received. When false, terminal verified inbounds are held for QA and emit verification.action_required with HUMAN_ESCALATION. |
requireManualReview | boolean | Hold all inbound responses for human review before finalizing. Overrides autoCompleteOnVerification. Combining requireManualReview=true with autoCompleteOnVerification=false is rejected; omit autoCompleteOnVerification or set it to true. |
Data-model implication when inbound is held for QA.When requireManualReview=true or autoCompleteOnVerification=false routes a verified inbound to QA, the persisted VerificationResult.outcome is set to ACTION_REQUIRED — not the extracted terminal outcome (VERIFIED, NO_RECORD, etc.). The extracted outcome is preserved in the activity/metadata trail for reviewers, but downstream consumers that read VerificationResult.outcome before QA resolution will see ACTION_REQUIRED. Once QA completes the manual review path, the outcome is updated to reflect the final decision.If your integration assumes VerificationResult.outcome always mirrors the inbound response, either leave autoCompleteOnVerification=true or wait for the subsequent verification.completed event before reading the outcome.
escalation
| Field | Type | Rules and behavior |
|---|
disableAutoEscalation | boolean | Prevents automatic escalation paths such as no-actionable-contacts, no-actionable-outbound-methods, retry-cap-reached, and SLA-exceeded reassignment. Takes precedence over tenant humanEscalation.enabledForSource policy. |
escalationWebhookUrl | string | HTTPS URL that overrides escalation webhook delivery for this search. Installed as a fallback endpoint for outgoing verification.action_required events. Superseded by notifications.webhookOverride when both are set. |
disableThirdPartyEvent | boolean | Suppresses the third-party verification.action_required webhook when a third-party vendor is detected. When true, outbound is not cancelled and workflow continues through enabled outbound channels. Applies broadly to all detected third parties, unlike thirdPartyBan, which is vendor-specific. |
notifications
| Field | Type | Rules and behavior |
|---|
suppressNotifications | boolean | Suppresses intermediate verification.notification events for this search. Terminal verification.completed and verification.action_required events still fire. |
includeRawInboundInWebhook | boolean | Includes raw inbound content in outgoing inbound notification payloads. Explicitly set to false to strip raw body and attachment text from those notification events. |
webhookOverride | WebhookConfigDto | Full per-search webhook override for notification and escalation delivery. Supersedes tenant-level webhook routing and escalation.escalationWebhookUrl. See WebhookConfigDto. |
notifications.webhookOverride summary
| Field | Type | Rules and behavior |
|---|
enabled | boolean | Enable or disable the override for this search. |
secret | string | Optional HMAC secret used to sign webhook deliveries. |
retryAttempts | number | Number of retry attempts on delivery failure. Range 0–10. |
closeoutEndpoints | object | Per-search-type closeout endpoints, such as EMPLOYMENT and EDUCATION. Each key maps to a URL string or one or more WebhookTargetDto entries. |
fallbackEndpoint | string, object, or array | Fallback endpoint used when no closeout endpoint matches the search type. Accepts a URL string, a WebhookTargetDto object, or an array of either. |
Examples
Ban One Third-Party Vendor
{
"thirdPartyBan": ["TALX_WORK_NUMBER"]
}
Ban Multiple Third-Party Vendors
{
"thirdPartyBan": [
"TALX_WORK_NUMBER",
"NSCH"
]
}
Ban Vendors With Normalization
The API trims whitespace, uppercases values, and deduplicates before policy resolution. This request resolves to ["TALX_WORK_NUMBER", "NSCH"].
{
"thirdPartyBan": [
" talx_work_number ",
"TALX_WORK_NUMBER",
"nsch"
]
}
Ban Third Parties While Deferral Is Enabled
thirdPartyBan wins over outbound.thirdPartyDeferral. If TALX_WORK_NUMBER is detected, no pending third-party timer is created and no delayed third-party webhook is emitted.
{
"thirdPartyBan": ["TALX_WORK_NUMBER"],
"outbound": {
"thirdPartyDeferral": true,
"thirdPartyDeferralHours": 72
}
}
Email-Only Outbound With a Blocked Generic Inbox
{
"channels": {
"email": true,
"voice": false,
"fax": false,
"preferredChannel": "EMAIL",
"blockedDestinations": ["hr-noreply@company.com"]
}
}
Weekday 9-5 Central With a 48-Hour SLA
{
"timing": {
"searchSlaMinutes": 2880,
"outboundWindowMinutes": 120,
"businessHours": {
"timezone": "America/Chicago",
"startTime": "09:00",
"endTime": "17:00",
"allowedDays": [1, 2, 3, 4, 5]
}
}
}
{
"outbound": {
"maxAttemptsPerMethod": 5,
"maxTotalAttempts": 12,
"cancelOutboundOnTerminalInbound": true,
"contactHints": [
{
"name": "Jane Doe",
"title": "HR Director",
"email": "jane.doe@company.com",
"phone": "+1 (555) 123-4567",
"priority": "HIGH"
},
{
"department": "Payroll",
"fax": "+1 (555) 555-0100",
"priority": "NORMAL"
}
]
}
}
{
"research": { "skipResearch": true },
"outbound": {
"contactHints": [
{ "email": "verify@company.com", "priority": "HIGH" },
{ "phone": "+1 (555) 123-4567", "priority": "NORMAL" }
]
}
}
Route Every Verified Inbound To QA
{
"inbound": { "requireManualReview": true }
}
Email-Only Outbound Even When Any Third Party Is Detected
Use escalation.disableThirdPartyEvent when the search should suppress every third-party event, regardless of vendor. Use thirdPartyBan when suppression should apply only to specific vendor codes.
{
"channels": {
"email": true,
"voice": false,
"fax": false,
"preferredChannel": "EMAIL"
},
"escalation": {
"disableThirdPartyEvent": true
}
}
Per-Search Webhook Override That Only Routes Completions
{
"notifications": {
"suppressNotifications": true,
"webhookOverride": {
"enabled": true,
"secret": "s3cret-per-search",
"retryAttempts": 3,
"closeoutEndpoints": {
"EMPLOYMENT": [
{
"url": "https://client.example.com/webhooks/employment-closeout",
"events": ["verification.completed"]
}
]
}
}
}
}
Complete Example
A SearchConfigDto combining most sections, as you might attach to a single search:
{
"thirdPartyBan": ["TALX_WORK_NUMBER", "NSCH"],
"channels": {
"email": true,
"voice": false,
"preferredChannel": "EMAIL",
"blockedDestinations": ["hr-noreply@company.com"]
},
"timing": {
"searchSlaMinutes": 2880,
"outboundWindowMinutes": 120,
"businessHours": {
"timezone": "America/Chicago",
"startTime": "09:00",
"endTime": "16:00",
"allowedDays": [1, 2, 3, 4, 5]
}
},
"outbound": {
"maxAttemptsPerMethod": 5,
"maxTotalAttempts": 12,
"cancelOutboundOnTerminalInbound": true,
"contactHints": [
{ "email": "hr@company.com", "priority": "HIGH" }
]
},
"research": { "skipResearch": false }
}
Attached to a create-order request either as a per-search override or an order-level default:
{
"defaultSearchConfig": {
"timing": { "outboundWindowMinutes": 120 }
},
"searchTypes": [
{
"searchType": "EMPLOYMENT",
"searchConfig": {
"thirdPartyBan": ["TALX_WORK_NUMBER"],
"channels": { "email": true, "preferredChannel": "EMAIL" },
"outbound": {
"contactHints": [{ "email": "hr@company.com", "priority": "HIGH" }]
}
}
},
{ "searchType": "EDUCATION" }
]
}
In this request:
- The
EMPLOYMENT search gets its per-search overrides — defaultSearchConfig is not merged in (e.g. outboundWindowMinutes falls back to tenant policy, not to 120).
- The
EDUCATION search has no per-search searchConfig, so it uses defaultSearchConfig (outboundWindowMinutes: 120 on top of tenant policy).
Validation Highlights
channels.blockedDestinations and channels.allowedDestinations are mutually exclusive; each is capped at 100 entries.
- Each
outbound.contactHints[] entry must include at least one of email, phone, or fax, or a thirdPartyVendor; max 50 hints.
contactHints[].thirdPartyVendor must be a canonical vendor code or UNKNOWN; unknown codes are rejected. thirdPartyCode requires thirdPartyVendor, and a hint’s thirdPartyVendor cannot also appear in thirdPartyBan.
timing.businessHours.startTime must be strictly earlier than timing.businessHours.endTime; allowedDays values must be in 0–6.
timing.businessHours.timezone must be a valid IANA timezone (validated via Intl.DateTimeFormat).
inbound.requireManualReview: true combined with inbound.autoCompleteOnVerification: false is rejected at validation time — omit autoCompleteOnVerification or set it to true.
escalation.escalationWebhookUrl and any URL fields inside notifications.webhookOverride are validated as URLs.
research.skipResearch: true requires outbound.contactHints with at least one reachable contact (email, phone, fax, or a thirdPartyVendor) and bypasses the research agent at runtime. Channel-disabled contact methods are auto-suppressed; third-party hints route outside the channel pipeline and are never channel-suppressed.
thirdPartyBan must be an array of canonical third-party vendor codes. UNKNOWN, malformed values, non-arrays, and unknown codes are rejected. Empty arrays are accepted and behave the same as omission.
- Unknown fields on
searchConfig are not part of the public contract and may be ignored by runtime policy resolution; send only the fields documented above.
Behavior Precedence
Once a search is created, the runtime resolves its effective policy by layering tenant defaults under the per-search overrides. These precedence rules apply at runtime:
- Escalation gating:
escalation.disableAutoEscalation=true wins over tenant-level humanEscalation.enabledForSource. When disableAutoEscalation=false (or omitted), the per-source tenant flag is consulted.
- Escalation webhook routing:
notifications.webhookOverride > escalation.escalationWebhookUrl > tenant webhook config. Set one or the other, not both.
- Inbound terminal routing:
inbound.requireManualReview=true routes verified inbounds to ACTION_REQUIRED regardless of autoCompleteOnVerification. When requireManualReview=false, autoCompleteOnVerification=false holds the search for QA as ACTION_REQUIRED; autoCompleteOnVerification=true (default) auto-completes.
- Outbound cancel on terminal inbound: a pending third-party task always cancels outbound, regardless of
outbound.cancelOutboundOnTerminalInbound.
- Third-party ban:
thirdPartyBan wins over immediate third-party routing, third-party deferral, and inbound third-party redirects for matching canonical vendors. Banned vendors may still appear in the contact plan for auditability, but third-party webhooks are not emitted.
- Organization preferences: applied after per-search channel overrides. An org-level channel block still suppresses a channel that
searchConfig.channels.* enables — this is a safety rail.
- Notification suppression:
notifications.suppressNotifications only affects intermediate verification.notification events. Terminal verification.completed and verification.action_required always fire.
- Raw inbound stripping: only applied when
notifications.includeRawInboundInWebhook is explicitly false. Tenants that have not set the flag retain current behavior.
Merge Semantics
- When
searchTypes[i].searchConfig is undefined or null, defaultSearchConfig applies for that search.
- When
searchTypes[i].searchConfig is present — including {} — it fully replaces defaultSearchConfig for that search. Section-wise merging is not performed.