Case Study Link Broadband · Stefanov Capital · 2026

Three systems.
One integration contract.
A deadline none of them could move.

Link Broadband needed a marketing website, a HubSpot lifecycle automation layer, and a seamless handoff into a third-party checkout platform — all built, integrated, and launched in four weeks. The work wasn't just building pages. It was defining exactly what each system owned, what it didn't, and where they had to connect precisely.

ClientStefanov Capital (Emily, Jeffrey, Landon)
My roleTechnical PM · PM on all client comms
Delivery window4 weeks — Apr 7–30, 2026
TeamDev · Designer · QA
External partiesGaiia · EPC · Mapbox
Status✓ Launched
3
Independent systems to coordinate — Astro, Gaiia, HubSpot
7
HubSpot lifecycle workflows designed and built by BetaCraft
4wk
Fixed client deadline with a hard design gate at week 2
90+
Lighthouse score target — technical SEO shipped to spec

01 / Context

What Link Broadband needed to launch.

Link Broadband is a fibre broadband provider rolling out neighbourhood by neighbourhood across Colorado. Before customers could sign up, they needed to know the service was coming to their street — and when. Before the rollout could scale, Link needed a system to capture interest, nurture prospects through construction, and convert them to subscribers the moment their area went live.

BetaCraft was engaged to build three things that had to work together as a single system: a marketing website built in Astro, a HubSpot lifecycle automation layer covering seven customer journey stages, and a precision handoff to Gaiia — Link's third-party checkout and provisioning platform — so customers could check availability and sign up without ever leaving a familiar-feeling experience.

None of these three systems talked to each other natively. Defining the integration contracts between them — what each owned, what each expected to receive, and where the boundaries sat — was as much of the project as the build itself.

Astro Vercel GitHub HubSpot Gaiia (checkout) Mapbox GA4 UTM tracking Technical SEO

02 / The system

Four parties. One customer journey.

The full customer journey ran through four distinct parties — BetaCraft (the website), Gaiia (checkout and provisioning), EPC (the construction company sending build-stage signals), and HubSpot (lifecycle automation). Understanding where each party's responsibility began and ended wasn't assumed — it was explicitly mapped and agreed before a line of code was written.

System responsibility map — full customer journey
BetaCraft
Gaiia
EPC
HubSpot
Customer BETACRAFT BUILDS Marketing site · Neighbourhood pages · SEO · Admin panel GAIIA OWNS Availability check Plan selection Payment Install scheduling Order comms ⚡ Integration seam — Mapbox prefill HUBSPOT — 7 WORKFLOWS (BETACRAFT) Pre-reg · Construction updates · Stall detection · Service available · Re-engagement EPC SIGNALS Build stage events Customer email / SMS nurture Order confirmation (Gaiia owns) Gaiia → HubSpot API connection is Gaiia's responsibility — BetaCraft defined the contract, not the pipe

03 / Scope contracts

What BetaCraft built. What Gaiia owned. Non-negotiable.

The single most important PM decision on this project was drawing the ownership line between BetaCraft and Gaiia clearly, in writing, before the build started. Without it, scope creep from the Gaiia side — "can you also handle the availability check?" — would have added weeks to a four-week engagement.

Area Owner Notes
Marketing website (all pages) BetaCraft Homepage, neighbourhood pages, pricing, support, legal shell
Mapbox address autocomplete + Gaiia prefill redirect BetaCraft Hero CTA: capture address → construct prefill URL → redirect. Nothing after the click.
HubSpot workflows (7 of 11) BetaCraft WF-01 through WF-07, WF-11. All pre-order lifecycle stages.
Admin panel + status banner BetaCraft Non-technical admin for Link team to push operational updates
Address availability check Gaiia Gaiia's geo-fence logic. BetaCraft sends address, Gaiia decides.
Plan selection, payment, install scheduling Gaiia Full post-click checkout experience
WF-05, WF-08, WF-09, WF-10 (post-order workflows) Gaiia Order confirmed, install scheduled, install failure, welcome series
Gaiia → HubSpot API connection Gaiia BetaCraft defined the property names and event structure. Gaiia built the pipe.
Construction stage events (WF-02 trigger) EPC EPC sends build stage updates → Gaiia → HubSpot. BetaCraft needed the exact event names to configure WF-02.

