Skip to content

Security & SHA-256 PII Hashing

SignalRelay never sends a customer’s email, phone number or name to an advertising platform in plain text: each value is normalized and hashed with SHA-256 on your server first. Two things go out as they are, by design: the visitor’s IP address and browser user agent, which the platforms use for matching.

Customer information only exists when you map it: a Match row in the Event Builder, or the automatic field matching of the Elementor Forms integration (both Pro). Google Analytics 4 never receives customer information.


Before assembling the server-to-server payload:

  1. Email: Leading/trailing whitespace is trimmed, text is converted to lowercase, and a SHA-256 hash is computed: hash('sha256', strtolower(trim($email))).
  2. Phone: Every character that is not a digit is removed, leading zeros are dropped, and SHA-256 is applied. Meta receives the hash of the digits alone; TikTok receives the hash of the same digits with a + in front. Nothing validates a country code or adds one, so a number must include its own to match.
  3. Names: First and last names are converted to lowercase only, after trimming the ends. Punctuation and inner spaces are kept.
  4. City, state, ZIP and country: City and state are lowercased and everything that is not a letter or a digit is removed. A US ZIP+4 is cut to its first five digits, and any other postal code is lowercased with spaces and dashes removed. Country is lowercased.

A value that already looks like a SHA-256 hash (64 hexadecimal characters) is passed through unchanged.

Plaintext: " Client.Name@Company.COM "
Normalized: "client.name@company.com"
SHA-256: "5c4b90511928d47e682141d307f21bbacc20837afb918ae0ecaa871d9bf4df1c"
Phone typed: "+54 9 11 2233-4455"
Meta: sha256("5491122334455") = "c05486dc9903443d7733d5d5ea65735ea490867aea51d2922322135047f1f419"
TikTok: sha256("+5491122334455") = "81f0e3a8c199c04cdcf9753b542f83d4455880a1b34e658814e971c705be04a1"

Platforms use some identifiers as they are, so SignalRelay does not hash them: the visitor’s IP address and browser user agent, the anonymous first-party visitor ID, the platforms’ own click and browser IDs (_fbp, fbclid, ttclid), and the Facebook login ID if you map one.

Matching values you collect in the browser, such as a form’s email field, travel once, in plain text, to your own site’s tracking endpoint and are hashed there. No email, phone or name reaches an advertising platform in plain text.


SignalRelay never stores a plain-text email or phone number in your WordPress database. This is what it does keep:

  • The delivery queue. Conversions are not sent while the visitor waits: each one is queued as an Action Scheduler action, and that action holds the whole event. That means the event name and ID, the full page URL (with any query string and fragment), the hashed identifiers, the visitor’s IP address and user agent, the anonymous visitor ID and every custom data value. SignalRelay does not purge these rows itself; Action Scheduler does, by default 31 days after a completed action and about three months (93 days) after a failed one. You can change that, in seconds, with the action_scheduler_retention_period and action_scheduler_retention_period_for_failed filters.
  • The activity log. It keeps no matching values: only the event name, the outcome, the page URL without its query string or fragment, the timestamp, which matching parameters were present (never their values) and up to 12 custom data fields your rules send. Never map personal data into custom data.
  • Cookies. First-party and minimal: an anonymous visitor ID (365 days) and campaign attribution, meaning UTMs and click IDs (30 days).

Uninstalling. Deleting the plugin keeps your configuration by default. If you first switch on Delete data on uninstall (Settings → SignalRelay → Settings → Advanced), deleting the plugin also removes every queued, completed and failed delivery action of SignalRelay, together with its options and tables.