One event, many destinations: what changes per platform
Sending the same conversion to five platforms looks like copy and paste. It is not: each has its own hashing rule, identity format and event naming — and one of them does the opposite of all the others.

Once server-side sending to Meta works, the natural next question is sending the same event to the other platforms. It looks like copy and paste with a different URL. It is not — and the differences are not cosmetic.
What follows is the map of divergences that actually break integrations, gathered by implementing the destinations one by one.
What to hash, and what not to
The Meta family rule is well known: identity goes in sha256, never in clear text. It is natural to assume this holds everywhere. It does not, in two opposite directions.
| Platform | Identity | The catch |
|---|---|---|
| Meta, TikTok, Snapchat, Pinterest | sha256 | Each hashes a different set of fields |
| sha256, including IP and user agent | The inverse of the Meta family, which sends both in clear | |
| Microsoft Ads | sha256, with its own normalisation | Strips dots and plus-aliases from the email before hashing |
| Klaviyo, HubSpot, Customer.io | Clear text | Hashing breaks the integration: the email is the product there |
The last row usually surprises people. A marketing tool is not an ad platform: it needs a readable email to send the message. Hashing is an ad auction rule, not a communication rule.
There is no universal hashing rule. There is one rule per destination, and it needs to be declared on the destination — not buried in the code that assembles the send.
Event names do not travel unchanged
A purchase is Purchase on Meta, and the same concept has another name or another shape elsewhere. Pinterest expects lowercase names and calls a purchase checkout. LinkedIn does not work with event names at all: you reference a conversion identifier created in the account. TikTok lives with two different API shapes, one of them inherited.
The classic mistake here is silent: sending a name the platform does not recognise is usually accepted as a custom event. Nothing fails, and the conversion simply never appears where you expect it.
The shape of identity
After the name comes the form. Pinterest expects identity fields as arrays, even with a single value. LinkedIn expects typed identifiers, with the type declared next to the value, and time in milliseconds rather than seconds.
And there is a behavioural difference that changes the maths: LinkedIn discards an event that arrives with no identity at all. On Meta, that event is accepted and simply does not match. In both cases you get no attribution, but only in one of them do you find out.
What to do about it
The practical conclusion is not to avoid destinations. It is to separate two things that usually ship glued together: assembling the event, and the destination's rules.
- The event is assembled once, with the full identity and the business fields.
- Each destination declares what it accepts, what it hashes and how it names things — and the send applies that declaration.
- A new event name goes through a known list, so it does not become a custom event by accident.
- A destination that discards identity-less events has to report the discard, not swallow it.
With those four in place, adding a destination is filling in a declaration. Without them, every new destination is an integration from scratch — and each one ages on its own.
In CrazyLeads each destination declares its own contract: the accepted payload and the hashing rule per field name. The send itself is shared, which is why there are now more than twenty server-side destinations running on the same machinery.