HomeDev GuideAPI Reference
Dev GuideAPI ReferenceUser GuideGitHubNuGetDev CommunitySubmit a ticketLog In
GitHubNuGetDev CommunitySubmit a ticket

Content approvals

Describes the concepts for reviewing and approving content.

Approvals are a core system for the process of reviewing and approving. Specific approval types are built on top of this. The most common case is content approvals used in the editorial UI to review and approve content items before publishing, which is also the main reason the approval system exists. You can create custom approval types similar to how content approvals are defined, but this is currently not supported and is not covered here.


An approval is created when something needs reviewing (for example, a content item before publishing) and is connected to a definition. Multiple approvals can be created for each definition.

Running an approval is the process of stepping through the definition where each step's reviewers decide whether to approve or reject. Steps must be approved for the whole approval to be approved. If a step is rejected, then the whole approval is rejected.

A Uri-based reference identifies an approval, and it must have a definition.

A started approval is locked to the definition version that was the current version when the approval was started. It does not switch to a new definition version if the definition is changed, but new approvals will use the new version.

Approval definition

An approval definition is a series of steps to be approved in sequence. Each step has one or more reviewers. One reviewer in each step must approve the content before it is moved to the next step in the definition. If the site is multi-language, you can set the definition so that reviewers can approve different languages in a step.

Definitions are mostly static, and they are created and changed rarely.

A definition has a Uri-based reference to an object, usually a content item. A saved definition with a reference can be used for that reference and other references, such as a content item and its descendants. The resolve method searches for a definition and checks if a reference has access to a definition. In the case of content approvals, that means traversing the content tree upwards and looking for a definition.

Each time a definition is saved, a definition version is created. The latest saved version is the current definition and also the version returned when asking for a definition through IApprovalDefinitionRepository. It is also possible to get a specific version through the IApprovalDefinitionVersionRepository.

Content approval

The content approvals feature is accessed through the EPiServer.Approvals.ContentApprovals namespace, which gives access to content versions of the classes ApprovalDefinition and Approval, and also extension methods with ContentReferences in the repository interfaces. The ContentReference is converted to the Uri reference under the hood.



The methods in this namespace should only be used for content approvals. If another approval system for content is used that also wants to identify by ContentReference, it should have its own set of extension methods in its own namespace.

A definition can be created on a content item in a content tree and be used by the descendants of that content item. Use ResolveAsync to find a definition.



A content definition is shared for all versions/languages of a content item. Content approvals are created for a specific content version/language. That means it is possible to have multiple approvals for a content item running at the same time if they have different languages.

A content approval is started by setting the status of a content item to AwaitingApproval. The referenced content item is transitioned to status CheckedIn when content approval is approved. If rejected, the content item is transitioned to status Rejected.


Before CMS UI 10.10, a reviewer in an approval definition is a user's name. In release 10.10, Optimizely introduced a role reviewer, where a reviewer can be the user name or a role.

From CMS UI 11.8, you can implement the four-eyes principle. You can prevent users from approving their changes when configuring an approval sequence. The default value is false, letting users approve their changes.

When a user approves or rejects a content item, a validation is made to see if the user is part of the step, either as a user or as a member of a role. A call to the SecurityEntityProvider is used to validate if a user is part of a role. This will call the underlying user or role provider configured for the site (AspNet Identity Provider).



It is only the role name that is part of the definition, not the users in the role. The validation to see if a user is part of a role is made at the moment it is needed. This means that a user can be added to a role or removed from one and that will affect an already started approval.

The underlying user/role providers can have their own restrictions. For example, that the user must log in for the roles to update.

Approval flow

The normal state flow for a content version that is being approved is as follows:

  • CheckedOut – The editor has created a version that is being edited.
  • AwaitingApproval – The editor is done and marks the version ready for approval.
  • Rejected – If some reviewer does not approve the version, it transitions to Rejected. After the editor has made changes, it can be set for approval again.
  • CheckedIn – The version is approved and is ready for publishing.
  • Published – The version is published.