Arsalan Faysal – Automation & RevOps Blog

Rebuilding a Scalable CRM for a Multi-Location Kids Activity Franchise

Written by Arsalan Faysal | May 25, 2026 12:52:12 AM
7 Priority Workstreams
60+ Active Zaps Audited
189 Combined Zap Steps (Top 2)
~70% Zap Reduction Target

Most HubSpot audits reveal a handful of misconfigured properties, a few duplicate contacts, and some workflows that nobody turned off when a campaign ended. This one was different. A multi-location kids activity franchise — programs running from Foundation level through to Ultra+, serving hundreds of families across multiple club locations — had built a functioning CRM on top of a 60-Zap automation stack, two of which ran 94 and 95 steps respectively, and none of which had ever been formally documented or audited. The franchise was growing. The system was not scaling. This is the full rebuild.

The brief covered seven priority workstreams, shared simultaneously: parent-child contact architecture, Zapier reduction, contact management audit, pipeline review, automation and task management, Facebook and Messenger integration, and custom reporting. They also attached their full Zap inventory — a spreadsheet mapping every active automation touching HubSpot. That document told the real story of what had been built and what was quietly failing.

What follows is the complete technical breakdown of every workstream: the architecture decisions, the diagnostic findings, the replacement strategy, and the exact sequence of implementation. The client has been anonymised. The methodology is transferable to any multi-location service business with a comparable setup.

· · ·

Understanding the Business Model Before Touching Anything

Before a single property is created or a single Zap is switched off, the business model must be fully mapped. CRM configuration that ignores business model specifics produces technically clean infrastructure that serves nobody.

The operating model here has three characteristics that make it genuinely unusual compared to a standard B2C or B2B HubSpot setup:

  1. The buyer and the participant are different people. A parent pays, enrolls, and communicates with the club. A child attends. Standard HubSpot contact objects model one person. Every piece of personalization — birthday emails, achievement notifications, level-up announcements — requires knowing the child's data, not just the parent's email address. This is the root cause of Priority 1.
  2. Program progression is the primary lifecycle signal. In a typical SaaS or services business, lifecycle stage maps to pipeline stage: lead → MQL → SQL → customer. Here, lifecycle has a second axis: which program level is the child enrolled in? Foundation, Alpha Younger, Alpha Older, Gutsy Girls, Delta, Delta+, Ultra, Ultra+ — each with its own onboarding sequence, achievement framework, class change logic, and level-up announcement. The current Zap stack has one separate automation for nearly every combination. That is why there are 60+ Zaps.
  3. Multi-location means multi-owner assignment. Each club location has its own staff and its own inbox. A contact enrolled at the Frankston location should be owned by the Frankston manager, receive communications from the Frankston inbox, and appear in Frankston-specific reports. This adds a spatial dimension to everything from contact ownership to Facebook Messenger routing.

With the model understood, every architecture decision has a clear test: does this configuration correctly serve a parent who pays, a child who participates, a club that delivers, and a management team that needs to see performance data across all locations simultaneously?

· · ·

Priority 1: Parent-Child Contact Architecture

This is the structural foundation. Every other workstream — Calendly integration, Zapier replacement, personalized email flows, pipeline accuracy — is downstream of getting this right. If the data model is wrong, all the automation in the world produces confidently wrong outputs.

The Core Problem with Standard HubSpot Contacts

HubSpot's default contact object models one individual. For a business where the customer relationship involves a parent and one or more children, the default approach is to pile child-specific data onto the parent contact record as custom properties: child_1_first_name, child_1_dob, child_2_first_name, and so on.

This approach fails at scale for several reasons. A family with three children enrolled in different programs generates three sets of child properties on one contact record. Workflow enrollment triggers — "send a birthday email when the child's birthday is this week" — cannot differentiate between children on the same contact. Level-up automations fire based on a single program field that cannot represent multiple simultaneous enrollments. Achievement emails send with the wrong child's name because there is no clean way to know which child triggered the Udio event for a parent with multiple enrolled kids.

The Correct Architecture: HubSpot Contact Associations

HubSpot supports custom association types between objects. The correct implementation for this business creates child contacts as separate HubSpot contact records, associated to their parent contact via a custom association type.

PARENT-CHILD CONTACT ARCHITECTURE
──────────────────────────────────────────────────────────────────────

PARENT CONTACT (one per family account)
  Standard properties:
  • First Name, Last Name, Email, Phone
  • Club / Location (select — matches club assignment)
  • Contact Owner (assigned to club manager)
  • Lifecycle Stage (Lead → Customer)
  • Marketing Contact Status
  • Membership Status (Active / Inactive / Alumni)
  
  Communication properties:
  • Email Opt-in Status
  • SMS Opt-in Status
  • Last Contacted Date
  • Lead Source

         │
         │ [Custom Association: "Parent of" / "Child of"]
         │
         ▼

