Register your interest: Tag @Cody, get an agent
BlogEngineering

Mixpanel and CodeWords: the taxonomy decides everything

Event naming that survives contact with three teams, identity resolution before and after sign-up, and why a Mixpanel number and a database number will never quite agree.

Rebecca PearsonRebecca Pearson11 min read

Summarize with AI

Mixpanel and CodeWords: the taxonomy decides everything
On this page

Product analytics fails for organisational reasons far more often than technical ones. The tracking works; what breaks is that three teams named similar events differently over two years, nobody wrote down what any of them means, and the person who could explain the discrepancy has left.

So the useful automation around Mixpanel is mostly about the taxonomy — keeping it consistent, catching it when it drifts, and making the definitions visible — rather than about moving data around.

What we'll cover

Taxonomy, which is the whole game

Five rules, and a project's analytics usefulness is largely decided by whether they were followed from the start.

Object then action, consistently. "Project Created", "Invite Sent". Pick one order and apply it, because a project with both "Created Project" and "Invite Sent" is already inconsistent.

Properties, not event names, carry variation. One "Button Clicked" event with a property naming the button, not forty events. Otherwise the event list becomes unusable and cohort analysis becomes impossible.

Use a fixed vocabulary for property values. "mobile" and "Mobile" are different values and nothing warns you.

Track outcomes, not clicks. "Report Exported" is a fact about the product. "Export Button Clicked" is a fact about a mouse.

Write the definitions down where people will find them. A shared document saying what each event means, when it fires, and who owns it. This is the single highest-value artefact in any analytics implementation and it is the one that never gets made.

An automation that compares the events arriving against the agreed taxonomy and reports deviations keeps this from decaying, which it otherwise does within a quarter.

Identity, before and after sign-up

The other thing that breaks, and it breaks quietly.

Anonymous activity is tracked against a device identifier until the person identifies themselves.

Identifying links the two, so pre-signup behaviour joins the user's history — when it is done correctly and at the right moment.

Identify on sign-up and on sign-in, since a returning user on a new device is anonymous again.

One person across devices is not automatically one user unless they identify on each.

Server-side events need the identity supplied explicitly, and mixing client and server tracking without a shared identity is the most common cause of a funnel that loses most of its users at one step.

Do not use personal data as the identifier. Use an internal identifier, and send the email as a property where you need it, which keeps deletion requests tractable.

What the Mixpanel API reaches

Event ingestion accepts events from servers as well as clients, with properties and an explicit identity.

User profiles can be set and updated, which is how attributes such as plan or account age become available for segmentation.

Query endpoints run segmentation, funnels, retention, and saved reports, returning the numbers rather than a chart.

Raw event export retrieves events over a date range, which is what anything analytical or any warehouse load should use.

Cohorts can be read and, with the right configuration, pushed to other tools.

Annotations mark dates on charts, which is how releases become visible in the data.

Identity management endpoints handle the merging and aliasing described above.

Data deletion endpoints support privacy requests, which is not optional if you hold user data.

Connecting it to CodeWords

CodeWords connects to more than 3,000 integrations, and the connection is made once and reused.

  1. Open CodeWords and start a new automation.
  2. Describe what should happen in plain language to Cody, the automation builder: which events or reports, and where the answer should go.
  3. Authorize the connection with a project token for ingestion or a service account for queries, as appropriate.
  4. Describe the exceptions: an event name outside the taxonomy, a figure outside a plausible range, a report returning nothing.
  5. Send test events to a separate project before anything writes to the real one.

You describe the outcome; Cody builds it, connects it, and deploys it. The free plan covers light use, with Pro at $39 per month and Business at $100 per month as usage grows; details are on the pricing page.

Seven automations worth building

Taxonomy conformance reporting. New event names, new property values, and deviations from the agreed convention, reported weekly. The highest-value automation here and the one nobody builds.

Tracking health monitoring. Events that have stopped arriving, or whose volume has moved sharply. Instrumentation breaks on release and produces no error anywhere.

Profile enrichment from your own systems. Plan, account age, industry, and account health written onto profiles so segmentation reflects commercial reality rather than only in-product behaviour.

Server-side event ingestion. Events that cannot be observed in a browser — payments, background jobs, support interactions — sent from where they actually happen.

Scheduled report delivery. The funnel or retention figure somebody checks anyway, delivered with the comparison already calculated.

Cohort activation. A cohort pushed to the CRM or the messaging tool, so a finding turns into an action rather than a screenshot.

Release annotations. Deployments marked on the timeline automatically, which makes every chart interpretable without anybody remembering dates.

Why the numbers will not match

The recurring conversation, and it is better had in advance.

Ad blockers and privacy tools prevent some client-side events reaching Mixpanel at all. Your database sees those users; Mixpanel does not.

Timezones differ. The project's timezone and your database's may not agree, and a day boundary explains a surprising share of disputes.

