Operations Manual

Everything needed to run Crestline Growth, written for someone who starts with zero context. Read sections 0–2 once. Use sections 3–8 each time a new client comes in. Use sections 9–12 to run the book week to week.

0Start here

How to read this manual, and what you need before your first day.

How this manual is written

  • Bold text inside a step is the exact label of a button, menu, or field on your screen. Look for that exact wording.
  • Text in a box like this is something you copy and paste exactly. Do not retype it. Do not change it.
  • Each numbered step is one action. Do the steps in order. Do not skip steps.
  • A line that starts with Result: tells you what you should see after a step. If you do not see it, stop and go to section 11.
  • Blue boxes explain a word or a concept the first time it appears. Read them once; after that you can skip them.

What you need on day one

Ask the account owner for these before you start. You cannot operate without the first four.

AccessWhat it is for
This page's linkThe manual and, through the HQ page, every portal and tool. Treat the link like a password. Never send it to a client.
GoHighLevel agency loginThe CRM where all client accounts live. Log in at app.apexagency.io.
Meta Business Manager accessWhere the ads run. Each client grants partner access to their own ad account during onboarding.
Google Drive accessThe ads library folder with the finished videos and images you upload for every client.
Whop team accessWhere client payments land. Day-to-day billing runs itself; you need Whop only to see payouts or handle a dispute.
Blooio accountThe iMessage texting service. You buy one number per client there (section 6).
An email inbox for alertsThe internal notification emails (failed provisioning, failed charges) go to the team address set inside the GoHighLevel workflows.
What is GoHighLevel? GoHighLevel (you will also see "GHL") is the CRM platform the whole operation runs on. It holds contacts, calendars, text automations, forms, and the landing pages. Crestline's copy of it is branded and lives at app.apexagency.io. One "sub-account" inside it = one roofing client's complete world.

1How the business works

Read this once. Everything else in the manual is a zoom-in on one of these steps.

Crestline Growth is a lead-generation agency for roofing companies. The deal with every client is the same: Crestline runs Facebook and Instagram ads that get homeowners to book a free roof inspection on the client's calendar, and the client pays a fixed fee for every inspection that gets booked. The card is on file; charges and refunds happen automatically.

The life of one lead

  1. A homeowner sees the client's ad on Facebook or Instagram and taps it.
  2. They land on the client's landing page and answer a short survey (homeowner? roof age? zip code?).
  3. The system checks their zip code against the client's approved service area. Outside the area, they are routed to a polite "we do not serve your area" page.
  4. Inside the area, they pick a time on the client's booking calendar.
  5. Automatic text messages confirm the booking and remind them before the inspection.
  6. The moment the inspection is booked, the client's card on file is charged the per-inspection fee. If the homeowner cancels or does not show, the fee is refunded automatically.

The life of one client

  1. Sales call. A prospect books a call. You use the Growth Snapshot Calculator on the call (section 3).
  2. Close. The closer fills in two fields on the contact and adds one tag. Automation creates the billing account, the card-save link, and the service agreement, and texts the card link during the call (section 4).
  3. Onboarding form. The client receives one email, fills in the onboarding form, and signs the agreement inside it. The moment the form is submitted, the system builds their entire CRM account automatically and emails them their login (section 5).
  4. Setup. You finish the parts that need human hands: domain, one access token, calendar hours, texting number, and a few guided pastes. A portal generates every paste for you and checks your work (section 6).
  5. Kickoff call. You walk the client through their login and set expectations (section 7).
  6. Ads. You build their ad campaign following the playbook, using the ready-made ad library (section 8).
  7. Steady state. Leads book, charges run, texts send — all automatic. You check in weekly (section 10).
What is "the Worker"? Behind the scenes, one small server (a "Cloudflare Worker") does the automated jobs: zip-code checks, building each client's page header, firing their ad pixel, charging and refunding inspection fees, and creating new client accounts. You never touch it directly. You control it entirely through the two portals in section 2. If this manual says something happens "automatically", the Worker is doing it.

2The systems you use

Seven links do everything. All of them are one click from Crestline HQ.

