Appendix B

THE DATA CONTRACT

Agree it with engineering before the first property is written.

The rules are written against Klaviyo. They hold on any platform that keeps profile state and event history apart.

For the founder, three symptoms that mean this work wasn't done: a segment that should hold thousands holds eleven; a flow fires twice; a count shrinks after a release.

Each one looks like a marketing problem and starts in the data layer. Data failures don't throw errors. They produce a number slightly too low or a flow that fires slightly too often. The strategy gets blamed and rewritten while the plumbing stays broken.

Five rules

  1. Write state and history bothA profile property holds the current value and is overwritten on each write. An event records what happened and when. Segments and merge tags read properties; flows trigger on events. Most values need both, written from the same payload.
  2. Namespace the namesCase matters: "Properties and their values must be exactly the same across your account." Name profile properties in Title Case with a source prefix (Quiz Skin Type) and event properties in snake_case (skin_type). Keep profile and event property names distinct so nobody can confuse them in the segment builder.
  3. Guard the writeWrite set-once fields, like a holdout bucket or a first-order date, only when they're empty. A sync that rewrites them on every run reshuffles the data and throws no error. Enforce allowed values in application code.
  4. Make two calls in orderKlaviyo won't subscribe a profile and edit its custom properties in one API request. Subscribe first, per channel, with the source, and check the response. Then write the properties and fire the event. Log each failure with its identifier and retry from a queue.
  5. Check it in the platformKlaviyo's event endpoints answer 202 Accepted before the work is done. Check the profile. A test passes when you find the profile and see the event and the property on it.

The merge test

Identity decides whether any of this reaches a person. Run the merge test in a clean browser before each release that touches the header, checkout or account system. Browse anonymously, submit a test email through a form, log in with the same address and complete a paid checkout. Search for the address. One profile carrying all four stages passes; two or three fail.

A failed test means your flows fire at the copy with no purchase history and your segments count one person several times. Put the tracking script on every page, including subdomains and iframes. Normalize phone numbers to E.164 at capture. Don't ask a visitor who clicked through from your email for their address again, because a different answer forks a second profile.

Change an existing profile's email or phone server-side. Klaviyo's browser-side endpoints return 202 for an identifier change and leave the field as it was.

The register

Read it by symptom when a number moves and nobody can explain it. Read it by control when you build, because each control costs a field on day one and a migration on day ninety.

This is one chapter of The Second Order, which is free and readable in full on a single page with no form in front of it.