The AssignmentRules metadata type represents automated routing rules for Lead and Case records. Introduced in API version 27.0, AssignmentRules evaluates an ordered list of <ruleEntry> blocks from top to bottom and assigns the record’s OwnerId (and optional Case Team or notification email template) to the first matching Queue or User.
In Salesforce DX projects, assignment rules are stored per object in force-app/main/default/assignmentRules/Case.assignmentRules-meta.xml and Lead.assignmentRules-meta.xml.
Key Fields on AssignmentRule and RuleEntry
| Field | Location | Required | Description |
|---|---|---|---|
fullName |
assignmentRule |
Yes | Name of the assignment rule |
active |
assignmentRule |
No | Only one rule per object (Lead or Case) can have <active>true</active> at a time |
ruleEntry |
assignmentRule |
No | Ordered array of routing entries evaluated sequentially |
assignedTo |
ruleEntry |
No | Developer name of the target Queue or username of the target User |
assignedToType |
ruleEntry |
No | Queue (recommended for CI/CD) or User |
criteriaItems |
ruleEntry |
Conditional | Field filter conditions (field, operation, value)—mutually exclusive with formula |
booleanFilter |
ruleEntry |
No | Filter logic combining criteriaItems (such as 1 AND (2 OR 3)) |
formula |
ruleEntry |
Conditional | Formula expression evaluating to true/false—mutually exclusive with criteriaItems |
template |
ruleEntry |
No | Folder/name of the Classic Email Template sent to the new owner |
team |
ruleEntry |
No | Predefined Case Team name(s) added to the Case |
overrideExistingTeams |
ruleEntry |
No | Replaces (true) or appends (false) existing Case Teams |
Production-Grade XML Example (Case.assignmentRules-meta.xml)
Below is a CI/CD-friendly Case assignment rule (force-app/main/default/assignmentRules/Case.assignmentRules-meta.xml) that routes critical cases to an engineering queue and falls back to a general triage queue:
<?xml version="1.0" encoding="UTF-8"?>
<AssignmentRules xmlns="http://soap.sforce.com/2006/04/metadata">
<assignmentRule>
<fullName>Global_Support_Case_Routing</fullName>
<active>true</active>
<ruleEntry>
<assignedTo>Tier_3_Engineering_Queue</assignedTo>
<assignedToType>Queue</assignedToType>
<booleanFilter>1 AND 2</booleanFilter>
<criteriaItems>
<field>Case.Priority</field>
<operation>equals</operation>
<value>Critical,High</value>
</criteriaItems>
<criteriaItems>
<field>Case.Origin</field>
<operation>equals</operation>
<value>Web,API</value>
</criteriaItems>
<overrideExistingTeams>false</overrideExistingTeams>
</ruleEntry>
<ruleEntry>
<assignedTo>Tier_1_General_Support_Queue</assignedTo>
<assignedToType>Queue</assignedToType>
<formula>TRUE</formula>
<overrideExistingTeams>false</overrideExistingTeams>
</ruleEntry>
</assignmentRule>
</AssignmentRules>Triggering AssignmentRules in Apex via Database.DMLOptions
A classic Salesforce interview question and production bug: inserting a Lead or Case in Apex does not trigger active Assignment Rules by default. You must attach Database.DMLOptions:
public with sharing class InboundCaseIntakeService {
public static Id createRoutedCase(String subject, String priority) {
AssignmentRule activeRule = [
SELECT Id
FROM AssignmentRule
WHERE SobjectType = 'Case' AND Active = true
WITH SYSTEM_MODE
LIMIT 1
];
Database.DMLOptions dmlOpts = new Database.DMLOptions();
dmlOpts.assignmentRuleHeader.assignmentRuleId = activeRule.Id;
// Alternatively: dmlOpts.assignmentRuleHeader.useDefaultRule = true;
Case newCase = new Case(
Subject = subject,
Priority = priority,
Origin = 'API'
);
newCase.setOptions(dmlOpts);
insert as user newCase;
return newCase.Id;
}
}Querying AssignmentRule with SOQL
-- List all Lead and Case AssignmentRules and verify which rule is currently active
SELECT Id, Name, SobjectType, Active, LastModifiedDate
FROM AssignmentRule
ORDER BY SobjectType, Active DESC, Name ASCFrequently asked questions
Which Salesforce objects support AssignmentRules metadata?
Only two standard objects support AssignmentRules metadata: Lead (Lead.assignmentRules-meta.xml) and Case (Case.assignmentRules-meta.xml).
What is the difference between AssignmentRules and AssignmentRule in package.xml?
Use AssignmentRules with member Case or Lead to retrieve all assignment rules for that object in a single file. Use the singular AssignmentRule with member Case.RuleName to retrieve or deploy one specific named rule.
Why do my active AssignmentRules not fire when Leads or Cases are inserted via Apex?
By default, Apex DML does not run active AssignmentRules unless you explicitly set Database.DMLOptions dmlOpts = new Database.DMLOptions(); dmlOpts.assignmentRuleHeader.useDefaultRule = true; and call record.setOptions(dmlOpts) or Database.insert(records, dmlOpts).
How are ruleEntry blocks evaluated inside an AssignmentRule?
Salesforce evaluates ruleEntry blocks strictly in top-to-bottom XML order and stops at the first ruleEntry whose criteriaItems or formula evaluates to true.
Why should I assign records to a Queue rather than a User inside AssignmentRules?
Assigning to a User requires hardcoding an org-specific username in assignedTo, which breaks deployments across sandboxes and scratch orgs. Assigning to a Queue uses an environment-independent Queue developer name.
Comments
Questions, corrections and tips are welcome. Comments are GitHub Discussions, so you sign in with GitHub.