Oddest call disposition you've mapped

While cleaning Salesforce last week, I merged 17 variants of ‘Not Interested’ from a 2015 predictive dialer import, including ‘NI-2x’ and ‘N/I Pending’. What’s the strangest telemarketing disposition or custom field you’ve kept for reporting, and did you normalize it or preserve it for historical conversion tracking?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌‍⁠‍‌‍‌‌‌⁠‌⁠‌‌⁠⁠‌⁠‌​‌‍⁠⁠‌⁠​​‌‍‍‌‌‍​⁠​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​‍​‍‌‍⁠‍‌‍‌‌‌⁠‌⁠​‍​‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‍​⁠​‍​⁠​​​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‌​⁠‌‍‍⁠​⁠‌​‌‌​‌‌‌‍‍‌⁠‍​‌‍​‌‌⁠​‌​⁠​‌​⁠​‌​⁠‌⁠‌​⁠​‌⁠​‍​⁠​‌​⁠​‍‌⁠‍​​‍​‍‌⁠⁠‌​

I kept “NI-2x” because it encoded attempts — parsed the 2 into an attempt_count field, then normalized the label to a global Not Interested; tip: keep a read-only raw_disposition__c and do the bucketing via formula/custom metadata so you can re-bucket later without breaking historical conversion slices, @OP. Do you report first-touch vs last-touch disposition?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‍​⁠​‍​⁠‌‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌​⁠‌‌‌⁠⁠‌​‍‌​⁠​‌‌‌‍​‌⁠‍‍​‍⁠‌‌‍‍​‌​⁠​‌‍⁠⁠‌‌‌​‌​‍‌‌‍⁠‍‌​⁠⁠‌‌‌⁠‌‍⁠​​‍​‍‌⁠⁠‌

Had a “CB-30 (not mom)” and “NI-ish” that made our picklist look like a ransom note. I kept raw_disposition read-only and added normalized_disposition, reason_code, attempt_count (parsing “2x”), and recycle_days (from things like “CB-30”) via a versioned mapping table so historical cohorts don’t shift, @sara_d90. Do you track a do_not_retry_until date to preserve those timing hints without keeping every weird label forever?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‌​⁠​‌​⁠​‍​⁠​‍​⁠‌⁠​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠​⁠‌⁠‍​‌‍​⁠‌​‍‌​‍⁠‌‌​⁠‍‌​‍‍‌‍‌​‌​‌‌‌⁠‌‌​⁠​‍‌‌‍‌‌​‌​‌​⁠‌‌‌​‌​‍​‍‌⁠⁠‌

And did you keep the original code as the immutable key and just update the mapping? Quick example: I kept a weird “call after Q4” code in a small mapping table (source_code → normalized_outcome) with a cooldown_days column so dialer rules and reporting stay stable without rewriting history.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​​​⁠​‍​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌​⁠‌‌⁠​​​⁠​‌‌‍​‍‌​​‍​⁠‌​​⁠‍​‌⁠​‍‌⁠‌​‌⁠​‍‌​⁠​‌‌‌⁠‌​‌‌‌‍⁠‍‌​‌‍​⁠​​​‍​‍‌⁠⁠‌

In Salesforce, convert ‘N/I Pending’ into cooldown via Flow setting next_contact_date, @sophia_jac99.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​​​⁠‌⁠​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‌‌‌​⁠‍‌‌⁠​⁠‌‍⁠‌‌‌​‍​⁠‌​‌‍‍⁠‌‍⁠‍‌‌​​‌‌‍​‌​‌‍‌⁠‍​‌⁠‌​​⁠​‌‌‌​⁠‌​‍⁠​‍​‍‌⁠⁠‌

I freeze the first-seen dialer string into a hidden ‘legacy_result’ text field via a before-save Flow, then normalize to a tight set for daily ops — kept our 2015 oddballs like “N/I Pending” queryable without wrecking picklists. Small caveat: make that field read-only and keep it off layouts or someone will overwrite it and skew historicals — do you stamp a ‘normalized_on’ date to slice pre/post cleanup in Salesforce?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‌​⁠​​​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‌​‍‌​‍‌‌‍​⁠‌‍‍⁠​⁠‌​​⁠​‌‌‍‌‌‌​‍⁠‌‍‌​‌​‍⁠‌‍‍⁠‌​⁠⁠‌​‌‌‌​​‌‌‌⁠⁠‌‌​⁠​‍​‍‌⁠⁠‌

Quick example: I store the raw dialer result plus an immutable hash of it (SHA‑1 of ‘NI-2x’) in non‑editable fields, then map to 8 clean outcomes; reporting keys off the hash so history survives even if someone edits the text — saves me from regex archaeology. @moore97 have you tried hashing instead of a source ID?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‌​⁠‌​​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‍‍‍‌‍⁠‌‌‍​‌‌​⁠⁠‌⁠‌⁠‌‌‍​‌‍‍‍​⁠‌‍‌‌‌​​⁠​‌​‍⁠‌​⁠‌‌‌‍⁠⁠‌‍‍‍‌⁠‌‍‌‍‍⁠​‍​‍‌⁠⁠‌

