Email PHP Intermediate

BCC All Outgoing WordPress Emails

Last updated: May 6, 2026

WordPress sends a significant amount of transactional email: new user registrations, password resets, order confirmations, shipping notifications, form submissions, and more. On complex sites it can be surprisingly difficult to know exactly what email a user received and when, especially when multiple plugins are generating their own email flows. Adding a BCC to all outgoing mail gives you a complete audit trail of everything sent from your site, delivered to a single inbox you control.

This is particularly useful during development and testing, when debugging a broken email flow, when onboarding clients and needing to verify their transactional emails are working, or for ongoing compliance monitoring on sites with regulatory requirements.

The Code

Add this to your functions.php or a site-specific plugin. Replace audit@nahnuplugins.com with the address you want to receive the blind copies. The filter intercepts the full arguments array passed to wp_mail() before it’s dispatched.

How wp_mail Headers Work

The wp_mail filter receives an array with five keys: to, subject, message, headers, and attachments. The headers value is the tricky one, WordPress and various plugins pass it either as a string (with headers separated by
or
) or as an array of header strings. The snippet handles both cases by normalising the headers to an array before appending the BCC line.

The array_filter() call strips any empty entries that may result from splitting a string with trailing newlines, keeping the headers array clean.

Use Cases

During development, point the BCC at a shared team inbox or a mail testing service like Mailtrap. Every email the site sends, to real users, test accounts, or placeholder addresses, lands in one place for review. This is faster than checking multiple inboxes or recreating specific user flows to trigger emails.

For compliance use cases, the BCC address can feed into an email archiving service that stores a legally defensible record of all communications. Financial services, healthcare, and legal sectors often have record-keeping requirements that make this kind of audit trail mandatory.

For client sites in the support phase, a BCC to your agency’s inbox lets you proactively spot broken email flows, for example, a password reset email that never arrives because an SMTP configuration broke, before a client reports it.

Privacy and Volume Considerations

BCCing all outgoing mail means the audit address receives copies of password reset emails, which contain reset links. Treat this address with appropriate security, it should not be a shared inbox with broad access, and the emails it receives should be retained only as long as necessary. On high-traffic sites, the volume can be substantial; make sure the receiving mailbox or archiving service can handle the load without bouncing or throttling.

Removing in Production

If you add this snippet for a debugging session, remember to remove it when done. A permanent BCC on all mail is intentional on some sites but should always be a deliberate, documented decision rather than a forgotten filter from a troubleshooting session.

functions.php
add_filter( 'wp_mail', function( $args ) {
    $bcc_address = 'audit@nahnuplugins.com';

    // Normalise headers to an array
    if ( is_string( $args['headers'] ) ) {
        $args['headers'] = array_filter( explode( "\n", str_replace( "\r\n", "\n", $args['headers'] ) ) );
    }
    if ( ! is_array( $args['headers'] ) ) {
        $args['headers'] = [];
    }

    $args['headers'][] = 'Bcc: ' . $bcc_address;

    return $args;
} );

Built by Nahnu Plugins

Need something more powerful than a snippet?

Our commercial plugins go further, built for serious WordPress sites with full support, updates, and documentation included.

Browse All Plugins →

This website uses cookies to enhance your browsing experience and ensure the site functions properly. By continuing to use this site, you acknowledge and accept our use of cookies.

Accept All Accept Required Only