Breakdown of the SharePoint API for List Rules & Quick Steps

Rules & Quick Steps - quick intro

Quick Steps and Rules form a simple automation mechanism in SharePoint which can be used to perform actions like sending an email or setting a field value. Rules are triggerd by a list item event whilst Quick Steps are triggered by a button press. Rules allow you only to send an email or set a field value, but Quick Steps also allow you to start a Flow, or start a Teams chat.

Rules are the recommended replacement for Alerts which are being retired in July, 2026.

Rules and Quick Steps can often be used as a simple alternative where Microsoft Flow would otherwise be required. I believe Microsoft will continue to invest in this area since it’s quick and simple way to add automation - indeed, the new SharePoint Knowledge Agent integrates with them by automatically creating rules for you from a natural text request.

It turns out that Rules and Quick Steps share an API, and appear to be essentially the same thing on the backend - which makes sense, Quick Steps are simply rules where the trigger is a button press.

Retrieving

There’s a single API to retrieve both Rules and Quick Steps:

Request

POST $"/_api/web/lists(guid'{list.Id}')/GetAllRules()

{
	"includeQuicksteps":true,
	"includeAutomaticRules":true
}

The two parameters above are self explanatory - Quick Steps and Rules can be returned independently by toggling the values.

Response

In this response, we have one Quick Step and one Rule:

{
  "d": {
    "GetAllRules": {
      "__metadata": {
        "type": "Collection(SP.SPListRule)"
      },
      "results": [
        {
          "ActionParams": "{\"NotificationReceivers\":\"[{\\\"name\\\":\\\"Jonathan Cardy\\\",\\\"email\\\":\\\"jonathan@cardy2.onmicrosoft.com\\\",\\\"userId\\\":\\\"jonathan@cardy2.onmicrosoft.com\\\",\\\"rawData\\\":null}]\",\"CustomMessage\":\"'A 2026 item was updated!'\",\"ModifiedFieldInternalName\":\"PublishYear\"}",
          "ActionType": 0,
          "Condition": "[$PublishYear.NewValue] == '2026'",
          "CreateDate": "2025-09-23T06:44:33Z",
          "ID": "40f43cc4-854e-4768-a7b2-8741f612f2b8",
          "IsActive": true,
          "LastModifiedBy": null,
          "LastModifiedDate": "2025-09-23T06:44:33Z",
          "Outcome": "[{\"name\":\"Jonathan Cardy\",\"email\":\"jonathan@cardy2.onmicrosoft.com\",\"userId\":\"jonathan@cardy2.onmicrosoft.com\",\"rawData\":null}]",
          "Owner": "Jonathan Cardy",
          "RuleTemplateId": "40f43cc4-854e-4768-a7b2-8741f612f2b8",
          "Title": "When an item is modified, if Year changes and the new value is 2026, send an email to Jonathan Cardy",
          "TriggerType": 3
        },
        {
          "ActionParams": "{\"QuickstepTitle\":\"Start Work\",\"ItemData\":\"{\\\"Status\\\":{\\\"values\\\":[\\\"In Progress\\\"],\\\"valueType\\\":0}}\"}",
          "ActionType": 10002,
          "Condition": "[$Status] == 'New'",
          "CreateDate": "2025-09-23T08:49:09Z",
          "ID": "f92c6088-7265-4ee6-9960-3fada450050e",
          "IsActive": true,
          "LastModifiedBy": null,
          "LastModifiedDate": "2025-09-23T08:49:09Z",
          "Outcome": null,
          "Owner": "Jonathan Cardy",
          "RuleTemplateId": "f92c6088-7265-4ee6-9960-3fada450050e",
          "Title": "Show a command that will, for each selected item, if its Status is New, set the value in field Status to In Progress",
          "TriggerType": 5
        }
      ]
    }
  }
}

The following parameters are of interest:

  • Outcome is a JSON format indicating the parameters for that specific action. This is only used for rules, and is null for Quick Steps.
  • TriggerType is an enum outlined below.
  • ActionType is always 0 for Rules, and is a 5-digit value for Quick Steps as shown below.

Enumerations

enum TriggerType {
	ItemCreated = 0,
	ItemDeleted = 1,
	Unknown = 2, //This option doesn't seem to be present in the UX
	ItemModified = 3,
	ItemDateDeltaReached = 4
	QuickStepCommand = 5
}

enum ActionType {
	None = 0,
	ExecuteItemFlow = 10001, //Must set the FlowId value within ActionParams
	SetItemFieldValue = 10002, //Set ItemData in ActionParams
	DraftEmail = 10003, //Set email properties in ActionParams
	StartTeamsChat = 10004, //Set TeamsRecipients etc within ActionParams
	Unknown = 10005, //This option doesn't seem to be present in the UX
	ExecuteListFlow = 10006 //Execute a flow with the content of the list - set FlowId in ActionParams
}

Creating

A little frustratingly, the creation of a rule is in a different format than that of loaded rules above:

POST $"/_api/web/lists(guid'{list.Id}')/CreateRuleEx()

