caseHoldRules
Case Hold Rules. Query rules scoping what a case-hold policy preserves. The caseHoldRules entity set lives under /exchange/v1.0/caseHoldRules in the eDiscovery & audit category.
| Fact | Value |
|---|---|
| Path | /exchange/v1.0/caseHoldRules |
| Category | eDiscovery & audit |
| Tier | Tier 5, Compliance |
| Read role | Compliance.IPPS.Read.All (Community) |
| Write role | none (read-only) |
| Backing cmdlets | Get-CaseHoldRule, Set-CaseHoldRule, New-CaseHoldRule, Remove-CaseHoldRule |
Routes
Section titled “Routes”| Method | Path | Synopsis | Role | Plan |
|---|---|---|---|---|
| GET | /exchange/v1.0/caseHoldRules |
List caseHoldRules entries. | Compliance.IPPS.Read |
Community |
| POST | /exchange/v1.0/caseHoldRules |
Create a new caseHoldRules entry. Body keys map 1:1 to New-CaseHoldRule parameter names (camelCased). Required: name + policy (parent case-hold policy Name or GUID). Returns 201 + Location + the freshly-fetched rule. | Compliance.IPPS.ReadWrite |
Enterprise |
| GET | /exchange/v1.0/caseHoldRules/{key} |
Get a single caseHoldRules entry by Identity. | Compliance.IPPS.Read |
Community |
| PATCH | /exchange/v1.0/caseHoldRules/{key} |
Partial update of the caseHoldRules at /caseHoldRules/{key}. Body keys map 1:1 to Set-CaseHoldRule parameters. Returns 200 + the post-Set rule. | Compliance.IPPS.ReadWrite |
Enterprise |
| DELETE | /exchange/v1.0/caseHoldRules/{key} |
Remove the caseHoldRules at /caseHoldRules/{key}. Returns 204 with no body. | Compliance.IPPS.ReadWrite |
Enterprise |
GET /exchange/v1.0/caseHoldRules
Section titled “GET /exchange/v1.0/caseHoldRules”List caseHoldRules entries.
Backing cmdlet: Get-CaseHoldRule. Role: Compliance.IPPS.Read (Community).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
policy |
query | string | Scope to rules under a specific case-hold policy (policy Name or GUID). |
List case hold rules
Section titled “List case hold rules”Lists per-case hold rules via Get-CaseHoldRule on the IPPS pool. Each rule scopes a content query and date range under its parent caseHoldPolicy (the Policy field is the GUID back-pointer). Optional ?policy=<name|guid> narrows to one policy’s rules. Unlike caseHoldPolicies, list-all is allowed.
GET /exchange/v1.0/caseHoldRules HTTP/1.1Authorization: Bearer {token}HTTP/1.1 200 OK
{ "@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules(Id,Name,Mode,Disabled,Policy,Workload)", "value": [ { "Id": "contoso.com/Configuration/Q1 2026 Hold Policy", "Name": "Q1 2026 Hold Policy", "Policy": "policy-q1-2026-guid", "Disabled": false, "Mode": "Enforce", "Workload": "Exchange, SharePoint" }, { "Id": "contoso.com/Configuration/Litigation Houston Hold", "Name": "Litigation Houston Hold", "Policy": "policy-litigation-houston", "Disabled": false, "Mode": "Enforce", "Workload": "Exchange, SharePoint" } ]}Related: GET /exchange/v1.0/caseHoldPolicies/{key}, GET /exchange/v1.0/caseHoldRules/{key}
POST /exchange/v1.0/caseHoldRules
Section titled “POST /exchange/v1.0/caseHoldRules”Create a new caseHoldRules entry. Body keys map 1:1 to New-CaseHoldRule parameter names (camelCased). Required: name + policy (parent case-hold policy Name or GUID). Returns 201 + Location + the freshly-fetched rule.
Creates a rule scoped to a parent caseHoldPolicies entry, identified by the required policy field. The contentMatchQuery (KQL) narrows the hold to matching content; omit it to hold ALL content in the policy’s locations. Wiki gotcha: the rule-state toggle is disabled (Boolean), NOT enabled - opposite of how the parent policy works. disabled: false means the rule is active.IPPS-side - controller passes omitConfirm: true. Pass ?dryRun=true to map to -WhatIf.
Backing cmdlet: New-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
name |
body | yes | ||
policy |
body | yes | ||
comment |
body | |||
contentMatchQuery |
body | |||
disabled |
body | |||
dryRun |
query | bool (switch) |
Create a content-match rule for a case hold policy
Section titled “Create a content-match rule for a case hold policy”Create a new case hold rule via New-CaseHoldRule on the IPPS pool. Required: name + policy (parent caseHoldPolicies Name or GUID). Optional contentMatchQuery (KQL) narrows the hold to matching content; omit it to hold ALL content in the policy’s locations. Wiki gotcha: the rule-state toggle is disabled (Boolean) - NOT enabled like the parent policy. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.
POST /exchange/v1.0/caseHoldRules HTTP/1.1Authorization: Bearer {token}Content-Type: application/json
{ "name": "Q1-2026-Project-Apollo-Filter", "policy": "Q1-2026-Litigation-Hold", "comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.", "contentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01", "disabled": false}HTTP/1.1 201 CreatedLocation: /exchange/v1.0/caseHoldRules/Q1-2026-Project-Apollo-Filter
{ "@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity", "Id": "rule-apollo-guid", "Name": "Q1-2026-Project-Apollo-Filter", "Identity": "rule-apollo-guid", "Policy": "hold-q1-2026-litigation", "Disabled": false, "Mode": "Enforce", "ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01", "Comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.", "Workload": "Exchange, SharePoint", "Priority": 0, "WhenCreated": "2026-05-25T10:15:00Z", "WhenChanged": "2026-05-25T10:15:00Z"}Related: GET /exchange/v1.0/caseHoldRules?policy={policyId}, GET /exchange/v1.0/caseHoldRules/{key}, PATCH /exchange/v1.0/caseHoldRules/{key}, DELETE /exchange/v1.0/caseHoldRules/{key}, GET /exchange/v1.0/caseHoldPolicies/{policy}
GET /exchange/v1.0/caseHoldRules/{key}
Section titled “GET /exchange/v1.0/caseHoldRules/{key}”Get a single caseHoldRules entry by Identity.
Backing cmdlet: Get-CaseHoldRule. Role: Compliance.IPPS.Read (Community).
Get a case hold rule by Identity
Section titled “Get a case hold rule by Identity”Get a single case hold rule by Identity (Name or GUID). Backed by Get-CaseHoldRule on the IPPS pool. Use GET /caseHoldRules?policy={policyId} to discover rules under a specific parent caseHoldPolicies entry.
GET /exchange/v1.0/caseHoldRules/{key} HTTP/1.1Authorization: Bearer {token}HTTP/1.1 200 OK
{ "@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity", "Id": "rule-apollo-guid", "Name": "Q1-2026-Project-Apollo-Filter", "Identity": "rule-apollo-guid", "Policy": "hold-q1-2026-litigation", "Disabled": false, "Mode": "Enforce", "ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-10-01", "Comment": "Narrow the Q1 2026 hold to content tagged with the Project Apollo subject line.", "HoldContent": "All", "Workload": "Exchange, SharePoint", "Priority": 0, "CreatedBy": "John Woods", "LastModifiedBy": "John Woods", "WhenCreated": "2026-05-25T10:15:00Z", "WhenChanged": "2026-05-25T10:15:00Z", "WhenCreatedUTC": "2026-05-25T10:15:00Z", "WhenChangedUTC": "2026-05-25T10:15:00Z"}Related: GET /exchange/v1.0/caseHoldRules?policy={policyId}, PATCH /exchange/v1.0/caseHoldRules/{key}, DELETE /exchange/v1.0/caseHoldRules/{key}, GET /exchange/v1.0/caseHoldPolicies/{policy}
PATCH /exchange/v1.0/caseHoldRules/{key}
Section titled “PATCH /exchange/v1.0/caseHoldRules/{key}”Partial update of the caseHoldRules at /caseHoldRules/{key}. Body keys map 1:1 to Set-CaseHoldRule parameters. Returns 200 + the post-Set rule.
Use this endpoint to tune a rule post-creation - narrow / widen the KQL filter via contentMatchQuery, toggle the rule on/off via disabled, or amend the comment. The parent policy link is immutable after creation; to move a rule between policies, DELETE + re-POST. IPPS-side - controller passes omitConfirm: true.
Backing cmdlet: Set-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
comment |
body | |||
contentMatchQuery |
body | |||
disabled |
body | |||
dryRun |
query | bool (switch) |
Update a case hold rule
Section titled “Update a case hold rule”Partial update of the case hold rule at /caseHoldRules/{key} via Set-CaseHoldRule on the IPPS pool. Tune the rule post-creation: narrow or widen the KQL filter via contentMatchQuery, toggle the rule on/off via disabled (Boolean - disabled:false means active), or amend the comment. The parent policy link is immutable; to move a rule between policies, DELETE + re-POST. Returns 200 + the post-Set rule. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.
PATCH /exchange/v1.0/caseHoldRules/{key} HTTP/1.1Authorization: Bearer {token}Content-Type: application/json
{ "comment": "Updated by exonaut-sample automation: broadened scope to all Project Apollo correspondence.", "contentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-01-01", "disabled": false}HTTP/1.1 200 OKContent-Type: application/json
{ "@odata.context": "https://api.contoso.com/exchange/v1.0/$metadata#caseHoldRules/$entity", "Id": "exonaut-sample-caseHoldRules", "Name": "exonaut-sample-caseHoldRules", "Identity": "exonaut-sample-caseHoldRules", "Policy": "exonaut-sample-caseHoldPolicy", "Disabled": false, "Mode": "Enforce", "ContentMatchQuery": "subject:\"Project Apollo\" AND received>=2025-01-01", "Comment": "Updated by exonaut-sample automation: broadened scope to all Project Apollo correspondence.", "Workload": "Exchange, SharePoint", "Priority": 0, "WhenCreated": "2026-05-29T10:15:00Z", "WhenChanged": "2026-05-29T11:42:00Z"}Notes: Doc-derived from Wiki + write-param allowlist; not live-captured. Body fields are Wiki-valid; values are illustrative.
Related: GET /exchange/v1.0/caseHoldRules
DELETE /exchange/v1.0/caseHoldRules/{key}
Section titled “DELETE /exchange/v1.0/caseHoldRules/{key}”Remove the caseHoldRules at /caseHoldRules/{key}. Returns 204 with no body.
Rules don’t have their own distribution-pending state (only the parent caseHoldPolicies entry does), so no pre-DELETE guard is needed here. However, if the parent policy is currently in distributionStatus: “Pending”, the cmdlet may surface a related tenant-side error. Wait for the parent policy to settle, or retry distribution via PATCH on the parent policy.IPPS-side - omitConfirm: true. Note: this cmdlet uses -ForceDeletion (not the usual -Force); we don’t expose it in the surface - the standard DELETE flow covers the practical case.
Backing cmdlet: Remove-CaseHoldRule. Role: Compliance.IPPS.ReadWrite (Enterprise).
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
dryRun |
query | bool (switch) |
Delete a case hold rule
Section titled “Delete a case hold rule”Remove the case hold rule at /caseHoldRules/{key} via Remove-CaseHoldRule on the IPPS pool. Returns 204 with no body. Rules have no own distribution-pending state, but if the parent caseHoldPolicies entry is in distributionStatus ‘Pending’ the cmdlet may surface a related tenant-side error - wait for the parent policy to settle or retry distribution via PATCH on the parent policy. Tier 5 IPPS - backed by Compliance.IPPS.ReadWrite.All; the cmdlet ignores -Confirm so the controller omits it.
DELETE /exchange/v1.0/caseHoldRules/{key} HTTP/1.1Authorization: Bearer {token}Content-Type: application/jsonHTTP/1.1 204 No ContentNotes: Doc-derived from Wiki + write-param allowlist; not live-captured. Body fields are Wiki-valid; values are illustrative.
Related: GET /exchange/v1.0/caseHoldRules
?dryRun=true previews of any write stay on Community.

