A unified campaign automation stack: one customer record, permission attached, every tool reading from it

TL;DR

Difficulty: Intermediate

A unified stack is one record of each customer and each event, with permission stored on the record, and every tool reading from it.

  • Five jobs: collect events, keep the record, send email, reach ad audiences, move data between them.
  • Consent is a field with source, wording and time, checked per purpose before anything leaves.
  • For a small shop the bill is mostly the email tool and the tag server. Buying usually beats building until volume pricing makes the break even short.
  • A daily check of counts in and out is the best value part of the whole stack.
  • In Ireland the rules are the GDPR and the ePrivacy Regulations 2011, enforced by the DPC.

Most small shops run several marketing tools that each keep their own version of the customer and of who agreed to what. This article shows how to make one record the source for all of them, with consent attached, and what that costs to build, buy, run and leave, worked through for an invented tea shop in Limerick.

One customer, one record, and every tool reads from it

Most small shops do not have a marketing stack. They have a collection of subscriptions that each grew up on their own. The email tool knows who opened what. The ad accounts know who clicked. The shop knows who paid. Nobody knows all three, and nobody knows for certain who said yes to what.

A unified campaign automation stack fixes that with one idea. There is one record of each customer, and one record of each thing they did, and every tool that acts (the email tool, the ad platforms, the analytics) reads from those records instead of keeping its own version. The permission each person gave travels with their record, so a tool can only see the people it is allowed to see.

I do not automate campaigns in isolation, and this article is the reason why. It is about the architecture: which pieces you need, what each costs, whether to build or buy them, what breaks, and who owns the data when you leave a vendor. The pieces themselves each have their own article, and I link to them as we go rather than repeat them.

Throughout I use one invented business. Milk Market Tea Co is an online loose leaf tea shop in Limerick, run by Róisín, on Shopify, at milkmarkettea.example. It takes about 1,000 orders a month at an average of €28, keeps about €14 of each order after the cost of the tea, packaging and An Post, and has 6,000 contacts in its email tool. It spends about €3,000 a month on Meta and €2,000 on Google. Nobody real, and every number is made up so I can show every step.

The stack is five jobs, not five products

The old version of this article listed products: Zapier, Segment, Python, the Google Ads API, Postmark, BigQuery. Products change every year, the jobs do not. There are five.

  1. Collect events. Something records what visitors and customers do, page views, add to baskets, purchases, along with the consent state of the browser at that moment. That is the subject of my article on event tracking and consent mode, and server side tagging is one way of doing it.
  2. Keep the record. One place holds one row per customer, with their identifiers, their orders and their permissions. For a small shop that is often the shop platform plus the email tool. For a bigger one it is a data warehouse.
  3. Send email. An email service provider (ESP), such as Klaviyo or Postmark, sends the messages.
  4. Reach ad audiences. Customer lists and conversion data go to Google and Meta, which is the subject of triggering ads from email activity and of auto bidding on first party data.
  5. Move data between them. Native integrations, a tool like Zapier, or your own code on webhooks and serverless functions.

The order matters. Everything flows from collection, through the record, to the tools that act, and permission is checked at the record, before anything leaves.

How data moves through a unified campaign stackEvents and orders are collected with their consent state, written to one customer record, and each destination receives only the people whose permission for that purpose is granted. Anyone without permission stays in the shop's own records only.A visitor browses, subscribes or buysThe event is collected with thebrowser's consent stateThe customer record is updated:identifiers, orders, permissionsIs permission granted for thispurpose?yesSent to the tool for that purpose:email, ad audience or analyticsnoKept in the shop's own records, sentnowhereA daily check compares what went inwith what came out

The decision step is the heart of it: one question, asked per purpose, before any data leaves. A yes sends the person to that one tool. A no keeps them in the shop's own order records, which are needed to run the shop anyway. The last step is the boring one that saves the most money, and it has its own section further down.

Worked example: Milk Market's five jobs

