Why the PresenceUserConfig Metadata Type Controls the Agent Experience

While ServiceChannel defines what is routed and QueueRoutingConfig defines how items are prioritized, PresenceUserConfig (presenceUserConfigs/<Name>.presenceUserConfig-meta.xml) governs the agent’s Omni-Channel console behavior and capacity limits:

  1. Total & Interruptible Capacity (capacity, interruptibleCapacity): Maximum workload units an agent can hold at once, plus separate capacity for background/interruptible work (Case / Email) vs. live synchronous channels (Voice / Messaging).
  2. Auto-Accept vs. Manual Decline (enableAutoAccept, enableDecline, declineReasons): Whether work opens automatically or allows agents to reject offers with an audited reason.
  3. Automatic Away Status on Missed Push (presenceStatusOnPushTimeout, presenceStatusOnDecline): Prevents “ghost agents” who walk away from their desk without logging out of Omni-Channel from stalling the routing queue.
PresenceUserConfig(Tier2_Blended_Agents.presenceUserConfig-meta.xml) Capacity Limits(capacity: 10, interruptibleCapacity: 6) Offer Handling(enableAutoAccept vs enableDecline) Ghost-Agent Protection(presenceStatusOnPushTimeout: Away_No_Response) assignments(Profiles / Users)

Key Metadata Fields on PresenceUserConfig

Field Type Required Description
label string Yes Display name of the Presence Configuration in Setup.
capacity int Yes Maximum primary capacity units an agent assigned to this configuration can hold simultaneously.
interruptibleCapacity int No (API v57.0+) Maximum capacity units allowed for interruptible work items (where QueueRoutingConfig.isInterruptible = true).
enableAutoAccept boolean No Automatically accepts pushed work items without requiring the agent to click Accept (cannot be combined with enableDecline = true).
enableDecline boolean No Allows agents to decline pushed work offers.
enableDeclineReason boolean No Requires agents to pick a reason (declineReasons) when declining a work item.
presenceStatusOnDecline string No ServicePresenceStatus developer name automatically applied when an agent declines an offer.
presenceStatusOnPushTimeout string No ServicePresenceStatus developer name automatically applied when a push offer times out (QueueRoutingConfig.pushTimeout).
acwExtensionEnabled boolean No (API v60.0+) Allows agents to extend their After Conversation Work (ACW) wrap-up timer.
maxExtensions / acwExtensionDuration int No (API v60.0+) Number of allowed ACW extensions and seconds per extension.

Real-World XML Example (presenceUserConfigs/Blended_Voice_And_Case_Agents.presenceUserConfig-meta.xml)

XML
<?xml version="1.0" encoding="UTF-8"?>
<PresenceUserConfig xmlns="http://soap.sforce.com/2006/04/metadata">
    <acwExtensionDuration>60</acwExtensionDuration>
    <acwExtensionEnabled>true</acwExtensionEnabled>
    <capacity>10</capacity>
    <declineReasons>On_Customer_Escalation_Call</declineReasons>
    <declineReasons>Shift_Ending_Within_10_Mins</declineReasons>
    <enableAutoAccept>false</enableAutoAccept>
    <enableDisconnectSound>true</enableDisconnectSound>
    <enableDecline>true</enableDecline>
    <enableDeclineReason>true</enableDeclineReason>
    <enableRequestSound>true</enableRequestSound>
    <interruptibleCapacity>6</interruptibleCapacity>
    <label>Blended Voice and Case Agents</label>
    <maxExtensions>2</maxExtensions>
    <presenceStatusOnPushTimeout>Busy_Missed_Offer</presenceStatusOnPushTimeout>
</PresenceUserConfig>

Querying PresenceUserConfig and Assigned Users via SOQL

Both PresenceUserConfig and PresenceUserConfigUser / PresenceUserConfigProfile are queryable in SOQL.

1. Audit All Presence Configurations and Their Capacity Limits

SQL
SELECT Id, DeveloperName, MasterLabel, Capacity, InterruptibleCapacity,
       ShouldAutoAcceptEnabled, ShouldDeclineEnabled,
       PresenceStatusOnPushTimeoutId, PresenceStatusOnDeclineId
FROM PresenceUserConfig
ORDER BY MasterLabel ASC

2. List Users Assigned to a Specific PresenceUserConfig

SQL
SELECT Id, PresenceUserConfig.DeveloperName, User.Name, User.Username
FROM PresenceUserConfigUser
WHERE User.IsActive = true
ORDER BY PresenceUserConfig.DeveloperName, User.Name

Senior Architect Best Practices & Gotchas

Warning

Never Commit <assignments><users> to Git: If you assign individual users to a PresenceUserConfig in Setup and retrieve the metadata, Salesforce populates <assignments><users>jane@acme.com.sandbox</users></assignments>. Deploying that file to Production or another Sandbox will fail because the sandbox username does not exist. Always strip <assignments><users> from version control!

  • Always Configure presenceStatusOnPushTimeout: Without presenceStatusOnPushTimeout mapped to a busy/away ServicePresenceStatus, an agent who steps away from their computer with their Omni-Channel status set to Available will continuously receive and time out on every high-priority work item in the queue.

Frequently asked questions

What is the purpose of interruptibleCapacity on PresenceUserConfig?

Available in API v57.0+, interruptibleCapacity splits an agent's workload into primary (non-interruptible) and interruptible buckets so an agent working on asynchronous Cases or Leads can still receive real-time VoiceCall or MessagingSession requests.

Can enableAutoAccept and enableDecline both be set to true on a PresenceUserConfig?

No. Salesforce enforces that enableAutoAccept and enableDecline are mutually exclusive. If work items are automatically accepted when pushed to the agent, the agent cannot manually decline the push offer.

Why should you avoid hardcoding usernames inside PresenceUserConfig in SFDX?

Usernames inside the assignments.users block of a PresenceUserConfig are environment-specific and frequently fail deployment across Sandboxes. Assign PresenceUserConfig via profiles or automate user assignments separately.

How do you query PresenceUserConfig settings in SOQL?

You can query the PresenceUserConfig standard object in SOQL to inspect DeveloperName, MasterLabel, Capacity, InterruptibleCapacity, ShouldAutoAcceptEnabled, ShouldDeclineEnabled, and PresenceStatusOnPushTimeoutId.

Comments

Questions, corrections and tips are welcome. Comments are GitHub Discussions, so you sign in with GitHub.