diff --git a/src/Umbraco.Core/Services/IContentQueryOperationService.cs b/src/Umbraco.Core/Services/IContentQueryOperationService.cs
new file mode 100644
index 0000000000..06bbaf06af
--- /dev/null
+++ b/src/Umbraco.Core/Services/IContentQueryOperationService.cs
@@ -0,0 +1,123 @@
+// src/Umbraco.Core/Services/IContentQueryOperationService.cs
+using Umbraco.Cms.Core.Models;
+using Umbraco.Cms.Core.Persistence.Querying;
+
+namespace Umbraco.Cms.Core.Services;
+
+///
+/// Service for content query operations (counting, filtering by type/level).
+///
+///
+///
+/// Implementation Note: Do not implement this interface directly.
+/// Instead, inherit from which provides required
+/// infrastructure (scoping, repository access, auditing). Direct implementation
+/// without this base class will result in missing functionality.
+///
+///
+/// This interface is part of the ContentService refactoring initiative (Phase 2).
+/// It extracts query operations into a focused, testable service.
+///
+///
+/// Versioning Policy: This interface follows additive-only changes.
+/// New methods may be added with default implementations. Existing methods will not
+/// be removed or have signatures changed without a 2 major version deprecation period.
+///
+///
+/// Version History:
+///
+/// - v1.0 (Phase 2): Initial interface with Count, GetByLevel, GetPagedOfType operations
+///
+///
+///
+/// 1.0
+public interface IContentQueryOperationService : IService
+{
+ #region Count Operations
+
+ ///
+ /// Counts content items, optionally filtered by content type.
+ ///
+ /// Optional content type alias to filter by. If the alias doesn't exist, returns 0.
+ /// The count of matching content items (includes trashed items).
+ int Count(string? contentTypeAlias = null);
+
+ ///
+ /// Counts published content items, optionally filtered by content type.
+ ///
+ /// Optional content type alias to filter by. If the alias doesn't exist, returns 0.
+ /// The count of matching published content items.
+ int CountPublished(string? contentTypeAlias = null);
+
+ ///
+ /// Counts children of a parent, optionally filtered by content type.
+ ///
+ /// The parent content id. If the parent doesn't exist, returns 0.
+ /// Optional content type alias to filter by. If the alias doesn't exist, returns 0.
+ /// The count of matching child content items.
+ int CountChildren(int parentId, string? contentTypeAlias = null);
+
+ ///
+ /// Counts descendants of an ancestor, optionally filtered by content type.
+ ///
+ /// The ancestor content id. If the ancestor doesn't exist, returns 0.
+ /// Optional content type alias to filter by. If the alias doesn't exist, returns 0.
+ /// The count of matching descendant content items.
+ int CountDescendants(int parentId, string? contentTypeAlias = null);
+
+ #endregion
+
+ #region Hierarchy Queries
+
+ ///
+ /// Gets content items at a specific tree level.
+ ///
+ /// The tree level (1 = root children, 2 = grandchildren, etc.).
+ /// Content items at the specified level, excluding trashed items.
+ IEnumerable GetByLevel(int level);
+
+ #endregion
+
+ #region Paged Type Queries
+
+ ///
+ /// Gets paged content items of a specific content type.
+ ///
+ /// The content type id. If the content type doesn't exist, returns empty results with totalRecords = 0.
+ /// Zero-based page index.
+ /// Page size.
+ /// Output: total number of matching records.
+ /// Optional filter query.
+ /// Optional ordering (defaults to sortOrder).
+ /// Paged content items.
+ /// Thrown when pageIndex is negative or pageSize is less than or equal to zero.
+ IEnumerable GetPagedOfType(
+ int contentTypeId,
+ long pageIndex,
+ int pageSize,
+ out long totalRecords,
+ IQuery? filter = null,
+ Ordering? ordering = null);
+
+ ///
+ /// Gets paged content items of multiple content types.
+ ///
+ /// The content type ids. If empty or containing non-existent IDs, returns empty results with totalRecords = 0.
+ /// Zero-based page index.
+ /// Page size.
+ /// Output: total number of matching records.
+ /// Optional filter query.
+ /// Optional ordering (defaults to sortOrder).
+ /// Paged content items.
+ /// Thrown when contentTypeIds is null.
+ /// Thrown when pageIndex is negative or pageSize is less than or equal to zero.
+ IEnumerable GetPagedOfTypes(
+ int[] contentTypeIds,
+ long pageIndex,
+ int pageSize,
+ out long totalRecords,
+ IQuery? filter = null,
+ Ordering? ordering = null);
+
+ #endregion
+}
diff --git a/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentQueryOperationServiceInterfaceTests.cs b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentQueryOperationServiceInterfaceTests.cs
new file mode 100644
index 0000000000..9f6bafed14
--- /dev/null
+++ b/tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentQueryOperationServiceInterfaceTests.cs
@@ -0,0 +1,30 @@
+// tests/Umbraco.Tests.UnitTests/Umbraco.Core/Services/ContentQueryOperationServiceInterfaceTests.cs
+using NUnit.Framework;
+using Umbraco.Cms.Core.Services;
+
+namespace Umbraco.Cms.Tests.UnitTests.Umbraco.Core.Services;
+
+[TestFixture]
+public class ContentQueryOperationServiceInterfaceTests
+{
+ [Test]
+ public void IContentQueryOperationService_Interface_Exists()
+ {
+ // Arrange & Act
+ var interfaceType = typeof(IContentQueryOperationService);
+
+ // Assert
+ Assert.That(interfaceType, Is.Not.Null);
+ Assert.That(interfaceType.IsInterface, Is.True);
+ }
+
+ [Test]
+ public void IContentQueryOperationService_Extends_IService()
+ {
+ // Arrange
+ var interfaceType = typeof(IContentQueryOperationService);
+
+ // Act & Assert
+ Assert.That(typeof(IService).IsAssignableFrom(interfaceType), Is.True);
+ }
+}