Skip to content
  • FG-99
  • 12 min read
  • Last checked November 7, 2026

How to Handle a Data Access or Deletion Request With WordPress Export and Erase Personal Data Tools

Someone asked for a copy of their data or for it to be deleted. Run the request with WordPress tools, find the data they miss, and keep a record you can rely on.

Run the health check

An email arrives: “Under data protection law, please send me all the personal data you hold about me,” or “Please delete my data.” It might come from a former customer, a newsletter subscriber or someone who filled in your contact form once. You have a deadline, you want to do it properly, and you are not sure where your WordPress site even keeps their details.

WordPress has built-in tools for exactly this, under Tools, Export Personal Data and Erase Personal Data. They are good, but they only cover WordPress itself and the plugins that choose to plug into them. This guide shows you how to run a request end to end, find the data the tools miss, and keep a record. It is a practical guide, not legal advice: deadlines, exemptions and what you may keep vary by law, so check anything uncertain with a qualified adviser.

What is happening

WordPress treats every privacy request as a small workflow stored in the database. Each request is saved as a post of type user_request, with the requester’s email address in the title and the request type in the slug: export_personal_data or remove_personal_data. Its status moves through these stages.

Status Shown as Meaning
request-pending Pending Created; waiting for the person to click the link in the confirmation email.
request-confirmed Confirmed The person clicked the link, proving they control the address. The site admin gets a notification email.
request-failed Failed The confirmation link expired before it was used. By default links last 24 hours.
request-completed Completed You (or WordPress) marked it done after exporting or erasing.

The actual searching is done by exporters and erasers: small functions registered by WordPress core and by plugins. When you run an export, WordPress calls every registered exporter with the email address, collects what they return and builds a zip file. When you run an erasure, it calls every eraser.

Source Exporter Eraser
WordPress core: user profile (also session tokens and Community Events location) Yes No: the user account is not deleted
WordPress core: comments Yes Yes: comments are kept but author name, email, URL and user agent are cleared and the IP is anonymized
WordPress core: media uploaded by the user Yes (list of file URLs) No
WooCommerce: customer data, orders, downloads, payment tokens Yes Yes, subject to its settings
Other plugins Only if the plugin registers one Only if the plugin registers one

Anything outside WordPress, such as your inbox, mailing list service, CRM, accounting software, backups and server logs, is never touched by these tools.

Before you start

You need an administrator account (on multisite, a network admin). Take a full backup before any erasure, because erasing cannot be undone through WordPress. Do not test erasure on a real customer: test on your own address first.

Most steps use admin screens. Optional WP-CLI commands run over SSH in the site folder, the one that contains wp-config.php; your host may call the command wp or wp-cli. Make sure WordPress can send email (see the separate guide on WordPress not sending email if confirmation messages never arrive).

Note the date the request reached you, in writing. Under GDPR and UK GDPR the usual deadline is one month from receipt, extendable in some circumstances; other laws set their own timelines.

Step 1: Log the request and find the person’s data

Before touching any tool, write down who asked, when, what they asked for (a copy, deletion or both) and how they contacted you. Then find out where this person exists on your site.

Check for a user account

wp user get EMAIL_ADDRESS --fields=ID,user_login,user_registered,roles

Run this over SSH. Replace EMAIL_ADDRESS with the address from the request. wp user get accepts an ID, username or email; --fields limits the output. Good: a table with the user’s ID and role, telling you a WordPress account exists. An error saying the user is invalid means there is no account, which is normal for contact form senders and guest buyers.

Search every table for the address

wp db search 'EMAIL_ADDRESS' --all-tables-with-prefix --stats

Run this over SSH; it only reads. Replace EMAIL_ADDRESS with the address, keeping the quotes. --all-tables-with-prefix includes plugin tables that use your WordPress prefix; --stats adds a count of matches per table. Good output lists each table and column where the address appears, such as wp_comments:comment_author_email, a form plugin’s entries table, a newsletter plugin’s subscribers table or an email log table. This is your map of where the data lives. If a table appears that belongs to a plugin without an exporter, you will need to handle it by hand in Step 5. On a very large database, add a table name after the search term to limit it.

Step 2: Create the request in WordPress