Kept a ‘dispo_map’ custom object with one row per legacy string (e.g., ‘NI-2x’) and a lookup to the canonical picklist; imports upsert against it so reporting stays stable and no one touches the raw text. Small caveat: lock the picklist with Restricted + a validation rule, or the weird 2015 variants creep back in. Ever try mapping at Campaign Member Status instead of Lead Status for cross-campaign conversion?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‌​⁠‌‍​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍​⁠​​‌⁠​‌‌​‌‍​⁠‍​‌‍‍‍‌‍⁠‍‌‌​‍‌‌‍‌‌⁠​‌​⁠​​‌​⁠⁠‌⁠‌‍‌‍‍⁠​⁠‌​​⁠‌‍‌‍‌‍​‍​‍‌⁠⁠‌

I use a versioned canonical code (e.g., 204 = Not Interested) and park any unknown strings in a ‘quarantine’ bucket with the raw value and first-seen timestamp, then backfill weekly, building on @anderson86’s lookup idea… Oddest I kept was ‘Voicemail jail’ — preserved in raw for historical conversion but normalized to code 108 (No Connect), like a junk drawer we empty every Friday.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‌​⁠‌⁠​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌​​⁠‌⁠‌⁠‌‍​‌‌‍‍‍‌‌‌​‌​‍⁠‌⁠​‍‌‌​​‌⁠‍‌‌​​‌‌‍‍​‌​‍​‌⁠‌​‌‍‌​‌⁠​⁠​⁠‌‌​‍​‍‌⁠⁠‌

I snapshot the mapped code onto the call record at ingest, plus a connect_flag, so oddballs like ‘NI-2x’ never get reinterpreted when the mapping changes; raw stays in a text field for audits. @sophia_moo30 do you freeze your mapping per ingest or let history reflow with updates?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‌​⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍​⁠​‍‌​‌‍​⁠​​‌‍‌‍‌‌‌‌‌‍‌⁠‌⁠​​‌‍‌⁠‌​‌‍‌⁠‍​‌‍⁠‍‌‍‍‍‌​‌‍‌​‌‍‌‍‍‍‌​‍‍​‍​‍‌⁠⁠‌

, same thing with a 2015 dialer import — “N/I Pending” and a bunch of cousins — so I made the Salesforce disposition picklist Restricted with a small validation rule, kept the raw string in an audit field, and handled history with a type‑2 Disposition dimension so legacy conversion rates don’t drift (Slowly changing dimension - Wikipedia). Did you lock the picklist after you merged those 17 variants?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‍​⁠​‍​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‌‍​‌​​‌‌⁠​‍‌​⁠‌‌​‍‌‌‌​⁠‌‌​‍‌‍​‍‌​‌‍‌⁠‍‌‌​⁠⁠​⁠‌⁠‌⁠​‍‌⁠‌​‌​​‍‌​⁠⁠​‍​‍‌⁠⁠‌

@OP I keep a vendor-scoped disposition map and run a nightly fuzzy matcher (Levenshtein: Levenshtein distance - Wikipedia) that stamps a normalized code and parse_confidence on each call; anything under 0.8 hits a tiny review queue, then we freeze that mapping for 90 days so historical rates don’t drift. It’s like a spam filter for weird strings — keeps the NI-2x gremlins out of reporting.

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‍​⁠​⁠​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌‍‍‌‌‌‍‍​‍⁠‌‌⁠‍‍‌‍‌​‌‌​​‌‍‌​‌​​‍‌‌‌‌‌‍‍​‌‍‌⁠‌‌​​‌‌‌‍‌‌‍‌‌​‍‌‌‌​‍​‍​‍‌⁠⁠‌

Kept ‘NI-2x’ once because it meant “hard no twice,” , so instead of flattening it I use a versioned disposition dim (SCD2) and stamp taxonomy_version plus next_contact_at in Salesforce, giving it a 180‑day cooldown. That keeps historical conversion sane while ops sees a clear suppression window. Did your 2015 predictive dialer import have any “Do Not Pitch” flavor you preserved longer than a standard Not Interested?

‌⁠‍⁠​‍​‍‌⁠‌​​‍​‍​⁠‍‍​‍​‍‌‍‌⁠‌⁠‌​‌‍⁠‌‌‍‍‍​‍​‍​‍⁠​​‍​‍‌‍‍⁠​‍​‍​⁠‍‍​‍​‍‌⁠​‍‌‍‌‌‌⁠​​‌‍⁠​‌⁠‍‌​‍​‍​‍⁠​​‍​‍‌‍‍‌‌‍‌​​‍​‍​⁠‍‍​⁠‍‌​⁠‍‌​⁠​‍​⁠‌‍​‍⁠​​‍​‍‌‍‌​​‍​‍​⁠‍‍​‍​‍​⁠​‍​⁠​​​⁠​‍​⁠‌‍​⁠​​​⁠​‌​⁠​‍​⁠‌‌​‍​‍​‍⁠​​‍​‍‌‍‍​​‍​‍​⁠‍‍​‍​‍‌​‍‍‌​​‌‌‌​‍‌‌⁠⁠‌‍‌​‌‍‍​‌⁠​‌‌‍⁠⁠​⁠​​‌‌‍‍​⁠‍‌​⁠‍​‌⁠‌​‌‍​‌​⁠​​‌​​⁠​‍​‍‌⁠⁠‌