Róisín writes the five jobs down and puts what she already pays for next to each one.

  1. Collect events: the Shopify store, its consent banner, and Google's tags.
  2. Keep the record: Shopify's customer list, which Klaviyo copies through its Shopify integration. Klaviyo documents that it brings customer profile and order data in, and that it can add customers who accept email marketing at checkout to a list.1
  3. Send email: Klaviyo.
  4. Reach ad audiences: the Meta and Google apps for Shopify, plus Klaviyo's audience sync.
  5. Move data between them: two Zapier automations, one that posts big orders to her phone and one that copies wholesale enquiries into a spreadsheet.

She already has a stack. What she lacks is one answer to "who may receive what", because three tools each hold a version of it.

Under the GDPR, where you rely on consent you must be able to show that the person consented, and withdrawing must be as easy as giving it.2 That one sentence decides the architecture. If the proof of consent lives inside an email tool, the ad sync cannot see it, and if a person withdraws in one tool, the other tools keep using the old answer.

So each permission is a field on the customer record, with what was agreed, where, when and with which wording. There are two kinds, and they behave differently.

Permission for email belongs to a person. In Ireland, regulation 13 of the ePrivacy Regulations 2011 (S.I. No. 336 of 2011) says marketing email to an individual needs their consent, with one exception for your own customers in regulation 13(11): you got their email address from them in the context of a sale, you market only your own products of a kind similar to what they bought, you gave them a clear, easy and free way to object when you collected the details and in every message since, and the sale was no more than 12 months before the email.3 So the record also needs the date of the last purchase, because the exception runs out.

Permission for cookies and tags belongs to a browser. Regulation 5(3) of the same Regulations says nobody may store information on a user's device, or read information already stored there, without the user's consent and clear, comprehensive information about the purpose, and regulation 5(5) exempts only what carries a communication or is strictly necessary for a service the user explicitly asked for.4 The banner answer is a snapshot on each event, not a fact about the person. The regulator that enforces both is the Data Protection Commission (DPC). The 2011 Regulations still name the Data Protection Commissioner, and the Data Protection Act 2018 transferred all of the Commissioner's functions to the Commission and reads every such reference as one to the Commission.5 The details of what needs a yes are in my article on event tracking and consent mode, and how to ask for email permission without losing sign ups is in GDPR versus growth.

The ad platforms add their own layer. Google's EU user consent policy covers end users in the European Economic Area, which includes Ireland, as well as the UK and Switzerland, and asks for legally valid consent to use personal data for ad personalisation, with records kept of it.6 For customer list uploads, Google's API refuses the request if the ad_user_data or ad_personalization consent field is denied.7 So the record needs a separate field for ad audiences, because a customer can happily want your newsletter and still not want to be matched to their Facebook account.

Worked example: Jo's record, three destinations

Jo buys a tin of Irish breakfast tea, ticks the marketing box at checkout, and a week later opens the preference centre and switches off "use my email to show me ads". Her record in Róisín's store now reads:

{
  "customer_id": "c_10482",
  "email": "jo@example.com",
  "orders": 1,
  "consents": {
    "email_marketing": {
      "state": "granted",
      "basis": "consent",
      "source": "checkout",
      "wording": "checkout_box_v3",
      "at": "2026-10-14T19:02:11Z"
    },
    "ad_audiences": {
      "state": "denied",
      "source": "preference_centre",
      "at": "2026-10-21T08:15:40Z"
    }
  }
}

The nightly sync asks the question from the diagram once per destination.

  1. Email tool: email_marketing is granted, so Jo stays on the newsletter list.
  2. Meta and Google customer lists: ad_audiences is denied, so Jo is not uploaded to either, not even to the list of recent buyers that is used to exclude people from prospecting ads.
  3. Analytics: nothing on the person record decides this. Each of Jo's page views carries the banner answer her browser gave at the time, and the tags respect that.

Step two has a price. Jo may now see an advert inviting her to try Milk Market for the first time, because Róisín cannot tell Meta to leave her out. That is the rule working, not failing. The alternative, uploading her anyway "only for exclusion", is a judgement for a lawyer, and Google's own consent field would refuse it in any case.

What the stack costs a month, and the orders that pay for it

