For a long time our demo bookings showed up in the CRM with a source of (direct). Someone read a Reddit answer, clicked through, booked a call, and as far as our data was concerned, fell out of the sky. We knew the off-page content was working. We could not prove which piece.
This is the writeup of the small thing we built to fix that. It is not clever. That is the point. Attribution does not need to be clever; it needs to actually fire on every booking.
The problem in one sentence
Calendly bookings landed in HubSpot with no campaign data, because the UTM parameters on the landing URL were not being carried through into the contact record. So every off-page channel collapsed into (direct), and we could not tell a Reddit-sourced demo from a Medium-sourced one from a podcast-sourced one.
The shape of the fix