Definitions differ. An "active user" in Mixpanel means whoever fired a tracked event; in your database it means something else. Both are correct and they count different things.

Deduplication differs. Mixpanel deduplicates users over a period in its own way.

Late-arriving events from offline clients shift historical numbers slightly after the fact.

The resolution is not to reconcile them. It is to agree which system is authoritative for which question — revenue from the database, behaviour from Mixpanel — and to say so on every report.

Reports people act on

Delivering a number automatically is easy. Delivering one that changes a decision takes a few deliberate choices.

Lead with the movement, not the level. "Activation fell from 34% to 28% this week" is a report. "Activation is 28%" is a fact nobody can act on.

Give the comparison in the message. Against last week and against the same week last quarter, so seasonality is visible rather than argued about.

Segment where the aggregate lies. An overall figure holding steady while one plan tier collapses is the situation the aggregate exists to hide.

Include the count, not only the rate. A retention rate over eleven users is noise, and nothing on the chart says so.

Say what changed in the product. Release annotations pulled into the report turn "something moved" into "something moved the day we shipped this".

Send it to whoever owns the number. A report addressed to everybody is read by nobody, and the recipient list is the part most often left as a default channel.

Building it so it survives

Send an identifier for deduplication with each event, since ingestion can be retried and a duplicated event distorts a funnel.

Keep event names in one place in your code, so a rename is a single change rather than a hunt.

Use the export endpoint for anything analytical rather than the query endpoints, which are built for reports rather than for bulk work.

Handle export pagination and rate limits, since raw export over a wide range is a substantial job.

Report the outcome. Events sent, profiles updated, and any name rejected for falling outside the taxonomy.

Limits worth knowing about

Query endpoints are rate limited and are not designed for bulk retrieval, which the export endpoint is.

Export is bounded by your data retention, which depends on your plan.

Event and property name limits exist, along with limits on the number of distinct properties, so an unbounded property value will eventually cause problems.

Ingestion accepts events with historical timestamps within a window, which matters for backfills and means a very old backfill may be rejected.

Deletion requests are asynchronous and take time to complete, which is worth knowing when a deadline applies.

What to build first

Taxonomy conformance reporting: a weekly comparison of the events and property values arriving against the agreed list, naming what is new or deviant. It writes nothing, it takes little building, and it catches the drift that otherwise makes the whole implementation untrustworthy within a year.

Two habits make the difference. Report new event names prominently, since an unplanned event is usually somebody's instrumentation that nobody else knows about. And send it to whoever owns the taxonomy document rather than to a general channel, because the value is in the document being updated or the event being corrected.

Frequently asked questions

Why does Mixpanel disagree with our database?

Ad blockers, timezone boundaries, differing definitions of an active user, and late-arriving events. All are expected. Agree which system is authoritative for which question rather than trying to reconcile them.

How many distinct events should we have?

Far fewer than most projects end up with. Variation belongs in properties, not in event names. A few dozen well-named events with rich properties is more useful than four hundred events nobody can find.

Why does our funnel lose almost everyone at one step?

Very often an identity problem, particularly where one step is tracked client-side and the next server-side without a shared identity. Check the identity handling before concluding there is a product problem.

Should we track from the client or the server?

Both, deliberately. Client-side for interface behaviour, server-side for anything that must be accurate — payments, background processing, anything an ad blocker would otherwise remove. Use the same identity on both or the data will not join.

What should we use as the user identifier?

An internal identifier, with the email sent as a property if you need it. Using personal data as the identifier makes deletion requests considerably harder and spreads that data further than intended.

How do we stop the taxonomy drifting?

Write the definitions down, and check the arriving events against them automatically. Documentation alone decays; documentation plus a weekly report of deviations stays accurate because somebody is told when it is not.

Can we push a cohort into another tool?

Yes, and it is what turns a finding into an action. A cohort sitting in Mixpanel is a screenshot in a meeting; the same cohort in your CRM or messaging tool is something somebody can act on.

Why does nobody read our automated analytics reports?

Usually because they state levels rather than changes, carry no comparison, and are addressed to a channel rather than a person. Lead with what moved, include the comparison and the counts, and send it to whoever owns the number.

How do I stop a report being misleading?

Include the sample size alongside every rate, and break out the segments where an aggregate could conceal a collapse. A steady overall figure hiding a failing tier is the commonest way an honest report misleads.

Can we backfill historical events?

Within the ingestion window for historical timestamps, which means a recent backfill works and a very old one may be rejected. Check the window before planning a migration around it.

Should profile properties come from the product or from our own systems?

From whichever owns the truth. Plan, billing status, and account health live in your systems and should be written onto profiles; in-product behaviour is Mixpanel's. Segmentation is far more useful once both are present on the same profile.

Get started today

Your first workflow is free to build.

Describe what you need. Cody handles the build, the connections, and the deployment.