SystemWhat you do thereWhen
Client Setup portalRegister and verify a new client's backend. It holds the full click-by-click setup guide (16 steps) and generates every code paste per client.Once per new client
Billing portalSee every client's card status, charges, refunds, and failures. Change a client's fee. Make a new card-save link.Weekly, and when billing questions come up
Ads Manager PlaybookThe complete recipe for launching a client's Meta ads: tracking setup, campaign settings, and the ad library with ready copy.Once per new client
Growth Snapshot CalculatorThe tool you share on screen during sales calls.Every sales call
GoHighLevelThe CRM. The sales pipeline lives in the sales sub-account. Each client has their own sub-account with their contacts, calendar, funnel, and automations.Daily
Ads library (Drive)The finished ad videos and images. You upload these into every new client's campaign.Once per new client
Meta Business ManagerWhere campaigns run and where you read performance.Weekly
What is a sub-account? GoHighLevel splits the agency into separate walled-off accounts, one per client, called sub-accounts (the interface sometimes says "location"). Switch between them with the account picker at the top left of GoHighLevel. Two sub-accounts matter beyond the clients' own: the sales sub-account (the pipeline of prospects and closed deals — the onboarding automations run here) and the master snapshot (the template every new client account is cloned from — do not edit it casually; see section 13).
What is a funnel? The set of web pages a lead moves through: the landing page with the survey, the booking page with the calendar, and the thank-you page. Each client's funnel lives inside their sub-account, under Sites → Funnels, and is served on their own domain (for example getpriorityroofing.com).
What is a tag? A label on a contact in GoHighLevel, like a sticker. Automations add tags to record what happened (for example in-service-area or subaccount-created) and other automations react to them. When this manual says "check the tags", open the contact and look at the list of labels on their record.

3The sales call

The calculator turns the pitch into the prospect's own numbers.

  1. Before the call, open the Growth Snapshot Calculator in a browser tab.
  2. On the call, share your screen and fill in the prospect's real numbers as they give them to you (average job value, close rate, volume).
  3. Walk through the output with them. The point is that they watch their own numbers produce the result — do not rush this part.

The offer you are selling is fixed and simple: Crestline runs the ads and the booking system; the client pays a flat fee per booked inspection, card on file, refunded automatically for cancels and no-shows. Do not invent custom deal structures.

4Closing a client

When a prospect says yes, the closer does four small actions in the sales sub-account. Everything else fires on its own. This whole section happens while you are still on the call with them.

The closer's actions

  1. In GoHighLevel, switch to the sales sub-account and open the prospect's contact record.
  2. Fill in the Business Name field with the client's company name as customers know it (the name on their trucks — for example "Priority Roofing"). Legal names come later, on the form.
  3. Fill in the Inspection Fee field with the agreed per-inspection price as a plain number. Type 85, not "$85" and not "85 dollars".
  4. Add the tag onboarding_needed to the contact.
    Result: within about one minute, the contact's Card Save Link and Agreement Link fields fill in, the tag onboarding-ready appears, and the client receives a text with the card-save link.
  5. Stay on the call while the client opens the text and saves their card. The page is Crestline-branded, takes card or bank details, and does not ask them to create any account.
    Result: the tag card-on-file appears on the contact when the card is saved.
If the card does not get saved on the call: do not chase it manually. An automatic reminder sequence nudges the client until card-on-file appears. You can always fetch a fresh card link from the Billing portal — open the client's row and copy their card-save link.
If the tag onboarding-error appears instead of onboarding-ready: a required field was empty or wrong — almost always Business Name or Inspection Fee. Fix the field, remove the onboarding_needed tag, and add it again. Re-running is always safe; it updates the same records rather than creating duplicates.

What happens next, automatically

  • The client receives one onboarding email with a single button.
  • The button opens a page that shows their service agreement (already signed by Crestline, with their fee filled in) and the onboarding form.
  • The form collects their legal details, service-area zip codes, logo, certifications, pricing, inspection availability — and their signature, which executes the agreement.
  • After the form, they land on the card page (skipped automatically if the card is already on file), then a confirmation page.

You do nothing during this phase. Your next action begins when the form arrives — section 5.

5The form comes in — the account builds itself

Submitting the onboarding form triggers the big automation. Know what it does so you can verify it and pick up where it stops.

What happens on its own

  1. A complete new sub-account is created for the client, cloned from the master snapshot: funnel pages, calendar, text automations, tags — everything.
  2. A login for the client is created (admin of their own sub-account only) with a generated password like Maple-River-4821.
  3. The client is pre-registered in the Setup portal: a new row appears in its table with their zip codes, account ID, phone, and timezone already filled in.
  4. The tag subaccount-created lands on the sales contact, and the client receives a welcome email with their login and password.

What you check (2 minutes)

  1. Open the Setup portal and confirm the client's row appeared in the table.
  2. Click the row's Login button.
    Result: you see the client's login email, their generated password, and their account ID. This is the same login the welcome email gave them. You will read it out again on the kickoff call.
