# Personal Data Request Form Shortcode

> Adds a [privacy_request_form] shortcode where visitors can ask for a copy of their personal data or for its deletion. Requests go into WordPress's own privacy tools and the visitor confirms by email.

- Type: PHP
- Runs: Frontend only
- Category: [Privacy & Cookies](https://wpide.com/library/category/privacy/)
- Tags: gdpr, forms, shortcode
- Author: WPIDE Team
- Installs: 0
- Updated: 2026-10-28
- Page: https://wpide.com/library/privacy-data-request-form/

## Code

```php
add_action( 'template_redirect', function () {
    if ( empty( $_POST['wpide_privacy_request'] ) ) {
        return;
    }

    $back = wp_get_referer() ? wp_get_referer() : home_url( '/' );

    if ( ! isset( $_POST['_wpide_pr_nonce'] ) || ! wp_verify_nonce( sanitize_key( $_POST['_wpide_pr_nonce'] ), 'wpide_privacy_request' ) || ! empty( $_POST['wpide_website'] ) ) {
        wp_safe_redirect( add_query_arg( 'privacy_request', 'error', $back ) );
        exit;
    }

    $ip    = isset( $_SERVER['REMOTE_ADDR'] ) ? sanitize_text_field( wp_unslash( $_SERVER['REMOTE_ADDR'] ) ) : '';
    $rate  = 'wpide_pr_' . md5( $ip );
    $email = isset( $_POST['wpide_pr_email'] ) ? sanitize_email( wp_unslash( $_POST['wpide_pr_email'] ) ) : '';
    $type  = isset( $_POST['wpide_pr_type'] ) && 'remove' === $_POST['wpide_pr_type'] ? 'remove_personal_data' : 'export_personal_data';

    if ( (int) get_transient( $rate ) >= 3 || ! is_email( $email ) ) {
        wp_safe_redirect( add_query_arg( 'privacy_request', 'error', $back ) );
        exit;
    }

    set_transient( $rate, (int) get_transient( $rate ) + 1, HOUR_IN_SECONDS );
    $request_id = wp_create_user_request( $email, $type );

    if ( ! is_wp_error( $request_id ) ) {
        wp_send_user_request( $request_id );
    }

    // Same message whether or not a request already existed, so the form reveals nothing.
    wp_safe_redirect( add_query_arg( 'privacy_request', 'sent', $back ) );
    exit;
} );

add_shortcode( 'privacy_request_form', function () {
    $status = isset( $_GET['privacy_request'] ) ? sanitize_key( $_GET['privacy_request'] ) : '';
    $html   = '';

    if ( 'sent' === $status ) {
        $html .= '<p class="wpide-pr-msg" role="status">Thank you. Please check your inbox and click the confirmation link to complete your request.</p>';
    } elseif ( 'error' === $status ) {
        $html .= '<p class="wpide-pr-msg" role="alert">Your request could not be sent. Please check the email address and try again later.</p>';
    }

    $html .= '<form method="post" class="wpide-privacy-request">'
        . wp_nonce_field( 'wpide_privacy_request', '_wpide_pr_nonce', true, false )
        . '<p><label for="wpide-pr-email">Your email address</label><br><input type="email" id="wpide-pr-email" name="wpide_pr_email" required autocomplete="email"></p>'
        . '<fieldset><legend>What would you like us to do?</legend>'
        . '<label><input type="radio" name="wpide_pr_type" value="export" checked> Send me a copy of my personal data</label><br>'
        . '<label><input type="radio" name="wpide_pr_type" value="remove"> Delete my personal data</label></fieldset>'
        . '<p style="position:absolute;left:-9999px" aria-hidden="true"><label>Website <input type="text" name="wpide_website" tabindex="-1" autocomplete="off"></label></p>'
        . '<p><button type="submit" name="wpide_privacy_request" value="1">Send request</button></p></form>';

    return $html;
} );
```

## Notes

Handle the confirmed requests under Tools > Export Personal Data and Tools > Erase Personal Data; submissions are limited to 3 per hour per visitor.

## How to use it

Install the free WPIDE plugin (https://wordpress.org/plugins/wpide/), find "Personal Data Request Form Shortcode" in its snippet library and add it in one click; or create a new PHP snippet in WPIDE (or any code snippets plugin) and paste the code above. More snippets: https://wpide.com/library/