Go to Tools, then Export Personal Data (for a copy) or Erase Personal Data (for deletion). Under “Add Data Export Request” or “Add Data Erasure Request”, enter the username or email address.

The confirmation email checkbox

Leave “Send personal data export confirmation email” (or the erasure equivalent) checked in most cases. WordPress emails the person a link; clicking it proves they control that address before you hand over or destroy anything. That protects against someone requesting another person’s data.

Uncheck it only if you have already verified identity another way, for example the request came from the same address while the person was logged into their account. Without the email, the request is created already confirmed.

If the link expires

Confirmation links are valid for 24 hours by default. If the person misses the window, the request shows as Failed. Check it in the list, choose “Resend confirmation requests” from Bulk actions, and apply. Tell the person to look out for the email and check spam.

When they confirm, WordPress emails the site admin and the status changes to Confirmed.

Step 3: Run the export

Once a request is Confirmed, hover over it in the Export Personal Data list. You can choose “Download personal data” to get the zip yourself, or “Send export link” to email the person a download link. The “Next steps” column offers the same options.

What is in the file

The zip contains index.html, a readable report grouped by source (User, Comments, Media, WooCommerce Orders and so on), and export.json with the same data in machine-readable form. Download it yourself first, even if you plan to send the link, and read it. Check that it contains only this person’s data and that nothing is obviously missing based on your Step 1 search.

The zip is stored in wp-content/uploads/wp-personal-data-exports/ under a randomized file name, and WordPress deletes export files older than three days on an hourly scheduled task. The emailed link will stop working after that.

Common export errors

  • “Unable to generate personal data export file. ZipArchive not available.”: the PHP zip extension is missing. Ask your host to enable it.
  • “Unable to create personal data export folder.”: WordPress cannot write to wp-content/uploads. Check folder permissions and free disk space.
  • The progress spinner never finishes: one exporter is failing. Open the browser DevTools Network tab, retry, and look at the failing admin-ajax.php response; it usually names the exporter or shows a PHP error. Check the PHP error log at the same time.

Add anything you found outside WordPress (Step 5) as a separate file or message, then mark the request complete: hover and click “Complete request”, or use the bulk action “Mark requests as completed”.

Step 4: Run the erasure

For a Confirmed erasure request, hover and choose “Erase personal data”. For a request still Pending, WordPress also offers “Force erase personal data”; use that only when you have verified identity some other way.

Read the result messages

Each eraser reports whether items were removed or retained, and may add messages explaining why something was kept. For example, WooCommerce may retain order data it is set to keep. Read every message and copy them into your record. When the request completes, WordPress emails the person that their erasure request has been fulfilled.

What erasure does not do

  • It does not delete the WordPress user account. If the person wants their account removed, delete it under Users. Choose whether to delete their posts or attribute them to another user.
  • It does not delete comments. It anonymizes them: the text stays, the author shows as “Anonymous”. If the comment text itself contains personal information, edit or delete it by hand.
  • It does not remove media files the user uploaded. Review them and delete any that identify the person.

To delete an account from the command line instead:

wp user delete USER_ID --reassign=NEW_AUTHOR_ID

Run this over SSH. USER_ID is the ID from Step 1. NEW_AUTHOR_ID is the ID of the account that should inherit their posts, found with wp user list. Without --reassign, the user’s posts are deleted with the account, so think before omitting it. Good output: “Success: Removed user”. If the account owns content you need, always reassign.

Step 5: Handle what the tools miss

This is where most incomplete responses come from.

Form plugin entries

If your Step 1 search found the address in a form entries table, check whether the form plugin supports the WordPress privacy tools. Gravity Forms, for example, has a per-form Personal Data setting that connects the form to the exporter and eraser and can set a retention policy. Other plugins may offer their own export or delete options in their entries screen, or none at all. Test with your own address: if the plugin’s data did not appear in your test export, it does not participate, and you must export or delete those entries in the plugin’s own screen.

WooCommerce

Go to WooCommerce, then Settings, then Accounts & Privacy. Under “Account erasure requests”, “Remove personal data from orders on request” decides whether an erasure request anonymizes order data; “Remove access to downloads on request” handles downloadable products. Under “Personal data removal”, “Allow personal data to be removed in bulk from orders” adds a bulk action in the orders list. The “Personal data retention” section sets how long inactive accounts and pending, failed, canceled, refunded and completed orders are kept before they are trashed or anonymized. Tax and accounting rules often require keeping order records for years, so agree those settings with your accountant or adviser before turning on removal from orders.