The scope boundary that needed managing

Emily confirmed a key Gaiia detail mid-project: WF-10 (Customer Welcome) might be owned by Gaiia, not BetaCraft. I flagged this as pending Emily's written confirmation with a hard deadline of April 14 — because if BetaCraft built WF-10 and Gaiia also ran it, customers would receive duplicate welcome sequences. The boundary had to be decided before the workflow was built, not discovered after.

04 / The integration seam

The technical detail that couldn't be guessed.

The hero section CTA — "Check Availability" — looks simple from the outside: user types their address, clicks the button, lands on the Gaiia checkout with their address pre-filled. Behind it is a precise integration contract that required reading Gaiia's technical documentation in full before writing a line of code.

Gaiia's checkout accepts a pre-filled address via a URL-encoded JSON parameter. The structure looks straightforward — but one detail caused silent failure if missed: premise (house number) and thoroughfare (street name) must be separate fields. Combining them into a single address string results in no error, no warning — just no prefill on Gaiia's side, and a confused customer re-entering their address from scratch.

// Correct — Gaiia prefill structure { "country": "USA", "premise": "6864", // house number ONLY "thoroughfare": "Terreno Drive", // street name ONLY "line2": "", "locality": "Castle Rock", "region": "CO", "postalCode": "80104", "county": "" } // Silent failure — do NOT combine into one field "premise": "6864 Terreno Drive" // prefill fails, no error thrown

I used Mapbox autocomplete in the Astro hero section — matching Gaiia's own internal address tooling — which returns structured address components that map directly to Gaiia's expected fields. The redirect constructs the encoded JSON from those components and passes it as the address query parameter. Worst case if something is malformed: Gaiia falls back to showing its own address form. No broken experience for the customer, but the goal was to skip that step entirely.

Why this required a technical PM

A PM without the technical background would have read "pass the address to Gaiia" and assumed the dev would figure out the format. The format wasn't in the main Gaiia docs — it was in a separate PDF Tyler shared. I read it, identified the field-splitting requirement, and specced the integration correctly before handing it to the developer. No rework required.

05 / HubSpot lifecycle layer

Seven workflows. One customer journey mapped end to end.

The HubSpot scope was the most complex part of the project to define — because it required understanding not just what BetaCraft would build, but what data would flow in from two external parties (Gaiia and EPC) and what events those parties were responsible for firing. I scoped all seven workflows before the dev team touched HubSpot.

ID Workflow Trigger source Purpose
WF-01 Pre-Registration Gaiia → HubSpot Nurture prospects during construction wait
WF-02 Construction Updates EPC → Gaiia → HubSpot Push build-stage updates to pre-registered contacts
WF-03 Stall Detection Gaiia → HubSpot Flag contacts with no lifecycle progression
WF-04 Service Available Gaiia → HubSpot Alert pre-registered contacts when their area goes live
WF-06 High-Intent Escalation Gaiia → HubSpot Surface high-intent contacts for direct follow-up
WF-07 Re-engagement HubSpot (time-based) Win back contacts who dropped off without converting
WF-11 Backlog Suppression EPC → Gaiia → HubSpot Suppress oversubscribed areas to manage demand

WF-02 and WF-11 depended on EPC sending build-stage events through Gaiia. Before those workflows could be configured in HubSpot, I needed the exact event names and property values EPC would use — because HubSpot's trigger logic is string-matched. I raised this as a blocking dependency early and got it resolved before the dev team reached the HubSpot build phase.

06 / Dependency management

The gates that could have broken the launch.

