Title: wp_ajax_wp_privacy_erase_personal_data
Published: October 5, 2018
Last modified: August 20, 2026

---

# wp_ajax_wp_privacy_erase_personal_data()

## In this article

 * [Source](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#source)
 * [Hooks](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#hooks)
 * [Related](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#related)
 * [Changelog](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#changelog)

[ Back to top](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#wp--skip-link--target)

Handles erasing personal data via AJAX.

## 󠀁[Source](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#source)󠁿

    ```php
    function wp_ajax_wp_privacy_erase_personal_data() {

    	if ( empty( $_POST['id'] ) ) {
    		wp_send_json_error( __( 'Missing request ID.' ) );
    	}

    	$request_id = (int) $_POST['id'];

    	if ( $request_id < 1 ) {
    		wp_send_json_error( __( 'Invalid request ID.' ) );
    	}

    	// Both capabilities are required to avoid confusion, see `_wp_personal_data_removal_page()`.
    	if ( ! current_user_can( 'erase_others_personal_data' ) || ! current_user_can( 'delete_users' ) ) {
    		wp_send_json_error( __( 'Sorry, you are not allowed to perform this action.' ) );
    	}

    	check_ajax_referer( 'wp-privacy-erase-personal-data-' . $request_id, 'security' );

    	// Get the request.
    	$request = wp_get_user_request( $request_id );

    	if ( ! $request || 'remove_personal_data' !== $request->action_name ) {
    		wp_send_json_error( __( 'Invalid request type.' ) );
    	}

    	$email_address = $request->email;

    	if ( ! is_email( $email_address ) ) {
    		wp_send_json_error( __( 'Invalid email address in request.' ) );
    	}

    	if ( ! isset( $_POST['eraser'] ) ) {
    		wp_send_json_error( __( 'Missing eraser index.' ) );
    	}

    	$eraser_index = (int) $_POST['eraser'];

    	if ( ! isset( $_POST['page'] ) ) {
    		wp_send_json_error( __( 'Missing page index.' ) );
    	}

    	$page = (int) $_POST['page'];

    	/**
    	 * Filters the array of personal data eraser callbacks.
    	 *
    	 * @since 4.9.6
    	 *
    	 * @param array $args {
    	 *     An array of callable erasers of personal data. Default empty array.
    	 *
    	 *     @type array ...$0 {
    	 *         Array of personal data exporters.
    	 *
    	 *         @type callable $callback               Callable eraser that accepts an email address and a page
    	 *                                                number, and returns an array with boolean values for
    	 *                                                whether items were removed or retained and any messages
    	 *                                                from the eraser, as well as if additional pages are
    	 *                                                available.
    	 *         @type string   $exporter_friendly_name Translated user facing friendly name for the eraser.
    	 *     }
    	 * }
    	 */
    	$erasers = apply_filters( 'wp_privacy_personal_data_erasers', array() );

    	// Do we have any registered erasers?
    	if ( 0 < count( $erasers ) ) {

    		if ( $eraser_index < 1 ) {
    			wp_send_json_error( __( 'Eraser index cannot be less than one.' ) );
    		}

    		if ( $eraser_index > count( $erasers ) ) {
    			wp_send_json_error( __( 'Eraser index is out of range.' ) );
    		}

    		if ( $page < 1 ) {
    			wp_send_json_error( __( 'Page index cannot be less than one.' ) );
    		}

    		$eraser_keys = array_keys( $erasers );
    		$eraser_key  = $eraser_keys[ $eraser_index - 1 ];
    		$eraser      = $erasers[ $eraser_key ];

    		if ( ! is_array( $eraser ) ) {
    			/* translators: %d: Eraser array index. */
    			wp_send_json_error( sprintf( __( 'Expected an array describing the eraser at index %d.' ), $eraser_index ) );
    		}

    		if ( ! array_key_exists( 'eraser_friendly_name', $eraser ) ) {
    			/* translators: %d: Eraser array index. */
    			wp_send_json_error( sprintf( __( 'Eraser array at index %d does not include a friendly name.' ), $eraser_index ) );
    		}

    		$eraser_friendly_name = $eraser['eraser_friendly_name'];

    		if ( ! array_key_exists( 'callback', $eraser ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: %s: Eraser friendly name. */
    					__( 'Eraser does not include a callback: %s.' ),
    					esc_html( $eraser_friendly_name )
    				)
    			);
    		}

    		if ( ! is_callable( $eraser['callback'] ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: %s: Eraser friendly name. */
    					__( 'Eraser callback is not valid: %s.' ),
    					esc_html( $eraser_friendly_name )
    				)
    			);
    		}

    		$callback = $eraser['callback'];
    		$response = call_user_func( $callback, $email_address, $page );

    		if ( is_wp_error( $response ) ) {
    			wp_send_json_error( $response );
    		}

    		if ( ! is_array( $response ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Did not receive array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}

    		if ( ! array_key_exists( 'items_removed', $response ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Expected items_removed key in response array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}

    		if ( ! array_key_exists( 'items_retained', $response ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Expected items_retained key in response array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}

    		if ( ! array_key_exists( 'messages', $response ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Expected messages key in response array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}

    		if ( ! is_array( $response['messages'] ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Expected messages key to reference an array in response array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}

    		if ( ! array_key_exists( 'done', $response ) ) {
    			wp_send_json_error(
    				sprintf(
    					/* translators: 1: Eraser friendly name, 2: Eraser array index. */
    					__( 'Expected done flag in response array from %1$s eraser (index %2$d).' ),
    					esc_html( $eraser_friendly_name ),
    					$eraser_index
    				)
    			);
    		}
    	} else {
    		// No erasers, so we're done.
    		$eraser_key = '';

    		$response = array(
    			'items_removed'  => false,
    			'items_retained' => false,
    			'messages'       => array(),
    			'done'           => true,
    		);
    	}

    	/**
    	 * Filters a page of personal data eraser data.
    	 *
    	 * Allows the erasure response to be consumed by destinations in addition to Ajax.
    	 *
    	 * @since 4.9.6
    	 *
    	 * @param array  $response        {
    	 *     The personal data for the given exporter and page number.
    	 *
    	 *     @type bool     $items_removed  Whether items were actually removed or not.
    	 *     @type bool     $items_retained Whether items were retained or not.
    	 *     @type string[] $messages       An array of messages to add to the personal data export file.
    	 *     @type bool     $done           Whether the eraser is finished or not.
    	 * }
    	 * @param int    $eraser_index    The index of the eraser that provided this data.
    	 * @param string $email_address   The email address associated with this personal data.
    	 * @param int    $page            The page number for this response.
    	 * @param int    $request_id      The privacy request post ID associated with this request.
    	 * @param string $eraser_key      The key (slug) of the eraser that provided this data.
    	 */
    	$response = apply_filters( 'wp_privacy_personal_data_erasure_page', $response, $eraser_index, $email_address, $page, $request_id, $eraser_key );

    	if ( is_wp_error( $response ) ) {
    		wp_send_json_error( $response );
    	}

    	wp_send_json_success( $response );
    }
    ```

[View all references](https://developer.wordpress.org/reference/files/wp-admin/includes/ajax-actions.php/)
[View on Trac](https://core.trac.wordpress.org/browser/tags/7.1/src/wp-admin/includes/ajax-actions.php#L5154)
[View on GitHub](https://github.com/WordPress/wordpress-develop/blob/7.1/src/wp-admin/includes/ajax-actions.php#L5154-L5383)

## 󠀁[Hooks](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#hooks)󠁿

 [apply_filters( ‘wp_privacy_personal_data_erasers’, array $args )](https://developer.wordpress.org/reference/hooks/wp_privacy_personal_data_erasers/)

Filters the array of personal data eraser callbacks.

 [apply_filters( ‘wp_privacy_personal_data_erasure_page’, array $response, int $eraser_index, string $email_address, int $page, int $request_id, string $eraser_key )](https://developer.wordpress.org/reference/hooks/wp_privacy_personal_data_erasure_page/)

Filters a page of personal data eraser data.

## 󠀁[Related](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#related)󠁿

| Uses | Description | 
| [wp_get_user_request()](https://developer.wordpress.org/reference/functions/wp_get_user_request/)`wp-includes/user.php` |

Returns the user request object for the specified request ID.

  | 
| [is_email()](https://developer.wordpress.org/reference/functions/is_email/)`wp-includes/formatting.php` |

Verifies that an email is valid.

  | 
| [current_user_can()](https://developer.wordpress.org/reference/functions/current_user_can/)`wp-includes/capabilities.php` |

Returns whether the current user has the specified capability.

  | 
| [__()](https://developer.wordpress.org/reference/functions/__/)`wp-includes/l10n.php` |

Retrieves the translation of $text.

  | 
| [esc_html()](https://developer.wordpress.org/reference/functions/esc_html/)`wp-includes/formatting.php` |

Escaping for HTML blocks.

  | 
| [check_ajax_referer()](https://developer.wordpress.org/reference/functions/check_ajax_referer/)`wp-includes/pluggable.php` |

Verifies the Ajax request to prevent processing requests external of the blog.

  | 
| [wp_send_json_error()](https://developer.wordpress.org/reference/functions/wp_send_json_error/)`wp-includes/functions.php` |

Sends a JSON response back to an Ajax request, indicating failure.

  | 
| [wp_send_json_success()](https://developer.wordpress.org/reference/functions/wp_send_json_success/)`wp-includes/functions.php` |

Sends a JSON response back to an Ajax request, indicating success.

  | 
| [apply_filters()](https://developer.wordpress.org/reference/functions/apply_filters/)`wp-includes/plugin.php` |

Calls the callback functions that have been added to a filter hook.

  | 
| [is_wp_error()](https://developer.wordpress.org/reference/functions/is_wp_error/)`wp-includes/load.php` |

Checks whether the given variable is a WordPress Error.

  |

[Show 8 more](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#)
[Show less](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#)

## 󠀁[Changelog](https://developer.wordpress.org/reference/functions/wp_ajax_wp_privacy_erase_personal_data/?output_format=md#changelog)󠁿

| Version | Description | 
| [4.9.6](https://developer.wordpress.org/reference/since/4.9.6/) | Introduced. |

## User Contributed Notes

You must [log in](https://login.wordpress.org/?redirect_to=https%3A%2F%2Fdeveloper.wordpress.org%2Freference%2Ffunctions%2Fwp_ajax_wp_privacy_erase_personal_data%2F)
before being able to contribute a note or feedback.