In the autumn of 2024, a digital marketing company reached out to me. They run websites in several countries, pay ad networks for traffic, and collect sign-ups from people interested in their partners' offers. When a sign-up turns into a customer, the partner pays them. Typical affiliate marketing.

They needed a platform built from scratch: websites the marketing team could launch and change on their own, with sign-up forms, customizable email and SMS campaigns, and tracking that shows which ads bring in real customers. And they wanted a developer who could hold all of it.

For a business like this, the website is the cash register. Every sign-up is a lead somebody paid for. Every visitor arrives with a note from the ad network saying where they came from, and if that note gets lost, nobody knows which ads are worth the money. And when someone who signed up says "please stop emailing me", that's a legal obligation.

Two years and hundreds of thousands of leads later, I'm still the only developer on it. Here's what that looks like.

What happens when someone taps an ad

Say someone is scrolling on their phone and taps an ad. A moment later, they're on one of the company's sites. There are five of them, all running on a single Wagtail installation, each with its own look and with content in six languages. Before the page has finished loading, the platform has already noted which ad brought them in.

The page compares offers from the company's partners, around 500 of them across all the sites, each with its own logo, rating and tracked link. Someone on the marketing team ranked these offers for this market.

From here, our visitor can go two ways. They can click straight through to an offer, and the tracked link makes sure the client gets credit for sending them. Or they can leave their details in a sign-up form: tick the consent boxes, get waved through by the spam protection, hit submit. Within a minute, their lead is on its way, and the platform tells the ad network that its ad worked, so the budget can follow the campaigns that bring people in.

Their lead lands in the email and SMS tools. Two hours later, they might get a text. Three days later, another one. Nobody sends those by hand: the marketing team set up that sequence themselves, right in the admin, along with one-off broadcasts and message templates.

And when the team wants a whole new site? They add it in the admin, pick a design from a set of previews, select an existing country to start from, and go. The platform even sets up the domain on the server. No ticket to me.

That's when everything goes right.

Where the money leaks

The first thing this project taught me is that problems here rarely look like problems. When something goes wrong with leads, nobody sees an error page. A lead just doesn't arrive. A person who unsubscribed keeps getting emails. The numbers slip, and nobody can say why.

So a big part of my job is finding those leaks before anyone else does. Two examples.

No lead left behind

When a lead comes in, it goes through a funnel: an outside service validates it, and then it's stored in the email and SMS tools the site uses. Every step depends on someone else's system, and other people's systems go down. When that happens, the lead doesn't vanish. It waits, the platform tries again, and twice a day a sweep picks up anything that still hasn't gone through.

One partner's system had a habit of sending the same notification twice. Now the platform spots the second one and ignores it.

And when someone on the team asks "what happened to this lead?", the answer is on that lead's page in the admin. Every step it went through is logged, and if something didn't sync, there's a plain-English explanation of why.

When someone says "stop", it sticks

People unsubscribe in all sorts of places: the preference page on the site, a link in the email footer, or the unsubscribe button Gmail shows at the top of a message. The last two never touch the client's website. They only tell the email provider.

Now the email provider tells the platform about every unsubscribe within seconds. Those notifications occasionally go missing, so twice a day a backup check compares the full lists across all twelve of the company's messaging accounts and catches anything that slipped through. If that check ever can't read the data properly, it raises an alarm instead of reporting that everything is fine.

What nobody has to do manually

The platform runs over twenty automated jobs around the clock. Every minute, new leads go out. Every couple of minutes, SMS campaigns run. Every five minutes, pages the team scheduled go live on their own. Every half hour, subscriber preferences sync with the messaging tools. Twice a day, the sweeps I mentioned catch missed unsubscribes and retry failed leads. Every night, the platform checks that its connections to outside services still work.

When something does need attention, it shows up where the team already looks: the dashboard they see when they log in. Status panels show what synced, what failed and what's waiting, with a short explanation for each. A broken connection appears there as a warning, instead of as a campaign that silently sent nothing.

Each of those panels saves the team a message to me. More importantly, the person who can fix a problem sees it the day it happens.

How it's built

I built the platform with Django and Wagtail CMS, the same foundation as the healthcare membership platform I wrote about before. The websites, the sign-ups, the campaigns and the partner data all live in one system. One admin, one login, one codebase. Nothing to keep in sync between "the website" and "the marketing tool", because they're the same thing.

More than 2,200 automated tests check the platform before every release, and a release only goes out if they all pass. When a bug costs money without crashing anything, tests are the cheapest insurance I know of.

Two years in, everything runs on current versions, upgraded a step at a time and never left to fall behind.

What two years of ownership looks like

I've been the only developer since the first line of code. I know which job touches what, which partner's system likes to send things twice, and which email client will ruin your afternoon. When the client asks for a change, there's no onboarding. I already know where it goes and what it might break.

Keeping things fast is part of the job too. For example, when the twice-daily unsubscribe check started tying up the database for twenty minutes at a time, I reworked it to finish in seconds.

These days, every bigger change starts with a short written plan: what's wrong, what I checked, what I decided and what I ruled out. There are 47 of them on this project so far. Anyone can look back months later and see why something works the way it does, so the knowledge doesn't live only in my head.

How I work

This is how I like to work: I build a platform, and then I stay with it. My clients don't have to explain their business to a new developer every year, and nothing gets lost when a contract ends.

I work mainly with Django and Wagtail CMS, across the whole stack: business logic, database, background automation, integrations with outside services, frontend and deployment.

If your website is where your revenue comes from, and you'd like a developer who treats it that way, I'd love to hear what you're working on. Let's talk.