If the internal alert email "Provisioning failed" arrives: open the sales contact and read the situation from its tags. The two common causes: the Approved ZIP Codes answer on the form contained no zip codes (fix the field on the contact, then resubmit the form or re-run the workflow), or the client's email already has a GoHighLevel login somewhere (rare — see section 11). Re-running is always safe: the system never creates a second account for the same contact; it only retries the piece that failed.

6Finishing the setup — the per-client checklist

The automation built the account. A human finishes the parts that platforms refuse to automate: the domain, one access token, a few pastes, calendar hours, and the texting number. The Setup portal walks you through every click and generates every paste — this section is the ordered checklist of what to do there and around it.

Because the account was auto-provisioned, skip guide steps 1, 2, and 4 — the portal row already exists with the zips and account ID filled in. The portal's intro says the same thing.
#TaskWhereNotes
1Connect the client's funnel domainClient's sub-account → Settings → DomainsBuy a clean domain if the client has none for the funnel (pattern: getclientname.com). Point it at the funnel per GoHighLevel's on-screen DNS instructions. Then open the portal row's Edit and type the domain in.
2Create the access tokenSetup portal, guide step 3Made inside the client's sub-account (Settings → Private Integrations). The guide shows every click. Paste it into the portal row's Edit.
3Tags, test contact, VerifyGuide steps 5, 6, 7Verify runs real checks against the client's account and shows green or red per check, with the fix written next to any red. Do not continue until the checks are green.
4Landing-page pastesGuide steps 8 and 9The row's Pastes button generates the exact code and URLs. Follow the guide's paste locations word for word.
5Billing checkGuide step 10 → Billing portalThe billing client and fee already exist from the close. Confirm the row shows the card as saved.
6Live funnel testGuide step 11Submit the funnel yourself once with a test zip. Confirms the whole chain end to end.
7Header bannerGuide step 12 (the row's Banner button)Upload the logo from the client's form submission, tick the certifications they selected, type their Google rating and review count. The banner then renders on their pages automatically.
8Tracking-code checkGuide step 13A 60-second confirmation that the three tracking blocks rode in with the account clone.
9Calendar hoursGuide step 14Set the client's inspection days, hours, and buffer from their form answers — always by editing the existing calendar, never by creating a new one.
10Texting number (Blooio)Guide step 15Buy one Blooio number for the client, authorize it for their sub-account, and switch each Send SMS step's channel to it. Message text stays untouched.
11A2P registrationClient's sub-account → Settings → Phone NumbersUS carrier registration for business texting. The form collected everything it asks for (legal name, EIN, address). Follow GoHighLevel's registration wizard.
12AdsGuide step 16 → Ads PlaybookCovered in section 8.
What is the access token ("PIT")? A Private Integration Token is a long key, generated inside one sub-account, that lets the backend act inside that sub-account: tag leads, write settings, read the calendar. Each client has their own. It is shown once at creation — copy it straight into the portal. If it is ever lost, create a new one and paste the new one into the portal row; nothing else needs changing.

7The kickoff call

One short call after setup. The client walks away logged in and knowing exactly what happens next.

  1. Before the call, open the client's row in the Setup portal and click Login so their credentials are in front of you.
  2. Have them go to app.apexagency.io and read the login email and password out to them. They already have both in their welcome email; this is a walkthrough, not a reveal.
  3. Tell them: "First thing, change that password — click your profile icon, then settings, then change password." Wait while they do it.
  4. Have them connect their personal calendar (Google or Outlook) under their profile's calendar settings, so inspections appear where they already look.
  5. Show them where booked inspections appear (Calendars) and where leads appear (Contacts).
  6. Set expectations, in this order:
    • Ads go live within a few days; the first leads usually follow within days of that.
    • Every booked inspection charges the card on file at the agreed fee. Cancels and no-shows are refunded automatically. Their card statement will show the payment processor's name, WHOP, not Crestline.
    • Leads get automatic confirmation and reminder texts; the client's job is to show up to the inspections and sell.

8Launching the ads

The Ads Manager Playbook is the complete recipe — every setting captured from a live, performing campaign. This section tells you the order and the rules; the playbook has the clicks.

  1. Get partner access to the client's Meta ad account (the onboarding form confirmed they will grant it).
  2. Do Part A of the playbook: create the client's dataset (their tracking pixel), connect it, and put the dataset ID into the client's row in the Setup portal. The portal feeds it to their pages automatically — never paste Meta's pixel code into the funnel yourself; the playbook explains why.
  3. Do Part B: build the campaign with the exact captured settings. One campaign, one ad set. The zip list for targeting comes from the portal row's Pastes panel (item F).
  4. Do Part C: download the videos and images from the ads library, upload them as ads named exactly after their filenames, and use the copy templates with the client's details filled into the placeholders.

The rules that protect the budget

  • One campaign, one ad set, many ads. Never split the same audience into multiple ad sets — it fragments Meta's learning and raises costs.
  • Never restart or duplicate a running campaign to "fix" it. Restarts reset the learning phase.
  • Kill an ad only when it has spent about $20 with zero landing-page views. Before that, let it run.
  • Judge results by leads inside GoHighLevel, not by Meta's own attribution numbers. Meta over-credits ads that were merely seen.
  • Do not pre-shrink the zip targeting on a hunch. After about a week, open the region breakdown in Ads Manager and remove areas the data shows are eating budget without producing.
  • Never touch a client's own pre-existing campaigns. Crestline's campaign is the one named CRESTLINE | CLIENT NAME | #1.

9How the money works

Billing is fully automatic. Your job is to watch it and to handle the rare failure.

The automatic loop

  • An inspection gets booked → the client's card is charged the per-inspection fee, once per appointment, never twice.
  • The appointment is marked cancelled or no-show → the charge is refunded in full, automatically.
  • A charge fails (expired card, insufficient funds) → the system retries once a day, three times, then stops and tags the situation for you.

What you do in the Billing portal

  1. Open the portal. Each row is a client: card status, total billed, refunds, failures, and their history.
  2. To change a client's fee: open their row, edit the fee, save. The new fee applies from the next booked inspection. No other system needs updating — the agreement viewer and charges all read from this one number.
  3. To get a client a fresh card-save link (new card, expired card): open their row and copy the card-save link. Send it to the client; the page recognizes an existing card and offers "use a different card".
Charges suspended for a client? That means three retries failed. Get a new card saved (fresh card link, above). Charging resumes with the next booked inspection. For the inspections that went uncharged during the gap, decide commercially: either let them go or settle them directly with the client.

Payments land in Crestline's Whop account. The client's statement says WHOP — tell clients this up front (it is in the kickoff script) so nobody disputes an unfamiliar charge.

10Weekly operations

Thirty minutes, once a week, same order every time.

  1. Open the Billing portal. Scan every row for failed charges or a card that stopped working. Handle per section 9.
  2. In GoHighLevel, open each client's sub-account → Contacts. Confirm new leads arrived this week and carry the in-service-area tag. A client with zero new leads and an active campaign is a red flag — go to section 11.
  3. In each client's sub-account → Calendars, confirm inspections are being booked, not just leads created.
  4. In Meta Ads Manager, per client: check spend is pacing, check cost per lead against that client's history, and after the first week of any campaign, prune non-producing regions from the region breakdown (section 8 rules).
  5. Check the internal alerts inbox. Every automated failure emails you; none of them age well.

11When something breaks

Find the symptom, apply the fix. Every automated failure also writes a plain-language reason — read the error before anything else; it usually names the fix.

Onboarding and account creation

SymptomCauseFix
Tag onboarding-error after the closeBusiness Name or Inspection Fee empty or malformed on the sales contactFix the field. Remove and re-add the onboarding_needed tag. Safe to repeat.
"Provisioning failed" alert; tag provisioning-errorUsually: the form's Approved ZIP Codes answer contained no zip codes (the client wrote "50 mile radius")Turn the answer into an actual zip list in the contact's field, then re-run the provisioning workflow (or have the form resubmitted). The system never duplicates an account on re-runs.
Provisioning alert says the email already has a loginThe client's email is attached to some other GoHighLevel account anywhere in the worldThe sub-account was still created. Get a different email from the client, put it in the contact's email field, re-run. Only the login user is retried.
Client never saved a cardThey dropped off after the callThe chase sequence is already nudging them. To push manually, copy their card link from the Billing portal and text or email it yourself.

Funnel and leads

SymptomCauseFix
Every lead lands on the out-of-area page, even good zipsThe form's redirect is not passing the zip to the next pageOpen the funnel's form settings → On Submit → Redirect URL, and re-paste item B from the client's Pastes panel in the Setup portal. The redirect must contain postal_code.
Leads arrive but have no in-service-area / out-of-service-area tagThe service-area workflow's webhook is failing — wrong token or the client's row is unverifiedRun Verify on the client's row in the Setup portal. Red checks print their own fix. Then re-check guide step 9's webhook settings.
Testing the workflow shows a bare "Internal Server Error"The test contact's zip field is empty — the system rejects blank zips on purposePut a real zip in the test contact's postal-code field (guide step 6 warns about exactly this) and test again.
Header banner missing on the client's pagesBanner not saved yet, or the funnel domain is not in the portal rowSetup portal → the row → Banner: logo + badges + rating + count, save. Confirm the domain is in Edit. The preview under the Banner panel shows exactly what the pages will show.
Client's texts say REPLACEME instead of their company nameThe account's fill-in values were never writtenRun Verify on the client's row — it writes the company name, phone, and location wording into the account as part of its checks.
Meta shows clicks but the pixel records nothingDataset ID missing from the portal rowSetup portal → the row → Edit → put the dataset ID in the pixel field, save, then Verify. Playbook Part A covers where the ID comes from.

Billing

SymptomCauseFix
Tag inspection-billing-failedA charge declinedNothing yet — automatic daily retries are running (three attempts).
Tag inspection-billing-suspendedThree retries failedFresh card link from the Billing portal → client saves a working card → charges resume with the next booking. See section 9 for the uncharged gap.
Client disputes a "WHOP" chargeThey did not recognize the processor's namePoint them at the kickoff explanation and their signed agreement (the agreement viewer link is on their sales contact). The Billing portal's history shows the exact appointment behind every charge.
An inspection was billed but should not have beenEdge caseMark the appointment cancelled or no-show in the client's calendar — the refund fires automatically off that status.

If the error is not in these tables

  1. Read the error text itself — every failure written by the system names its cause and, in most cases, the fix and which guide step to redo.
  2. Run Verify on the affected client's Setup-portal row. It re-tests the whole connection and pinpoints the broken layer.
  3. If a fix requires changing server code or infrastructure (nothing in this manual does), that is developer territory — escalate to whoever holds the Cloudflare account, with the exact error text.

12When a client leaves

Shut things down in this order so nothing charges and nothing dangles.

  1. In Meta Ads Manager, turn the client's campaign off. Do not delete it — history has value if they return.
  2. In the Billing portal, open the client's row and delete it.
    Result: no future inspection can be charged. Past records stay in Whop.
  3. In the Setup portal, delete the client's row there too.
    Result: their landing-page gate and lead tagging stop resolving. Their funnel effectively goes dormant.
  4. Cancel the client's Blooio number in the Blooio dashboard.
  5. Leave their sub-account alone for at least 90 days (their data, possible return), then the account owner can delete it from the agency if wanted.
Exception — the legacy clients. Diamond, Priority, and Tampa predate the portals and are wired into the backend directly, so they have no Setup-portal row to delete. If one of them leaves: turn off their ads and delete their Billing-portal row, and stop there. Their backend wiring is inert without ads and harmless to leave in place.

13Access and safety rules

The whole system is run through links that carry their own access. That is convenient and dangerous in equal measure. These rules keep it safe.

The rules

  1. The HQ link, this manual, the Billing portal, and the Setup portal are team-only. Treat each URL like a password. Never forward them, never paste them into a client-facing message, never post them anywhere public.
  2. The only links that ever go to a client: their card-save link, their agreement link, the onboarding form, their own funnel pages, and their own GoHighLevel login. Nothing else.
  3. Clients get admin of their own sub-account only. Never give a client agency-level access, and never do client work while switched into the wrong sub-account — check the account picker before every action.
  4. Do not edit the master snapshot sub-account unless you intend to change the template for every future client. Changes there do not affect existing clients; they ride into the next new account created. The placeholder values in it that read REPLACEME are deliberate — they make a missed setup step visible instead of silent. Do not "fix" them.
  5. Infrastructure — the Cloudflare account, the server code, the payment processor configuration — is not part of operations. Nothing in this manual requires touching it. If something ever does, escalate to the account owner rather than experimenting.

Client-facing page patterns (recognize them when you see them)

PageWhat it is
crestline-billing.pages.dev/card/…The branded card-save page. Generated per client; safe to send to that client.
crestline-billing.pages.dev/agreement/…The client's service agreement with their fee filled in, pre-signed by Crestline.
crestline-growth.com/onboarding-ncThe onboarding form every new client fills in.

Rebuilding a client account from scratch

If a client sub-account is ever damaged beyond repair, the master snapshot can be imported into a fresh sub-account (snapshot ID rq9O9VPIm7lqVHsoxxQY, permanent share link on the HQ page), and the client re-registered through the Setup portal's guide from step 1. Slow path, always available.