{
	"title": "When an item is modified, if PublishYear changes and the new value is 2026, send an email to Jonathan Cardy",
	"condition": "[$PublishYear.NewValue] == '2026'",
	"triggerType": 3, //item modified
	"action": {
		"ActionType": 0, //always 0 for rules - see enums above
		"ActionParams": {
		"results": [
			{
				"Key": "NotificationReceivers",
				"Value": "[{\"name\":\"Jonathan Cardy\",\"email\":\"jonathan@cardy2.onmicrosoft.com\",\"userId\":\"jonathan@cardy2.onmicrosoft.com\"}]",
				"ValueType": "String"
			},
			{
				"Key": "CustomMessage",
				"Value": "'A 2026 item was updated!'",
				"ValueType": "String"
			},
			{
				"Key": "ModifiedFieldInternalName",
				"Value": "PublishYear",
				"ValueType": "String"
			}
		]}
	}
}

Authentication

A SharePoint bearer access token is required. It must use an end-user identity which can be acquired with SharePoint Framework, PowerAutomate, PowerShell or another method of automation. It will not work if you use an application-identity token. The rule will be created - but it won’t do anything!!

Bonus - PnPCore extension methods

If you’re a .NET user, you can grab these extension methods and they’ll work as long as you’re referencing the PnPCore library (which provides a helpful ExecutePostAsync method).

Maybe some day, a kind soul will submit a PR to merge this functionality into PnPCore itself. Unfortunately, my time on this particular piece of work has run out.

public static ListRule[] GetListRules(this List list)
{
	list.EnsureProperty(l => l.Id);

	var responseString = list.ParentWeb.ExecutePostAsync($"/_api/web/lists(guid'{list.Id}')/GetAllRules()", "").GetAwaiter().GetResult();
	var response = JsonSerializer.Deserialize<GetAllListRulesResponse>(responseString);
	return response.value;
}


public static void AddListRule(this List list, ListRule rule)
{
	var serializeOptions = new JsonSerializerOptions
	{
		WriteIndented = true,
		Encoder = System.Text.Encodings.Web.JavaScriptEncoder.UnsafeRelaxedJsonEscaping
	};

	var createRequest = rule.GetCreateRequest();
	var requestJson = JsonSerializer.Serialize(createRequest, serializeOptions);

	list.EnsureProperty(l => l.Id);
	list.ParentWeb.ExecutePostAsync($"/_api/web/lists(guid'{list.Id}')/CreateRuleEx()",  requestJson, null, true).GetAwaiter().GetResult();
}

Data transfer object classes:

public class ListRuleCreateActionParamsResultItemRequest
{ 
	public string Key { get; set; }
	public string Value { get; set; }
	public string ValueType { get; set; }
}

public class ListRuleCreateActionParamsRequest
{
	public ListRuleCreateActionParamsResultItemRequest[] results { get; set; }
}

public class ListRuleCreateActionRequest
{
	public int ActionType { get; set; }
	public ListRuleCreateActionParamsRequest ActionParams { get; set; }
}

public class ListRuleCreateRequest
{
	public int triggerType { get; set; }
	public string title { get; set; }
	public string condition { get; set; }
	public ListRuleCreateActionRequest action { get; set; }
}

public partial class ListRule : BaseModel, IEquatable<ListRule>
{
	public string ActionParams { get; set; }
	public int ActionType { get; set; }
	public string Condition { get; set; }
	public bool IsActive { get; set; }
	public string Outcome { get; set; }
	public string Owner { get; set; }
	public string RuleTemplateId { get; set; }
	public string Title { get; set; }
	public int TriggerType { get; set; }

	public bool Equals(ListRule other)
	{
		//todo...
		return this.Title == other.Title;
	}

	public ListRuleCreateRequest GetCreateRequest()
	{
		List<ListRuleCreateActionParamsResultItemRequest> requestResultsItemValues = new List<ListRuleCreateActionParamsResultItemRequest>();

		//Convert the actionparams
		if(!string.IsNullOrEmpty(ActionParams))
		{
			foreach(var prop in System.Text.Json.JsonDocument.Parse(this.ActionParams).RootElement.EnumerateObject())
			{
				requestResultsItemValues.Add(new ListRuleCreateActionParamsResultItemRequest()
				{
					Key = prop.Name,
					Value = prop.Value.GetString(),
					ValueType = "String"
				});
			}
		}


		var request = new ListRuleCreateRequest()
		{
			condition = this.Condition,
			title = this.Title,
			triggerType = this.TriggerType,
			action = new ListRuleCreateActionRequest()
			{
				ActionType = this.ActionType,
				ActionParams = new ListRuleCreateActionParamsRequest()
				{
					results = requestResultsItemValues.ToArray()
				}
			}
		};


		return request;
	}
}

Summary

As you can see, List Rule and Quick Steps can be applied to lists automatically. For a managed provisioning and collaboration service which includes this functionality (and any other SharePoint feature you would need), contact us and we’ll give you a demo.