The bill for a small shop is mostly subscriptions, and most of them price by size: contacts, events or tasks. Here is what each vendor's own page says, checked in November 2026.

Klaviyo bills by active profiles, which it defines as any contact you can market to. Its free plan covers up to 250 active profiles, and the paid Email plan starts at 20 US dollars a month for 500 profiles, rising on a slider as the count grows.8 RudderStack, which collects events and routes them to tools, is free up to 250,000 events a month, and its Growth plan is 265 US dollars a month for one million events.9 Zapier's Pro plan is 29.99 US dollars a month on monthly billing for 750 tasks, a task being one successful action.10 A server side tagging container on Google Cloud Run costs about 45 US dollars a month per server, and Google recommends at least two.11 BigQuery, Google's warehouse, includes 1 TiB of query processing a month free.12 Twilio Segment, the best known of the event routers, publishes no prices on its pricing page and quotes by monthly tracked users instead.13

Worked example: Milk Market's monthly bill

Most of these prices are in dollars. For round arithmetic I convert at €0.75 to the dollar, which is an assumption for the example, so check the rate on the day. Róisín's 6,000 profiles put her well above Klaviyo's first step, and for this example I take her slider price as €110 a month. Read your own off the slider, because it moves with your count.

Her site gets 30,000 sessions a month at about eight events each:

30,000×8=240,00030{,}000 \times 8 = 240{,}000

Here 30,00030{,}000 is sessions a month and 88 is events per session, so 240,000 events, just under RudderStack's free 250,000. Then the bill, line by line:

  1. Klaviyo: €110.
  2. Zapier Pro: 29.99 dollars at €0.75 each is €22.49.
  3. RudderStack: €0, inside the free tier.
  4. BigQuery: inside the free query allowance, and I count €1 for storage of a few gigabytes as the example's assumption.
  5. Server side tagging: two servers at 45 dollars, at €0.75 each, is €67.50.
110+22.49+0+1+67.50=200.99110 + 22.49 + 0 + 1 + 67.50 = 200.99

Here 110110 is Klaviyo, 22.4922.49 Zapier, 00 RudderStack, 11 BigQuery and 67.5067.50 the tag server, all in euro a month, so about €201.

Milk Market's monthly stack cost by toolKlaviyo is the largest line at €110, server side tagging €67.50, Zapier €22.49, BigQuery €1 and RudderStack nothing, about €201 in total.Milk Market Tea Co, monthly tool cost€0€50€100€150€200€110Klaviyo€67.5Serversidetagging€22.5Zapier€1BigQuery€0RudderStack€ a month

Each bar is one tool, and the vertical axis is what it costs Róisín a month in euro. The takeaway is that the email tool and the tag server are nearly nine tenths of the bill, and the warehouse, the part people fear, is close to free at this size. RudderStack's bar is zero only while she stays under 250,000 events.

Is €201 worth it? The number of extra orders whose margin covers it is a simple ratio:

n∗=Cmn^{*} = \frac{C}{m}

Here n∗n^{*} is the break even number of extra orders a month, CC is the monthly cost of the stack in euro, and mm is the margin per order in euro, what is left after the cost of the goods, packaging and postage. It is a rate like any other, explained in Foundations: ratios and rates.

For Milk Market:

n∗=20114=14.4n^{*} = \frac{201}{14} = 14.4

Here 201201 is the monthly cost and 1414 the margin per order, both in euro. So 15 extra orders a month, 1.5% of her 1,000, pays for the whole stack. That is a low bar, which is exactly why it is worth checking honestly with a holdout group rather than assuming it. The methods are in my guide to digital marketing testing methods. Notice what the formula leaves out: the time to set it up and keep it running. That is the next section.

Build or buy: the one off cost against the monthly one

Every piece can be bought as a subscription or built as your own code on a warehouse. The subscription is quick to start and costs every month. Your own code is slow to start and costs little to run. Both need looking after, and people forget to count the upkeep of the thing they bought.

The comparison is a one off cost against a monthly saving. If building costs more up front but less each month, it catches up after