CHILD CONTACT (one per enrolled child — linked to parent)
  Child-specific properties:
  • child_first_name (text)
  • child_last_name (text)  
  • child_date_of_birth (date)
  • child_age (calculated — auto-updated via workflow)
  • child_program_level (select — Foundation/Alpha/Delta/Ultra etc.)
  • child_club_location (select — matches parent location)
  • child_udio_id (text — for Udio sync matching)
  • child_enrollment_date (date)
  • child_status (Active / On Hold / Cancelled / Alumni)
  
  Achievement tracking:
  • last_achievement_level (text)
  • last_achievement_date (date)
  • total_achievements_count (number)
  • current_level_start_date (date)

Property Setup: What Gets Created and Where

In HubSpot, navigate to Settings → Properties → Contact Properties and create a property group called Child Details. All child-specific properties live in this group. This keeps the parent contact record organized — child properties are grouped together and do not pollute the standard contact view.

The child_age property requires a workflow to stay current. Create a HubSpot workflow triggered on Contact Birthday is today (using the child_date_of_birth field) that recalculates and updates child_age annually. This means age-based triggers — "child turns 8 next month, send program advancement email" — are always working against accurate data without manual updates.

CRITICAL ARCHITECTURE DECISION — ASSOCIATION TYPE
OPTION A
Child as Associated Contact (Recommended) Child records are full HubSpot contact objects with their own record, associated to the parent via a custom association type labelled "Parent" / "Child". This allows child-specific workflows, child-specific properties, and independent reporting on child data. Requires HubSpot Pro or above for custom association types.
OPTION B
Child Properties on Parent Record (Not Recommended) Add numbered child property groups to the parent contact (child_1_name, child_2_name, etc.). Works on Starter. Breaks down for families with 3+ children. Cannot trigger per-child workflows cleanly. Creates reporting complexity. Only viable if HubSpot plan does not support custom associations.
OPTION C
Custom Object for Child (Future-State) HubSpot Enterprise allows fully custom objects. A "Child" custom object with its own properties and pipeline is the cleanest long-term architecture. Migration path from Option A is straightforward. If the business is on Enterprise or plans to upgrade, design Option A to be exportable into a Custom Object structure later.

Data Import: Adding Child Associations to Existing Contacts

The brief specifies an update-only import using data exported from Udio (the club management software). The import strategy:

  1. Export from Udio. Pull a full export of all active members with parent email, child first name, child last name, child DOB, program level, and club location. The parent email is the matching key — it must match the existing HubSpot contact email exactly.
  2. Prepare the import file. Structure as a flat CSV with one row per child. Include a parent_email column for matching. Every child property maps to the corresponding HubSpot property name.
  3. Import as "Update only" — do not create. In HubSpot's import tool, select Update existing contacts only (not "Create and update"). This prevents ghost contacts from being created for emails that don't already exist in HubSpot.
  4. Create child contact records with association. HubSpot's import tool supports creating associated records — select "Import contacts and their associations" and specify the association type as the custom Parent/Child type created in the previous step.
  5. Post-import validation. After import, run a HubSpot list query for child_date_of_birth is unknown and child_program_level is unknown. Any contacts in these lists were not successfully updated and need manual review.

Keeping the Data Live: Udio → HubSpot Sync

The one-time import gets the architecture right. Keeping it current requires a live sync mechanism. Every time a child changes program, moves to a new club, cancels, or earns an achievement in Udio, the corresponding HubSpot child contact record needs to reflect that update.

This is currently handled (partially and inconsistently) by the existing Zap stack. The Zapier reduction workstream (Priority 2) addresses which of these can be replaced with native HubSpot workflows and which still require an integration layer. The architectural principle: Udio is the system of record for membership data. HubSpot is the system of record for communication and commercial data. Data flows one direction — Udio → HubSpot — for membership events. Data flows the other direction — HubSpot → communication tools — for all marketing and engagement outputs.

Calendly Integration Review

Currently, the Calendly→HubSpot integration is handled by Zap #14 (14 steps) and Zap #21 (95 steps) — the two most complex Zaps in the stack. Zap #14 fires when a routing form is submitted without a booking (hot lead capture). Zap #21 fires on every Calendly booking, creates a HubSpot deal, branches by program interest across multiple paths, updates lifecycle stage, assigns contact owner, and segments into lists.

The question in the brief: can this be replaced with the native HubSpot-Calendly integration or a Cloudflare Workers solution?

