Marketing, Advertising & AdTech// definition

The data layer: a versioned contract between the people who ship the site and the people who measure it

In short

A data layer specification is a written interface: the exact event names, the parameters each carries, the type and requiredness of every one, an example payload, and a version with a stated breaking-change policy. Without it the data layer is still an API — just an API that 2 teams depend on and neither owns, which is why measurement breaks at every front-end rewrite.

Key takeaways

  • A data layer is an interface, not a convention. Treat it as an API with a version, an owner and a deprecation policy.
  • Each event needs 5 parts specified: name, required parameters with types, optional parameters, an example payload, and the version it conforms to.
  • Additive changes ship on any release. Renaming, retyping or redefining an event is breaking, and needs both shapes pushed in parallel.
  • Front-end owns the push, measurement owns the meaning, one named person owns the document. Shared ownership of a contract is no ownership.
  • A missing required parameter is a failed event, not a partial one — reject at the boundary and alert on the rejection rate.

A data layer specification is the document that turns a JavaScript object into an interface. It names each event, lists the parameters that event must carry, gives each one a type and a requiredness, shows a real example payload, and stamps the whole thing with a version and a rule about what may change without warning. The data layer is the object on the page; the specification is the contract about what is allowed to be in it.

Insist on that framing because of ownership. Front-end engineers write values into the object. Tag configuration and warehouse models read them out. Neither side compiles against the other, no test fails when the shapes drift, and no review catches a rename. That is an implicit API with 2 dependants and no owner, which is the specific reason tracking dies at a rebuild rather than degrading gracefully.

What one event's specification actually contains

The useful unit is a single event, fully specified. Anything shorter is a naming convention — a useful thing, but a different thing. A convention says event names are lower snake case. A specification says this event exists, carries these fields, and any consumer may rely on them.

ParameterTypeRequiredRule and failure behaviour
eventstring, enumYesOne of the declared names. An unrecognised value is dropped at the boundary and counted, never forwarded
transaction_idstringYesThe order id from the commerce back end, not a generated value. Stable across a refresh and a retry
valuenumberYesOrder total after discount, excluding shipping and tax unless stated here. Never a formatted string
currencystringYes3-letter currency code, required whenever value is present. A number with no currency is unusable
itemsarray of objectsYesAt least 1 element, each with item_id, item_name, price and quantity. item_id is the merchandising id
couponstringNoAbsent rather than empty when none applied. Empty string and absent must not both occur
schema_versionstringYesThe version this push conforms to. Consumers branch on it during a migration
Specification excerpt for one commerce event, schema version 2.3.0

The right-hand column is the part teams skip and the part that pays. "Required" with no stated failure behaviour is a preference; required with one is testable. An event missing transaction_id is rejected at the boundary, counted, and visible on a dashboard the same afternoon — a check that is cheap on day 1 and expensive to retrofit, which is why it belongs in the first sprint of the MVP and product builds that carry measurement.

The document also has to mark which fields carry joins rather than description. A campaign tag describes traffic; a click identifier is the value that lets a later sale find the ad that caused it, and the capture rules are in the parameters that tie a click to a sale. Consent is load-bearing in the same way, as a typed field on every event.

Why an undocumented data layer dies at every rebuild

A front-end rewrite does not set out to break measurement. It breaks measurement because the new codebase reimplements screens, not pushes. The component that fired the old event is gone, someone writes a replacement from what they can see in the network tab, and the field called value is now total. Each of those is a reasonable decision made without the contract in front of the person making it.

  • Renamed parameters. The value still exists, under a name nothing reads. Reports go flat rather than to zero, which delays discovery by weeks.
  • Retyped parameters. A number becomes a string, or an array becomes a comma-joined string. Sums quietly return 0 and nobody gets an error.
  • Timing changes. The push now happens after the tag reads the object, so events fire with stale values — the ordering defect behind tags firing before the banner gets an answer.
  • Meaning changes. The event name survives but fires on a different interaction. The worst case, because the data looks healthy and is wrong.

Meaning changes are the ones that end up in a room with a client. When the ad account and the warehouse stop agreeing, the resulting argument is mapped in the ad platform counting more conversions than you do, and a versioned specification is what lets you rule the data layer out in an hour rather than a fortnight. The pattern is general: wherever 2 systems count the same object independently, you close the gap with a declared record both sides read — the same move behind counts that come in lower than the exchange's.

An undocumented data layer is not a missing document. It is an API with two dependants, no owner, no version and no test — and it fails silently by design.

Versioning, and what counts as a breaking change

  1. Classify the change. Adding an event, or an optional parameter to one, is additive. Renaming, retyping, removing, promoting an optional field to required, or changing when an event fires is breaking.
  2. For a breaking change, push both shapes. The old event keeps firing alongside the new one, with schema_version telling them apart. This is the only expensive step, and the one that makes the rest safe.
  3. Give consumers a dated deadline — 2 release cycles, or 30 days, whichever your team actually honours. A deprecation with no date is a permanent parallel run.
  4. Remove the old shape only once every consumer has confirmed migration: tag configuration, warehouse models, any vendor reading the object directly.
  5. Record each change with its date and its reason. A version number is a claim about compatibility, not a changelog — if production does not conform to the version it declares, the marker is worse than nothing.

Who owns the document

Three roles, and they must not collapse into one. Front-end engineering owns the push — where in the lifecycle it fires and whether the values are right. Measurement owns the meaning — what an event represents and what a change costs downstream. One named person owns the document: the version, the deprecation dates, and the right to refuse a change that arrives with no parallel period.

  • Keep it in the application repository, not a wiki. It changes when the code changes, and a pull request is the only review that reliably happens.
  • Make it machine-readable. One JSON Schema per event can drive the boundary validation, the test fixtures and the human-readable table, so the 3 cannot drift.
  • If an agency operates the container, give the client the account and the agency the change rights — the split argued in who should own the tagging container.
  • Review it when a front-end project starts, not when it ships. The surrounding decisions sit under tracking, consent and event pipelines, in our marketing and advertising practice.

Frequently asked questions

Short answers to the follow-ups this page tends to raise.

What is a data layer specification?

It is a versioned document defining every event a site pushes: the event name, each parameter with its type and requiredness, an example payload, and the behaviour when a required parameter is missing. It exists so the people writing the pushes and the people reading them work against the same interface rather than against each other's assumptions.

Who should own the data layer, engineering or marketing?

Both, in different halves, with one named owner of the document. Front-end engineering owns the push — where it fires and whether the values are right. Measurement owns the meaning — what an event represents and what changing it costs downstream. The document needs a single owner with authority to reject a breaking change that arrives without a parallel period, because a contract owned by a committee gets edited by whoever is in a hurry.

What counts as a breaking change to a data layer?

Anything that changes what an existing consumer reads: renaming a parameter, changing its type, removing it, making an optional field required, or changing the interaction that triggers an event. Adding a new event or an optional parameter is additive and safe. The distinction decides the process — breaking changes need both shapes pushed in parallel and a dated deprecation.

  • data layer
  • measurement
  • event schema
  • front-end
// shipped work

The work behind this page

Builds from our portfolio that this page draws on.

Read next

Working on something in this space?

Tell us where you are in a sentence or two. We'll tell you honestly whether we're the right team, and what a sensible first slice of the work looks like.

Start the conversation