t∗=Bbuild−BbuyMbuy−Mbuildt^{*} = \frac{B_{\text{build}} - B_{\text{buy}}}{M_{\text{buy}} - M_{\text{build}}}

Here t∗t^{*} is the break even point in months, BbuildB_{\text{build}} and BbuyB_{\text{buy}} are the one off setup costs of each option in euro, and MbuyM_{\text{buy}} and MbuildM_{\text{build}} are their full monthly costs in euro, subscription or hosting plus upkeep time. If MbuyM_{\text{buy}} is not larger than MbuildM_{\text{build}}, building never catches up. It is a ratio of a one off amount to a monthly rate, the idea in Foundations: ratios and rates. Over a horizon of several years, money later is worth less than money now, which pushes the break even further out, as Foundations: discounting explains.

Worked example: Milk Market's routing layer, two ways

Milk Market's traffic grows to 600,000 events a month, past RudderStack's free tier. Róisín compares two ways of collecting events and sending customer lists to Google and Meta. To price time I assume a day of senior engineering at €550, a round figure for the example, not anyone's quote.

Buy: RudderStack Growth at 265 dollars, which at €0.75 each is €198.75 a month. Three days to set up and a quarter of a day a month to keep an eye on it.

Bbuy=3×550=1,650B_{\text{buy}} = 3 \times 550 = 1{,}650

Here 33 is the setup days and 550550 the day rate in euro.

Mbuy=198.75+0.25×550=336.25M_{\text{buy}} = 198.75 + 0.25 \times 550 = 336.25

Here 198.75198.75 is the subscription in euro and 0.250.25 the days of upkeep a month.