Option Custom Field Mapping Conditional Branching Child Contact Creation Deal Creation Owner Assignment Verdict
Native HubSpot-Calendly ✅ Standard fields ❌ No branching ❌ Single contact only ⚠️ Basic deal creation ⚠️ Round-robin only Cannot replace Zap #21 alone
Native + HubSpot Workflows ✅ Via native sync ✅ Workflow branching post-sync ⚠️ Workflow can create association ✅ Workflow deal creation ✅ Property-based routing Recommended — replaces 80% of Zap #21
Cloudflare Worker ✅ Full API access ✅ Full conditional logic ✅ Can create + associate child contact ✅ Full deal creation ✅ Location-based assignment Best for hot-lead capture (replaces Zap #14)
Keep Existing Zaps ⚠️ Current — no child association Fragile, costly, undocumented — replace

The recommended architecture: use the native HubSpot-Calendly integration as the data sync layer for standard contact and booking data, and a HubSpot workflow to handle all branching, deal creation, lifecycle stage updates, and owner assignment. The Cloudflare Worker handles the hot-lead routing form path (Zap #14 replacement) specifically because it involves a webhook payload that the native integration does not expose.

Critical requirement for the new integration: when a new Calendly booking is made, the workflow must create both a parent contact and a child contact association. Current Zap #21 does not do this — it creates the parent contact and deals but does not create the child association. This is why new bookings exist in HubSpot without linked child records until the post-booking import sync catches them.

· · ·

Priority 2: The Zapier Audit — 60 Zaps, What Stays, What Goes

The full Zap inventory reveals a system that was built incrementally — one automation added every time a new program level launched, a new event type needed handling, or a new communication requirement appeared. Nobody ever went back to consolidate. The result is a Zapier account that has become load-bearing infrastructure: everything depends on it, nothing is documented, and removing any piece of it without fully understanding its downstream effects risks breaking member communications.

The audit categorizes all active Zaps into four buckets: Replace with native HubSpot, Replace with Cloudflare Worker, Consolidate into fewer Zaps, and Keep as-is (for now).

Bucket 1: Replace with Native HubSpot Workflows

These are Zaps where Zapier is acting purely as a trigger relay or a simple property updater — work HubSpot can do natively without any middleware.

Zap # Zap Name Current Steps Replacement Effort
18 RK Onboarding SMS Prompt 3 HubSpot workflow → ClickSend native action (if available) or HubSpot workflow → webhook to ClickSend. Trigger: contact added to onboarding list. Same logic, zero Zapier dependency. Low — 1–2h
62 Booking Cancelled (Unable to Attend) 2 HubSpot workflow triggered by Udio data property update (booking_status = Cancelled). Enrol in re-engagement sequence natively. Low — 1–2h
12 Fam Jam Engagement Increase 5 Replace Google Sheets trigger with HubSpot form submission or list enrollment trigger. Low priority. Low — 2–3h

Bucket 2: Consolidate — The Class Change Confirmation Zap Explosion

This is the most immediately actionable finding in the entire Zapier audit. Currently, there are 17 separate Zaps (Zaps #29–42, #7) that all do the exact same thing: when a participant moves to a different class in Udio, send a class change confirmation email via Gmail. The only difference between each Zap is which program level it covers.

Seventeen Zaps. One function. This pattern appeared because every time a new program level was launched, someone duplicated the existing class change Zap and updated the program name. Nobody went back to consolidate.

CURRENT STATE: 17 separate 2-step Zaps
──────────────────────────────────────────────────────────────────
  Zap 29: Ultra+ Moving → Gmail confirmation
  Zap 30: Ultra Moving → Gmail confirmation
  Zap 31: Delta+ Moving → Gmail confirmation
  Zap 32: Gutsy Girls Delta Moving → Gmail confirmation
  Zap 33: Alpha+ Younger Moving → Gmail confirmation
  Zap 34: Alpha+ Older Moving → Gmail confirmation
  Zap 35: Gutsy Girls Younger Moving → Gmail confirmation
  Zap 36: Gutsy Girls Older Moving → Gmail confirmation
  Zap 37: Alpha Younger Moving → Gmail confirmation
  Zap 38: Alpha Older Moving → Gmail confirmation
  Zap 39: Momentum Moving → Gmail confirmation
  Zap 40: Future Leaders Moving → Gmail confirmation
  Zap 41: Delta Moving → Gmail confirmation
  Zap 42: Chase Tag Moving → Gmail confirmation
  + 3 more variants
  
  Total: 17 Zaps × 2 steps = 34 Zap steps
  Monthly Zap tasks consumed: ~34 tasks per class change event

FUTURE STATE: 1 HubSpot workflow
──────────────────────────────────────────────────────────────────
  Udio triggers webhook → HubSpot contact property updated
  (child_program_level change detected)
  
  HubSpot Workflow:
  Trigger: child_program_level property is updated
  Action 1: Branch by new child_program_level value
  Action 2: Send appropriate confirmation email template
  (17 email templates, one workflow, one trigger)
  
  Monthly Zap tasks consumed: 0

The same consolidation pattern applies to the New Enrolment Confirmation Zaps (Zaps #44–54, #6) — 12 separate Zaps that each send a program-specific enrollment confirmation email when a new purchase is made in Udio. Same trigger event, same action type, different email content. These 12 Zaps collapse into one HubSpot workflow with branch logic by program level.

And the Level-Up Announcement Zaps (Zaps #5, #55–61) — 8 Zaps that each fire when a participant completes a program level and send a collaboration announcement email. Same consolidation applies.

Combined, these three categories represent 37 Zaps doing the same pattern of work that one consolidated HubSpot workflow per category can handle natively.

Bucket 3: Replace with Cloudflare Worker

Zap # Zap Name Why Cloudflare Effort
14 Calendly Routing Form → HubSpot (Hot Lead Capture) Requires webhook payload parsing from Calendly API. Native integration doesn't expose routing form responses. Cloudflare Worker receives the webhook, parses all custom question fields, creates/updates HubSpot contact with full property mapping, creates child association where child data present. Medium — 6–10h
16 Nurture Campaigns | Add To List (Hot Lead No-Show) Works in tandem with Zap #14. The delay logic (wait until trial date, then add to nurture) is cleaner in a HubSpot workflow triggered by the contact property set by the Cloudflare Worker. Replace Zap, preserve logic in HubSpot workflow. Low — 2–3h (post Worker build)

Bucket 4: High Complexity — Audit Before Touching

Two Zaps in the stack must not be touched without a complete step-by-step map and full regression testing plan:

DO NOT MODIFY — REQUIRES FULL AUDIT FIRST
ZAP 17
Step 2: Signed Up, Onboarding & Actions (94 steps) Fires on every new Udio purchase/enrollment. Identifies program level, updates HubSpot contact and deal, adds to onboarding sequences, assigns tasks, updates lifecycle stage and contact owner. 94 steps means this Zap contains a significant amount of business logic — branching, filtering, property mapping — that must be fully documented before any replacement is attempted. Estimated audit time: 8–12h. Replacement estimated time: 20–30h. Do not turn this off without a tested replacement running in parallel.
ZAP 21
Step 1: Create Deal / Update Contact / Needs Segmentation (95 steps) Fires on every Calendly booking. Creates HubSpot deal, associates contact, branches by program interest, updates contact properties, sets lifecycle stage, assigns owner, segments into lists. This is the primary new-lead pipeline entry point. If this Zap fails silently, new leads do not enter the HubSpot pipeline at all. Estimated audit time: 8–12h. Replace with native Calendly integration + HubSpot workflows — but only after the workflow replacement is fully tested in a sandbox subaccount.
ZAP 13
Course Completion, Onboarding & Actions (91 steps) Fires on Udio Purchase Moved events (class change). At 91 steps this is the third major complex Zap. Handles program level identification across Foundation through Ultra+ and routes into appropriate HubSpot sequences. Document fully before any modification.

Zap Audit Summary: Before and After

Category Current Zaps Current Steps After Consolidation Zap Reduction
Class Change Confirmations 17 34 0 (1 HubSpot workflow) –17 Zaps
New Enrolment Confirmations 12 24 0 (1 HubSpot workflow) –12 Zaps
Level-Up Announcements 8 16 0 (1 HubSpot workflow) –8 Zaps
Achievement Workflows (Levels 1–3) 3 + 1 = 4 56 + 43 = 99 1 Zap (Udio trigger) + 1 HubSpot workflow –3 Zaps
Attendance & Alerts 4 30 2 (keep missed sessions; simplify cancellation) –2 Zaps
Calendly Pipeline (Hot Lead + Booking) 3 133 1 Cloudflare Worker + 1 HubSpot workflow –2 Zaps
Simple 2–3 step Zaps (SMS, re-engagement) 3 8 0 (HubSpot workflows) –3 Zaps
High-complexity Zaps (17, 21, 43) — keep pending audit 3 129 3 (short term) 0 (phase 2)
TOTALS ~60 ~550+ ~7 ~85% reduction
"The Zapier stack wasn't broken. It was the architecture of a business that had been adding automations faster than it was consolidating them. 37 Zaps doing 3 things. That's not complexity — that's a maintenance liability masquerading as automation." Arsalan Faysal — Revenue Systems Architect
· · ·

Priority 3: Contact Management Audit

Marketing vs Non-Marketing Contacts

HubSpot charges for marketing contacts — the threshold matters for billing and it directly affects which contacts receive marketing emails. The audit confirms three common misconfiguration patterns in this setup:

  1. Alumni contacts marked as marketing. When a family cancels (Zap #43 fires), the contact lifecycle stage updates to "Customer" closed lost. But marketing contact status is not explicitly set to Non-Marketing in the same automation. These contacts continue consuming marketing contact quota and receiving emails they shouldn't receive.
  2. Zapier-created contacts not getting lifecycle stage set. Contacts created by Zap #21 (Calendly booking) should enter as Leads. If the lifecycle stage property mapping in the Zap fails or maps incorrectly, contacts land with no lifecycle stage and no marketing status — they are invisible to marketing segmentation.
  3. Triggers for marketing status are not centralized. The correct architecture is a single HubSpot workflow (or workflow branch) that fires on any lifecycle stage change and sets marketing contact status accordingly: Lead and MQL → Marketing. Closed Lost, Unsubscribed, Alumni → Non-Marketing. Having this logic distributed across multiple Zaps and ad-hoc workflow settings creates inevitable inconsistencies.

Duplicate Contact Investigation

Duplicate contacts in this setup are almost certainly being created by the Calendly integration. Here is the most common mechanism:

DUPLICATE CREATION PATHWAY (MOST COMMON)
──────────────────────────────────────────────────────────────────
  1. Parent submits Calendly routing form (Zap #14 fires)
     → Creates HubSpot contact with email: sarah@example.com
     → Lifecycle: Lead
  
  2. Parent books Calendly session (Zap #21 fires, seconds later)
     → Searches HubSpot for email: sarah@example.com
     → If Zap #21's search step times out or returns no match
       (race condition between Zap #14 and Zap #21)
     → Creates SECOND HubSpot contact with same email
  
  Result: 2 contacts, same email, different property populations.
  
  Secondary duplicate pathway:
  3. Same parent books again weeks later with slightly different email
     (sarah.smith@gmail.com vs sarahsmith@gmail.com)
     → HubSpot email matching fails
     → New contact created, no merge, split history
  
  Third pathway:
  4. Udio sync Zap fires for a parent contact that was manually
     created by a club manager (with phone but no email)
     → New contact created from Udio export with email
     → Manual contact still exists, not merged

The fix operates at three levels. First, implement HubSpot's native Duplicate Management tool (Settings → Data Management → Duplicates) and run a full deduplication pass on the existing database. Second, fix the race condition in the Calendly integration by replacing the Zap sequence with the Cloudflare Worker + HubSpot workflow architecture — the Worker uses HubSpot's upsert API endpoint, which finds-or-creates rather than always-creates. Third, add email normalization to all intake points: convert to lowercase, strip whitespace, before attempting the HubSpot contact lookup.

Contact Owner Assignment Failures

The brief notes that some contacts are not being assigned to a user/owner. Three root causes:

  1. Club/location property not populated at creation time. Zap #21 attempts to assign contact owner based on program interest or location, but if the relevant property is empty (e.g., a routing form submission with no location selected), the owner assignment branch in the Zap finds no match and the contact lands unassigned.
  2. Owner lookup by name fails when staff turnover occurs. If a Zap is hardcoded to find the owner "John Smith" and John has left the business, the lookup returns null and the assignment silently fails. Fix: map assignments by a club location property rather than a person property.
  3. New subaccounts not configured in the routing logic. When a new club location was added, the Zap branching logic was not updated to include the new club. All contacts from that location fall through to the default branch (unassigned).

The correct fix: create a HubSpot workflow that triggers on Contact Owner is unknown AND Club Location is known and assigns the correct owner based on club location property. This workflow runs as a catch-all, ensuring no contact stays unassigned regardless of how it was created. Update this workflow whenever a new club is added or staff change.

· · ·

Priority 4: Pipeline Review and Deal Conversion Accuracy

The brief's specific goal: accurate deal conversion rate data. This is currently impossible to report on correctly because the pipeline has three structural problems.

Problem 1: Deals Are Not Being Closed Consistently

Conversion rate calculation requires knowing how many deals entered a stage and how many progressed to the next stage. If deals are never moved to Closed Won or Closed Lost — if they simply sit in an open stage indefinitely — the denominator for any conversion rate calculation is wrong.

Zap #43 (Accounts & Unenrolment — Purchase Cancelled) does attempt to close deals as Closed Lost when a Udio purchase is cancelled. But there is no corresponding mechanism to close deals as Closed Won when a Udio purchase is confirmed. Deals that convert to active members stay open in the pipeline indefinitely, inflating the open deal count and making funnel conversion metrics meaningless.

Fix: when Zap #17 fires (New Purchase/Enrolment) and successfully updates the HubSpot contact to Customer, a HubSpot workflow should simultaneously move the associated deal to Closed Won. The deal close date is set to today. This is a one-step addition to the existing onboarding workflow.

Problem 2: Pipeline Stages Don't Map to the Actual Sales Process

The typical HubSpot default pipeline stages (Appointment Scheduled → Qualified → Proposal → Closed Won / Lost) do not reflect the reality of this business. The actual sales motion is:

RECOMMENDED PIPELINE STAGE STRUCTURE
──────────────────────────────────────────────────────────────────
  Stage 1: Trial Booked
           Trigger: Calendly booking confirmed (Zap #21 replacement)
           Exit: Trial date arrives
  
  Stage 2: Trial Attended
           Trigger: Trial session attendance confirmed in Udio
           Exit: Parent contacts club OR books follow-up
  
  Stage 3: Offer Made / Follow-Up
           Trigger: Staff sends enrollment offer or trial follow-up
           Exit: Parent enrolls OR goes silent
  
  Stage 4: Enrolled — Closed Won
           Trigger: Udio purchase confirmed (Zap #17 replacement)
           Close date: Set automatically
  
  Stage 5: Trial No-Show / Disqualified — Closed Lost
           Trigger: No attendance after 7 days of trial date OR
                    parent explicitly opts out
           Close date: Set automatically

Problem 3: One Pipeline for Multiple Program Types

Consider creating separate pipelines for Trials vs Renewals vs Upsells. A family enrolling for the first time has a completely different sales motion than an existing family upgrading their child from Alpha to Delta. Mixing both deal types in one pipeline means conversion rates blend two fundamentally different journeys, making the data actionable for neither.

· · ·

Priority 5: Automations and Task Management Audit

Task Creation Audit

The brief flags task creation as an area needing review. In HubSpot, tasks are often created by workflows to prompt follow-up actions by sales or club staff. The common failure patterns:

  • Tasks created for contacts with no owner. A task assigned to no one is never completed. It sits in an unassigned task queue that nobody reviews. This is the task equivalent of the owner assignment problem — fix the contact owner assignment and task assignment resolves automatically.
  • Duplicate tasks from redundant workflows. If both a Zap (e.g., Zap #17, Step 2 Onboarding) and a HubSpot workflow fire on the same enrollment event, two tasks may be created for the same action. As part of the Zapier reduction, map every task creation trigger in Zapier and identify whether a HubSpot workflow is also creating the same task.
  • No task completion follow-up. Tasks that are created but not completed within a set timeframe should trigger a follow-up — an escalation notification to the club manager, or re-enrollment in a reminder sequence. Currently, overdue tasks simply sit overdue with no automatic escalation.

Workflow Health Check

Run a full HubSpot workflow audit using the following framework:

Workflow Status Check How to Check Common Finding Action
Enrollment count = 0 (30+ days) Workflows → Sort by Enrolled Workflow trigger changed or list it depends on was deleted Investigate and either fix or deactivate
Error rate > 5% Workflows → History tab → Filter by Errors Property referenced in workflow was renamed or deleted Fix property reference or update workflow
Workflow with no owner Workflows → Created by filter Staff member who created it has left; nobody owns the logic Reassign to current team member with documentation
Re-enrollment enabled on sequences that shouldn't re-enroll Workflow Settings → Re-enrollment tab Contacts receive onboarding sequences every time they're re-enrolled in a list Disable re-enrollment on one-time sequences
Active workflows with Zapier dependency Search workflow actions for "webhook" steps Workflows that fire webhooks to Zapier — should these be refactored? Tag for review during Zapier reduction phase
· · ·

Priority 6: Facebook and Messenger Integration — Multi-Club Inbox Architecture

The brief's goal: automated response flows for Facebook and Messenger across multiple club locations, with each club having its own inbox and sub-inboxes, reducing phone call volume, and enabling customers to book or get answers entirely through social channels.

Inbox Architecture: One Inbox Per Club

HubSpot's Conversations tool supports multiple connected inboxes. The architecture for a multi-location setup:

HUBSPOT CONVERSATIONS INBOX STRUCTURE
──────────────────────────────────────────────────────────────────

INBOX: Frankston Club
  ├── Channel: Facebook Page (Frankston Facebook Page)
  ├── Channel: Facebook Messenger (Frankston Page Messenger)
  ├── Channel: Email (frankston@[brand].com.au)
  └── Default Owner: Frankston Manager (HubSpot user)
  
INBOX: [Club 2 Name]
  ├── Channel: Facebook Page ([Club 2] Facebook Page)
  ├── Channel: Facebook Messenger ([Club 2] Messenger)
  ├── Channel: Email ([club2]@[brand].com.au)
  └── Default Owner: [Club 2] Manager
  
[Repeat for each club location]

INBOX: General / Brand Level
  ├── Channel: Brand Facebook Page
  ├── Channel: Brand Website Chat
  └── Default Owner: Head Office / Round Robin

Each club's Facebook Page must be connected separately in HubSpot (Settings → Inboxes → Connect a channel → Facebook Messenger). A HubSpot user with admin access to the Facebook Page is required for the connection. If club managers do not have admin access to their club's Facebook Page, this must be resolved at the Facebook Business Manager level before HubSpot configuration begins.

Automated Response Flows: The Conversation Framework

HubSpot's chatflow tool (Conversations → Chatflows) handles the automated response sequences. For the Messenger channel, the flow should cover the four most common inbound inquiry types:

Inquiry Type Automated Response Path Handoff Point
New enquiry / "What programs do you offer?" Bot asks age of child → branches by age group → sends program overview for relevant age → offers trial booking link (Calendly) If user asks a question not covered by bot: assign to club inbox for human response
Existing member enquiry ("What time is my child's class?") Ask for membership email → look up contact in HubSpot → send class schedule details from contact properties If contact not found or question requires staff knowledge: assign to club inbox
Class change request Collect details → create HubSpot ticket → assign to club manager → send confirmation that request received Club manager resolves in Udio + closes ticket in HubSpot
Cancellation / pause request Acknowledge request → collect reason → create HubSpot ticket with cancellation tag → assign to club manager Triggers a retention workflow: club manager receives task to call the family within 24h

The retention workflow on cancellation attempts is the highest-value automation in this entire workstream. A Messenger message saying "we're thinking of cancelling" is a churn signal that currently goes unanswered until a human sees it, hours or days later. An automated "I'm sorry to hear that — can I ask what's making you consider cancelling?" response, followed by a task assigned to the club manager to call within 24 hours, captures the churn risk at the moment of intent.

· · ·

Priority 7: Custom Reporting Dashboards

Custom reporting requirements are being provided separately by the client. However, the structural changes in Priorities 1–6 directly determine what becomes reportable. The reporting architecture depends on the data architecture being correct. Three dashboards that become immediately valuable once the parent-child structure and pipeline stages are correctly set up:

Dashboard 1: Membership Health (Operational)

Intended audience: Club managers. Refreshes daily.

  • Active members by club location (child contact count, status = Active)
  • New enrollments this month vs last month (by club)
  • Cancellations this month vs last month (by club)
  • Contacts with missed 3+ sessions in last 30 days (at-risk list)
  • Open tasks by club manager (overdue tasks flagged)

Dashboard 2: Pipeline Performance (Sales)

Intended audience: Head office / franchise leadership. Refreshes weekly.

  • Trial bookings this month (deals in Stage 1)
  • Trial attendance rate (Stage 2 / Stage 1)
  • Trial-to-enrollment conversion rate (Closed Won / Stage 1)
  • Average days from trial booked to enrolled
  • Deal conversion rate by club location
  • Lead source breakdown (where are trial bookings coming from?)

Dashboard 3: Retention and LTV (Strategic)

Intended audience: Franchise owner. Refreshes monthly.

  • Active member count trend (12-month view)
  • Churn rate by club and by program level
  • Average enrollment duration (time from enrollment date to cancellation date)
  • Program level distribution (how many children at each level?)
  • Achievement completion rates by level (using child_achievement data)

None of these reports are buildable accurately until the pipeline stages are correctly configured (Priority 4), child contact records have program level data (Priority 1), and deals are being consistently closed Won/Lost (Priority 4 fix).

· · ·

Implementation Sequence: The Right Order of Operations

The seven priorities in the brief are sequenced by urgency. The correct implementation order is different — it is sequenced by dependency. Getting it wrong means rebuilding work.

Week Work Why This Order Hours
Week 1 Parent-child property setup. Child contact object creation. Custom association type. Import template preparation (not import yet). Everything else depends on data structure being correct. Do not touch Zaps, pipelines, or workflows until contacts are modelled correctly. 8–12h
Week 1–2 Zapier audit: document Zaps #17, #21, #13 step-by-step. Map every property they write. Map every branch condition. Cannot replace what you don't fully understand. Documenting before touching is non-negotiable for the 3 complex Zaps. 16–20h
Week 2 Consolidate class change confirmation Zaps (17→1 workflow). Consolidate enrolment confirmation Zaps (12→1 workflow). Consolidate level-up announcement Zaps (8→1 workflow). Quick wins. 37 Zaps to 3 workflows. Low risk — each Zap is simple, replacement is straightforward. Immediate Zapier task volume reduction. 10–15h
Week 2–3 Udio data export → format import file → run update-only import to add child contact associations to existing parents. Post-import validation. Once property structure is confirmed from Week 1, the import can run safely. 8–10h
Week 3 Pipeline restructure: create new stages, add Closed Won trigger to Zap #17 (interim), run deduplication pass, fix owner assignment workflow. Pipeline accuracy and contact cleanliness are co-dependent. Fix them together. 8–12h
Week 3–4 Build Cloudflare Worker for Calendly hot-lead capture (Zap #14 replacement). Build native Calendly + HubSpot workflow integration (Zap #21 replacement). Test in parallel before switching off Zaps. Run replacement in parallel before switching off existing Zaps. Validate that all custom fields map correctly and child contact associations are created. 15–20h
Week 4–5 Facebook Messenger inbox setup per club. Chatflow automations. Retention workflow on cancellation intent. Infrastructure must be stable before adding new inbound channels. Setting up Messenger inboxes on a broken contact model creates more duplicates. 12–16h
Week 5–6 Custom reporting dashboards. Marketing contact status audit and workflow. Task management audit and escalation workflow. Reports are only accurate once data structure, pipeline, and contact management are correct. Build these last. 10–15h
Ongoing Document Zaps #17, #21, #13 fully → build HubSpot workflow replacements → test in sandbox → cut over with rollback plan. The 3 complex Zaps are Phase 2. Rushing them risks breaking the entire enrollment pipeline. 40–60h
· · ·

Hours, Rate, and What This Engagement Actually Requires

The brief budgeted $15–$35/hour. Phase 1 (Weeks 1–6) represents approximately 70–100 hours of implementation work. Phase 2 (Zaps #17, #21, #13 replacement) represents another 40–60 hours. Total engagement scope: 110–160 hours over 2–3 months.

At the lower end of the budget range ($15–$20/hour), this work will attract implementers without the HubSpot custom associations experience, Cloudflare Workers capability, or Zapier audit methodology that this engagement requires. The Zap #21 replacement alone — a 95-step Zapier automation that is the primary new-lead pipeline entry point — requires someone who can read complex Zapier branching logic, reverse-engineer all property mappings, build the equivalent HubSpot workflow, and test it without ever turning off the existing Zap until the replacement is confirmed working.

That is not $15/hour work.

The realistic market rate for this engagement — someone with HubSpot Pro/Enterprise implementation certification, Cloudflare Workers capability, and franchise/multi-location CRM experience — is $65–$120/hour. Scoping it as a fixed-price project at approximately $8,000–$12,000 for Phase 1 and $4,000–$6,000 for Phase 2 is more appropriate and protects both parties from scope ambiguity.

· · ·

Final Thoughts: What a Rebuilt HubSpot Looks Like at the End

At the end of this engagement, the infrastructure looks like this: every family in the system has a parent contact linked to one or more child contacts with accurate program level, DOB, and enrollment data. Every Calendly booking creates both the parent and child records automatically with the correct owner assigned based on the club location selected in the booking form. The Zapier stack has gone from 60+ Zaps to approximately seven, with the three highest-complexity Zaps replaced by documented, testable HubSpot workflows.

A parent who books a trial receives a confirmation email that mentions their child by name and includes the specific program details for the relevant age group. When their child completes a program level, they receive an achievement email from the club manager's inbox — not a generic brand mailbox. When a parent sends a Messenger message asking what time their child's class is, they get an answer within seconds from an automated flow that looked up their contact record. When they say "we're thinking of stopping," the club manager has a task assigned to their queue within two minutes.

The reporting dashboard shows the franchise owner the trial-to-enrollment conversion rate for each club, the churn rate by program level, and the active member trend — all updated weekly, all sourced from data that is accurate because the underlying architecture was built correctly.

None of this is complicated when the foundation is right. All of it is impossible when the foundation isn't.

In This Article Understanding the Business Model Priority 1: Parent-Child Architecture Priority 2: The Zapier Audit Priority 3: Contact Management Priority 4: Pipeline Review Priority 5: Automations Audit Priority 6: Facebook & Messenger Priority 7: Reporting Dashboards Implementation Sequence Hours & Rate Reality Check Final Thoughts
Stack in This Build
HubSpot Pro CRM + automation hub
Zapier Legacy middleware (being reduced)
Cloudflare Workers Webhook middleware replacement
Calendly Lead + trial booking capture
Udio Club management / MoR
ClickSend SMS delivery
Meta / Messenger Per-club inbox automation