diff --git a/includes/class-delete-all.php b/includes/class-delete-all.php
index 01390885d97eccacaa480ad820f6961a5392810b..261bf5e6e61dd282a7a24ae1cc7c0244ba6d8fa5 100644
--- a/includes/class-delete-all.php
+++ b/includes/class-delete-all.php
@@ -14,6 +14,7 @@ class Delete_All {
 	 * Register this bulk process' hooks
 	 */
 	public static function register_hooks() {
+		add_action( Main::build_hook( 'delete_all' ), array( __CLASS__, 'process' ) );
 		add_action( self::CRON_EVENT, array( __CLASS__, 'process_via_cron' ) );
 
 		add_action( 'admin_notices', array( __CLASS__, 'admin_notices' ) );
diff --git a/includes/class-main.php b/includes/class-main.php
index 47dbee56b0011745ba2fe05e1052082acac27033..9468582ac1368875587cf637e1533307e52b3818 100644
--- a/includes/class-main.php
+++ b/includes/class-main.php
@@ -3,6 +3,11 @@
 namespace Automattic\WP\Bulk_Edit_Cron_Offload;
 
 class Main {
+	/**
+	 * Prefix for bulk-process hook invoked by request-specific classes
+	 */
+	const ACTION = 'a8c_bulk_edit_cron_';
+
 	/**
 	 * Register action
 	 */
@@ -23,39 +28,19 @@ class Main {
 		check_admin_referer( 'bulk-posts' );
 
 		// Parse request to determine what to do
-		$vars = self::capture_vars();
-
-		// Now what?
-		switch ( $vars->action ) {
-			case 'delete_all' :
-				self::skip_core_processing();
-
-				Delete_All::process( $vars );
-				break;
+		$vars   = self::capture_vars();
+		$action = self::build_hook( $vars->action );
 
-			case 'trash' :
-				return;
-				break;
-
-			case 'untrash' :
-				return;
-				break;
-
-			case 'delete' :
-				return;
-				break;
-
-			case 'edit' :
-				return;
-				break;
+		if ( ! self::bulk_action_allowed( $vars->action ) ) {
+			return;
+		}
 
-			// Should only arrive here if loaded on the wrong admin screen
-			default :
-				error_log( var_export( get_current_screen(), true ) );
-				error_log( var_export( wp_debug_backtrace_summary( __CLASS__, null, false ), true ) );
+		// Pass request to a class to handle offloading to cron, UX, etc
+		do_action( $action, $vars );
 
-				return;
-				break;
+		// Only skip Core's default handling when
+		if ( has_action( $action ) ) {
+			self::skip_core_processing();
 		}
 	}
 
@@ -132,6 +117,34 @@ class Main {
 		return $vars;
 	}
 
+	/**
+	 * Validate action
+	 *
+	 * @param  string $action Action parsed from request vars
+	 * @return bool
+	 */
+	public static function bulk_action_allowed( $action ) {
+		$allowed_actions = array(
+			'delete',
+			'delete_all',
+			'edit',
+			'trash',
+			'untrash',
+		);
+
+		return in_array( $action, $allowed_actions, true );
+	}
+
+	/**
+	 * Build a WP hook specific to a bulk request
+	 *
+	 * @param  string $action Bulk action to offload
+	 * @return string
+	 */
+	public static function build_hook( $action ) {
+		return self::ACTION . $action;
+	}
+
 	/**
 	 * Unset flags Core uses to trigger bulk processing
 	 */