Build: her own small collector writing into BigQuery, with nightly sync jobs. Fifteen days to set up, about €10 a month to host (the example's assumption), and half a day a month of upkeep.

Bbuild=15×550=8,250B_{\text{build}} = 15 \times 550 = 8{,}250

Here 1515 is the setup days at 550550 euro each.

Mbuild=10+0.5×550=285M_{\text{build}} = 10 + 0.5 \times 550 = 285

Here 1010 is hosting in euro and 0.50.5 the days of upkeep a month.

Then the break even:

t∗=8,250−1,650336.25−285=6,60051.25=128.8t^{*} = \frac{8{,}250 - 1{,}650}{336.25 - 285} = \frac{6{,}600}{51.25} = 128.8

Here 6,6006{,}600 is the extra setup cost of building and 51.2551.25 is the monthly saving, so building catches up after 129 months, nearly 11 years. For Milk Market, buying wins by a distance.

Cumulative cost of buying versus building the routing layerBuying starts at €1,650 and reaches €9,720 after 24 months. Building starts at €8,250 and reaches €15,090. The lines barely converge over two years.Milk Market's routing layer, total spent to date€0€5,000€10,000€15,000€20,000Month 0Month 6Month 12Month 18Month 24BuyBuild€ spent to date

The horizontal axis is months since the decision, the vertical axis is the total spent so far in euro, setup included. The gap closes by only €51.25 a month, which is why the lines look almost parallel. Now change one number. Suppose Milk Market triples again and the subscription quote rises to €700 a month. MbuyM_{\text{buy}} becomes 700+137.50=837.50700 + 137.50 = 837.50, and

t∗=6,600837.50−285=6,600552.50=11.9t^{*} = \frac{6{,}600}{837.50 - 285} = \frac{6{,}600}{552.50} = 11.9

Here 552.50552.50 is the new monthly saving, and building pays back in under a year. The lesson is not "build" or "buy". Volume priced subscriptions grow with you and your own code mostly does not, so the answer flips at a size you can calculate in advance.

Small ad accounts cannot target with customer lists yet

One cost does not appear on any invoice: the features you cannot use. Google's Customer Match policy says targeting and bid adjustments with customer lists need 90 days of Google Ads history and more than 50,000 US dollars of lifetime spend. Accounts below that, with good policy and payment history, can still use customer lists for exclusions and in observation.14 Klaviyo's documentation repeats the same thresholds for its Google sync.15

The same Klaviyo page has a detail worth reading twice. When you market to the EEA, which includes every customer on an Irish list, Klaviyo asks you to agree that you only send audiences that have consented to ad targeting, then sends the consent as granted for every profile in the sync. It states that the setting does not check each profile's consent.15 The filter has to be in the segment you sync, which is exactly why the consent field belongs on the record.

An example: Milk Market has spent about €28,000 on Google Ads over its life, roughly 37,000 dollars at the example's rate, so it is under the threshold. Róisín's buyer list can exclude recent customers from her Google prospecting campaigns, which is useful, but it cannot target them. On Meta, a customer file audience can be used to target, and its documentation sets no spend threshold.16 So a stack that is "one audience, sent everywhere" does different things on each platform, and her plan has to say so, or she will spend a week wondering why the Google campaign will not serve.

What breaks, and what it costs when it does

A stack fails quietly. Nothing crashes. A sync stops, a field goes missing, an event is renamed, and the tools carry on with stale data. The useful way to price that is expected value: how likely each failure is in a month, times what it costs when it happens.

E=∑ipi ciE = \sum_{i} p_i \, c_i

Here EE is the expected cost of failures in a month, in euro, pip_i is the probability that failure ii happens in a given month, cic_i is what it costs when it does, in euro, and ∑i\sum_i adds the products over every failure on the list. The idea is in Foundations: expected value.

The common failures, from the vendors' own documentation:

  • Duplicates. Shopify says your app might receive the same webhook more than once and tells you to skip any delivery whose X-Shopify-Webhook-Id you have already seen.17 Meta deduplicates browser and server events only when the event name and id match, and only within 48 hours.18 Without that, purchases count twice and the bidding chases a ghost.
  • Deprecations. Since 1 April 2026, Google's older Customer Match services in the Google Ads API fail for projects with no Customer Match activity between October 2025 and March 2026, and Google points to the Data Manager API instead.7 Code that worked last year can stop this year without anyone touching it.
  • Renames and missing fields. A theme update renames the purchase event, or a new sync job forgets to copy the consent field. These are not in any vendor's documentation, because they are yours.

Worked example: Milk Market's expected monthly breakage

Róisín lists three failures. The probabilities and costs are the example's assumptions, chosen to be plausible, not measured.

  1. The Meta exclusion list of recent buyers stops updating for a week. Likelihood 10% a month. A week of Meta spend is 3,000×7/30=7003{,}000 \times 7 / 30 = 700 euro, and she assumes 12% of it reaches recent buyers when the list is stale, so c1=700×0.12=84c_1 = 700 \times 0.12 = 84.
  2. A theme update renames the purchase event and Google's bidding runs blind for five days. Likelihood 5%. Cost €350.
  3. A new sync job leaves out the consent field and refusers are uploaded to an audience. Likelihood 2%. Cost two days of clean up and review, 2×550=1,1002 \times 550 = 1{,}100, before any question of trust or the DPC.
E=0.10×84+0.05×350+0.02×1,100=8.40+17.50+22.00=47.90E = 0.10 \times 84 + 0.05 \times 350 + 0.02 \times 1{,}100 = 8.40 + 17.50 + 22.00 = 47.90

Here 0.100.10, 0.050.05 and 0.020.02 are the monthly likelihoods and 8484, 350350 and 1,1001{,}100 the costs in euro, so EE is about €48 a month. Now she adds a daily check that compares counts in with counts out, alarms when an audience has not changed for a day, and refuses to upload any row without a consent field. Each failure is now caught within a day. The first costs a seventh as much, €12. The second costs a fifth, €70. The third is blocked before upload, costing half a day, €275.

E′=0.10×12+0.05×70+0.02×275=1.20+3.50+5.50=10.20E' = 0.10 \times 12 + 0.05 \times 70 + 0.02 \times 275 = 1.20 + 3.50 + 5.50 = 10.20

Here E′E' is the expected monthly cost with the check in place, about €10. The check saves about €38 a month and takes a day to build, so it pays back in about 15 months on money alone. The part it really buys is the third line: the failure you cannot fully price is the one it stops.

Owning the record means you can leave

Data ownership sounds like a legal question. In practice it is a test: could you switch your email tool next month and take everything with you?

The law sets the floor. Under the GDPR a vendor that processes your customers' data for you does so under a contract, and that contract must say the vendor deletes or returns all the personal data at your choice when the service ends.19 It does not say in what shape. That is where the architecture comes in. If the only full copy of the consent history lives inside one vendor, leaving means trusting their export. If your own record holds it, the vendor holds a copy and you hold the original. Choosing and checking those vendors is its own job, covered in vetting vendors before they undermine your compliance.

Worked example: Róisín leaves her email tool

Suppose Róisín wants to move off Klaviyo. Klaviyo's list and segment export to a CSV file can include each profile's email and SMS consent status and consent timestamp, but it cannot export the full event history.20 The events come out through the API instead, which returns 200 events a page by default and up to 1,000.21

If her consent history lives only in Klaviyo, the CSV gives her the current state and a timestamp, but not the wording, the source or the earlier changes. If she keeps the record in her own store, as in Jo's example, nothing is lost, and her orders already sit in Shopify and her warehouse. Same vendor, very different week.

Where custom code earns its place

None of this means writing everything yourself. In the old version of this article I described the split I use, and it still holds. Zapier or n8n are fine glue for reactions that are not critical and do not need to happen within the second. When the logic becomes real, checking margin before a discount, filtering on returns, I write it in Python or Node, against the record.

On one shop I worked on, the win back rule had three conditions: no order in 45 days, a lifetime value above 100, and the last item not returned. The email tool on that project could not see returns, so the rule ran as a scheduled job against the warehouse and sent each email through Postmark. The old article showed that code, and it was wrong: it used another vendor's address and message format. Postmark's API takes a POST to https://api.postmarkapp.com/email with the server token in the X-Postmark-Server-Token header.22 Marketing mail also belongs on a broadcast stream, which Postmark keeps on separate infrastructure from transactional mail and which requires an opt out link.23

An example: the job for Milk Market, with the consent check where it belongs, before the send.

import os
import requests

def send_winback(customer):
    consent = customer["consents"]["email_marketing"]
    if consent["state"] != "granted":
        return "skipped: no email permission"
    response = requests.post(
        "https://api.postmarkapp.com/email",
        headers={
            "Accept": "application/json",
            "X-Postmark-Server-Token": os.environ["POSTMARK_SERVER_TOKEN"],
        },
        json={
            "From": "roisin@milkmarkettea.example",
            "To": customer["email"],
            "Subject": "Your Irish breakfast is nearly out",
            "HtmlBody": render_winback(customer),
            "MessageStream": "winback",
        },
        timeout=10,
    )
    response.raise_for_status()
    return "sent"

Here winback is a broadcast stream Róisín created in Postmark, and render_winback builds the message with its unsubscribe link. Jo, with her email permission granted, would get it. A customer whose email_marketing state is denied returns at the first if, and no amount of clever segmentation upstream can change that.

What I would set up first

In order, for a shop of Milk Market's size:

  1. Put the consent fields on the customer record, with source, wording and time. Everything else depends on it.
  2. Use the native integrations between the shop, the email tool and the ad platforms, and filter every synced segment on the consent fields.
  3. Add the daily check that compares counts in and out. It is the least glamorous part and the best value.
  4. Add server side tagging or an event router when the browser setup is right and there is a question it answers.
  5. Build your own code only where the break even says so, or where the logic is genuinely yours, like the win back rule.

And if you are below a few hundred orders a month with one email tool, steps one and two are the whole project. The rest is a well engineered answer to a question you do not have yet.

The tools are rented, the record is yours

The glue is not in the tools. It is in the orchestration, and the orchestration rests on one record of each customer that says who they are, what they did and what they allowed. With that in place, every tool becomes replaceable, every sync can be checked, and every new channel starts from the same permissions. Without it, each subscription you add is another place for the truth to drift.

Footnotes

  1. Klaviyo, Getting started with Shopify, Klaviyo Help Center, 2026, https://help.klaviyo.com/hc/en-us/articles/115005080407

  2. Regulation (EU) 2016/679, General Data Protection Regulation, Article 7, conditions for consent, paragraphs 1 and 3, EUR-Lex, 2016, https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679

  3. European Communities (Electronic Communications Networks and Services) (Privacy and Electronic Communications) Regulations 2011, S.I. No. 336 of 2011, regulation 13(1) and (11), Irish Statute Book, 2011, https://www.irishstatutebook.ie/eli/2011/si/336/made/en/print

  4. European Communities (Electronic Communications Networks and Services) (Privacy and Electronic Communications) Regulations 2011, S.I. No. 336 of 2011, regulation 5(3) and (5), Irish Statute Book, 2011, https://www.irishstatutebook.ie/eli/2011/si/336/made/en/print

  5. Data Protection Act 2018, section 14, transfer of functions of Data Protection Commissioner to Commission, Irish Statute Book, 2018, https://www.irishstatutebook.ie/eli/2018/act/7/enacted/en/print, read with regulation 17 of S.I. No. 336 of 2011, https://www.irishstatutebook.ie/eli/2011/si/336/made/en/print

  6. Google, EU user consent policy, Google, 2026, https://www.google.com/about/company/user-consent-policy/

  7. Google, Get started with Customer Match, Google Ads API documentation, Google for Developers, 2026, https://developers.google.com/google-ads/api/docs/remarketing/audience-segments/customer-match/get-started

  8. Klaviyo, Pricing, Klaviyo, 2026, https://www.klaviyo.com/uk/pricing

  9. RudderStack, Pricing, RudderStack, 2026, https://www.rudderstack.com/pricing/

  10. Zapier, Plans and pricing, Zapier, 2026, https://zapier.com/pricing

  11. Google, Cloud Run setup guide for server side tagging, Tag Platform, Google for Developers, 2026, https://developers.google.com/tag-platform/tag-manager/server-side/cloud-run-setup-guide

  12. Google Cloud, Try BigQuery using the sandbox, BigQuery documentation, 2026, https://docs.cloud.google.com/bigquery/docs/sandbox

  13. Twilio, Customer data pricing (Segment), Twilio, 2026, https://www.twilio.com/en-us/pricing/customer-data

  14. Google, Customer Match policy, Google Ads Help, 2026, https://support.google.com/google-ads/answer/6299717

  15. Klaviyo, Getting started with Google Ads, Klaviyo Help Center, 2026, https://help.klaviyo.com/hc/en-us/articles/6353315757211

  16. Meta, Customer file Custom Audiences, Marketing API documentation, Meta for Developers, 2026, https://developers.facebook.com/docs/marketing-api/audiences/guides/custom-audiences

  17. Shopify, Ignore duplicate webhooks, Shopify developer documentation, 2026, https://shopify.dev/docs/apps/build/webhooks/ignore-duplicates

  18. Meta, Handling duplicate Pixel and Conversions API events, Meta for Developers, 2026, https://developers.facebook.com/docs/marketing-api/conversions-api/deduplicate-pixel-and-server-events

  19. Regulation (EU) 2016/679, General Data Protection Regulation, Article 28, processor, paragraph 3(g), EUR-Lex, 2016, https://eur-lex.europa.eu/legal-content/EN/TXT/HTML/?uri=CELEX:32016R0679

  20. Klaviyo, How to export a list or segment to a CSV file, Klaviyo Help Center, 2026, https://help.klaviyo.com/hc/en-us/articles/115005078687

  21. Klaviyo, Get Events, Klaviyo developer documentation, 2026, https://developers.klaviyo.com/en/reference/get_events

  22. Postmark, Sending email with API, Postmark developer documentation, 2026, https://postmarkapp.com/developer/user-guide/send-email-with-api

  23. Postmark, Message streams, Postmark, 2026, https://postmarkapp.com/message-streams

If your tools each hold a different idea of who your customers are and what they agreed to, bring the list to my free workshop. We will map your five jobs together, and if it makes sense, the first two weeks of putting the record right are on me, no bother.