A four-week delivery with three independent external parties meant dependency management wasn't optional — it was the primary risk surface. I mapped every external dependency at kickoff and tracked each one as a blocking item.

Hard gate

Design sign-off by April 14 — or the April 30 launch moves

Week 2 started with design review. If Emily and Jeffrey didn't approve by April 14, the dev phase couldn't begin and the launch date would slip by exactly the number of days the review ran over. I made this a named gate in the kickoff document, not a footnote.

Dependency

Gaiia → HubSpot API connection is Gaiia's pipe, not BetaCraft's

BetaCraft configured HubSpot to receive events from Gaiia. But the connection itself — Gaiia firing events to HubSpot — was Gaiia's responsibility. I confirmed the point of contact at Gaiia (Tyler) early and made clear that full HubSpot workflow testing was blocked until that connection was live.

Dependency

EPC event names needed before WF-02 and WF-11 could be built

HubSpot triggers match on exact string values. The construction-stage event names EPC would send through the chain had to be confirmed before those workflows could be configured — otherwise we'd build against guessed property names and have to rework the triggers post-launch.

Dependency

Gaiia signup base URL and product slugs — needed before hero CTA could be built

Every "Check Availability" button on every page pointed to Gaiia's white-label checkout URL. That URL was specific to the Link Broadband Gaiia instance. Without it confirmed by Tyler, no CTA on the site could be tested end-to-end.

Hard gate

WF-10 ownership confirmed by Emily before build

The Customer Welcome workflow could not be built by BetaCraft until it was confirmed Gaiia wouldn't also run one. Duplicate welcome sequences would have been the first thing a new customer experienced after signing up. I escalated this as a blocking decision with a named deadline — April 14 — not a vague "we should clarify this".

07 / Outcomes

What launched on April 30.

Full marketing site launched in 4 weeks

Homepage, neighbourhood pages with status badges, pricing overview, support, admin panel, and legal shell — all live on schedule.

Gaiia address prefill integration live with zero silent failures

Mapbox autocomplete → structured JSON → Gaiia redirect working correctly at launch. The field-splitting requirement handled before build, not discovered after.

7 HubSpot workflows configured and ready for Gaiia connection

All BetaCraft-owned workflows built, tested against expected event structures, and documented. Blocked only on Gaiia's API connection — which was Gaiia's deliverable, not BetaCraft's.

Lighthouse 90+ on technical SEO

Sitemap, robots.txt, schema markup, meta tags, and GA4 + HubSpot tracking all shipped to specification.

Scope boundary held — no Gaiia work absorbed into BetaCraft

The explicit ownership table written at kickoff meant that when questions about the checkout or post-order experience came up mid-build, the answer was already documented. No scope creep in either direction.

Admin panel shipped — Link team can operate without a developer

Status banners, neighbourhood updates, and operational announcements are all self-serve. Link Broadband doesn't need to raise a ticket every time they need to update the site.

08 / Reflection

What multi-party integration actually demands.

The complexity on this project wasn't the code. The Astro build, the Mapbox integration, the HubSpot workflows — all of that was well within the team's capability. The complexity was the coordination surface: three external parties, each with their own systems, APIs, timelines, and assumptions about what the others were handling.

The PM job on an engagement like this is less about managing the team and more about managing the interfaces. Every integration seam is a potential gap where two parties each think the other is handling something. I made it my job to find those gaps before they became post-launch problems — mapping every handoff, naming every blocking dependency, and getting written confirmation on anything ambiguous before the build reached the point where it mattered.

The Gaiia integration is the clearest example. Reading Tyler's PDF and catching the premise/thoroughfare separation requirement wasn't a developer task — it was a PM task, because it determined the spec the developer would build against. Getting that wrong would have meant a silent failure in production that looked like a working feature until a customer noticed their address wasn't being passed correctly. The technical background meant I could read the document, understand the implication, and write the spec precisely — without a back-and-forth between Tyler, the developer, and me to decode it.