Newsletter, CRM and other services

Mailing list services, CRMs, booking systems and chat tools keep their own copies. Each has its own process for exporting or deleting a contact. Do it there and note what you did. For a newsletter, it is common to keep a suppressed or unsubscribed record so you do not email the person again; record why if you do.

Your inbox and email logs

Search your mailbox for the address: contact form notifications, replies and attachments. Delete or export as the request requires. If you use an SMTP or email logging plugin, its log table holds copies of messages sent to the person; it should have appeared in the Step 1 search.

Backups and logs

You usually cannot edit old backups. A common approach is to let them expire on their normal schedule and keep a record of erased addresses so that, if you ever restore a backup, you re-run the erasure. Server access logs record IP addresses rather than email addresses and are typically rotated automatically. Whether this approach satisfies the law that applies to you is a question for your adviser.

Step 6: Document the request

Keep a short record for every request, containing only what you need to show you handled it:

  • date received and how;
  • type of request and how identity was verified;
  • each system searched and what was found;
  • actions taken, including any data retained and the reason;
  • date you responded and how.

The completed request in the WordPress list is itself part of that record. List all requests over SSH:

wp post list --post_type=user_request --post_status=request-pending,request-confirmed,request-failed,request-completed --fields=ID,post_title,post_name,post_status,post_date

No placeholders here. --post_type=user_request selects privacy requests; --post_status lists all four request statuses; --fields shows the ID, email address (post_title), request type (post_name), status and date. Good output shows each request with a sensible status. Old Pending or Failed rows are abandoned requests you can follow up or delete with the bulk action “Delete requests”.

Advanced: checking which exporters and erasers are registered

Designers maintaining client sites can check exactly which plugins participate before a real request arrives. Over SSH, list registered exporters:

wp eval 'foreach ( apply_filters( "wp_privacy_personal_data_exporters", array() ) as $id => $e ) { echo $id, " : ", $e["exporter_friendly_name"], PHP_EOL; }'

This runs read-only PHP inside WordPress. wp eval executes the code after WordPress loads; the filter wp_privacy_personal_data_exporters is the same one the export screen uses. Good output lists IDs such as wordpress-user, wordpress-comments, wordpress-media and, on a shop, woocommerce-customer-orders, plus any plugin exporters. Swap the filter name for wp_privacy_personal_data_erasers and the key for eraser_friendly_name to list erasers. A plugin that stores personal data but is missing from both lists will need manual handling every time. Some plugins register only in the admin context; if one you expected is missing, confirm by running a test export on your own address.

Compare these lists with the tables found by wp db search on a test address. Any table with matches but no corresponding exporter is a gap. Write it into a per-site request checklist so whoever handles the next request knows to check that plugin manually.

Developers adding their own data stores can register exporters and erasers with the same filters; the WordPress Plugin Handbook documents the expected return format, including the done flag used for paging through large data sets.

When to contact your host

Open a ticket with your host if export files cannot be created (missing zip extension, permissions or disk space), if confirmation emails never send despite correct settings, or if you need to know how long backups and server logs are kept. Include:

  • the exact error text and the time you saw it, in UTC;
  • the relevant lines from the PHP error log around that time;
  • the result of a test export on your own address;
  • what you need: enabling the PHP zip extension, a permissions fix, or retention details for backups and logs.

For tools to check headers and email delivery, see the diagnostic tools page. If the site itself is broken, start at the Emergency Room.

Still stuck?

Print a free one-page checklist to keep, or open the Emergency Room if the symptom does not match.

Get the free checklists

Keep reading

All field guides
FG-116 Security

Scary Website Emails: Beg Bounties, Fake DMCA Notices and Renewal Scams

An email says your site has a vulnerability, broke copyright, is about to lose its domain or will be suspended. Most are scams, some are real. Verify each one by logging in to the real account yourself, never through the link in the email.

Read the guide
12 min read

Search the field manual

What is going wrong?

Press / to search from any page, Esc to close