Internal SOP · Team
The per-contractor checklist for standing up a new sub-account from the snapshot: everything the clone cannot carry on its own, grouped by where the work happens so admin can move top to bottom without jumping around.
The written steps below are current and complete. Screenshots get added to each step as they are captured; the words will not change.
Each item is tagged with how it gets filled:
The provisioning job fires when the contractor submits the post-purchase onboarding form. It clones the snapshot into a new sub-account and prefills what the order form and the onboarding form already gave us, so admin opens an account that is already part-filled.
What it writes:
business_name, business_email, business_phone, business_address, and license_number when the onboarding form carried it. business_email is the contractor's buying email. It is the NPS match key the central webhook joins on, and the value the per-contractor NPS report token is derived from, so it must be the real buying email, not a placeholder.nps_token, computed from business_email. The NPS report and tile menu links read this so a contractor opens only their own report.nps_survey_link, re-pointed to the new sub's own cloned survey URL (the survey clones with a new URL per sub-account).tts_support_contact, the same support address for every contractor.The account exists with no login, so there is no access and no welcome email until we create the user at the end of the pass (Group E, step 12). This lets us finish the mini-site and the rest of the build before the contractor can get in. Creating that user is the single moment access and the welcome email turn on.
The clone brings the eighteen custom value slots in empty. They fill at four separate moments, each one the first point at which anybody knows the value. An empty slot partway through this checklist is the normal state, not a miss.
| Filled at | Values |
|---|---|
| Provisioning, before this checklist | business_name, business_email, business_phone, business_address, nps_token, nps_survey_link, tts_support_contact |
| The engine build, when his GHL record is pulled | license_number |
| The engine build, after brand discovery crawls his site | Business Profile logo and socials, logo, notifications_from |
| The engine build, once his brand docs are written | primary_color, secondary_color, his Brand Board |
| The engine build, when the handoff package is assembled | minisite_url |
| This checklist, by hand | review_link (Group D), the three Facebook values (Group H) |
| The platform, after vetting | vetted_badge |
The engine writes these with tools/tts_fulfillment/fill_sub_account.py, which refuses to overwrite a value that already holds something different. Every slot has had its moment by the time you reach Group E, which is why the full check lives there and not here.
Open the new sub-account. Run the verify checklist at the bottom of the Build Guide (Step 11): the 18 custom values, the custom fields (4 lead fields, 3 NPS fields, 2 response-timer fields, 2 co-owner fields), the pipeline stages, the calendar, the 8 published workflows, the chat widget, the NPS Survey, the menu links.
Settings > Business Profile: confirm business name, address, email and website carry what was passed on the create call. The logo and the four social links (Facebook, Instagram, YouTube, LinkedIn) arrive later, from brand discovery, so leave them alone here and confirm them at Group E step 14.
Settings > Custom Values: confirm business_email holds the contractor's real buying email, nps_token is set, and tts_support_contact holds the support address. All three come from provisioning (Group 0); the NPS report links break if either of the first two is wrong or blank. primary_color, secondary_color, minisite_url and logo fill during the engine build, so they are confirmed at Group E step 14 rather than here.
Mint it by hand: open the NPS Apps Script project (under the Google account that deployed it), set the email inside linkFor() to this contractor's business_email, Run, and paste the 20-character token from the execution log into the nps_token custom value. Then open the sub's Dashboard and confirm the Net Promoter Score widget shows the gauge, not a blank card. Its embed URL must carry both merge fields (contractor and token); a contractor-scoped URL without its matching token renders an intentionally blank page, so a blank widget means the token parameter or the custom value is missing.
The contractor connects their own Google or Outlook to the Consultation calendar. A calendar connection cannot be cloned.
Connect the contractor's Google Business Profile and Facebook so review requests can post.
The contractor connects their own Stripe for Invoice / Text-to-Pay.
Provision the phone number for the sub-account. There is a per-contractor telephony cost; see X-3. Set the number's friendly name to his business name: that name is what he sees on his own Phone System screen.
Use the documents collected on the onboarding call (CP-575 / EIN letter PDF, exact legal business name, business type, industry, EIN, business email, region). Until it clears, the missed-call text-back and SMS follow-ups stay dormant.
The License Number (license_number) custom value holds the full display string (e.g. "CA License #1234567"), written by the engine build from his contact record in the TTS admin sub-account, where the onboarding call collects it. It stays blank for trades that do not carry one; the email footer line then renders empty instead of broken. Confirm rather than type.
Set the Review Link (review_link) custom value. Once the GBP is connected (step 5), GHL auto-builds the review link at Reputation > Settings > Review Link. Just copy it from there and paste it into the custom value, no Place ID lookup needed. The NPS survey's promoter (9-to-10) end screen merges it, so this is filled once.
The nps_survey_link custom value is set by provisioning (Group 0), which reads the new sub's own cloned survey URL. Confirm it points at this sub-account's survey, not the template's. Fallback if provisioning did not set it: Sites > Surveys, copy the share URL, and paste it in by hand. The NPS email reads the link from here, so a wrong value points the email at the template's survey.
Create the login with permissions that keep them out of the workflow builder. Hold this step until the build is done: the account is provisioned with no user on purpose (Group 0), and creating the user is what turns on access and sends the welcome email. Do it only when the mini-site and the rest of the onboarding pass are finished and we want the contractor to get in.
Features and Limits. The feature toggles are set on the SaaS plan the contractor signs up under, not carried by the snapshot, so this is a confirm, not a rebuild.
Every slot has had its moment by now, so this is where an empty one is a real gap. Open Settings > Custom Values and Settings > Business Profile and confirm all of these carry his own values, not the template's and not blanks.
| Where | What |
|---|---|
| Custom Values | business_name, business_email, business_phone, business_address |
| Custom Values | license_number, blank only if his trade carries no license |
| Custom Values | logo, his logo image URL, served from ttscontractors.com |
| Custom Values | primary_color, secondary_color, his own hex values |
| Custom Values | minisite_url, his live /pros/<slug>/ address |
| Custom Values | notifications_from, no-reply@ plus his own domain |
| Custom Values | tts_support_contact, nps_token, nps_survey_link, review_link |
| Business Profile | logo, and the Facebook, Instagram, YouTube and LinkedIn URLs he has |
| Phone System | the number's friendly name reads his business name |
notifications_from is forHis own Speed-to-Lead and chaser alerts send from it. Homeowner-facing emails send from business_email instead, because they all tell her to reply. Blank, the alert sends from the address it is sent to.
A social URL he does not have stays empty. vetted_badge and the three Facebook values are filled elsewhere and are not part of this pass.
Walk it as if you were the contractor (Build Guide Step 11).
Once the trust badge is generated, the platform pushes it into the contractor's media, writes the URL into the Vetted Badge (vetted_badge) custom value, and the contractor gets the "here is your badge" email. The badge artifact itself is a platform build item, not built yet.
One token per sub-account powers every platform automation that reaches into the account: the social media fulfillment engine and the lead-routing that drops new leads into the contractor's pipeline. Create it early in the onboarding pass, since the social engine needs it from day one.
In the sub-account, go to Settings > Private Integrations and create a Private Integration Token. This is the newer token type, not the legacy "API Key" (the legacy key does not work with the v2 API the platform calls). Name it something like "TTS Platform." Grant the scopes below, then copy the token once (GHL shows it one time only) and store it where the platform reads it. Grant only these scopes; fewer is better.
Social media fulfillment scopes:
Platform scopes (add to the same token). This is the full access the platform needs to operate inside a contractor sub across everything we build, granted once so we never reopen a hundred tokens to add one box. Several names overlap with the social list; each scope is granted once, so do not double-add them.
Lead charges and the membership product bill the contractor as a contact in the TTS admin sub, not inside the contractor's own sub, so payments and invoice scopes live on the admin-sub token instead.
Skip this whole group for a contractor who does not run Facebook or Google ads. The Facebook workflow clones in with every account but stays dormant with no credentials, and the Google action is not built until the contractor runs ads, so nothing breaks if this is left undone. Applies to any member who runs their own ads and to members on paid ad management. The contractor does their part from the Contractor Conversion Tracking Setup SOP; the back-end click-by-click is the Conversion Tracking GHL Wiring SOP (admin). The steps here are the onboarding checkpoint.
The contractor connects their own Google Ads and Meta (Facebook) ad accounts in Launchpad / Integrations. This is the ad-account connection, separate from the Reputation Facebook connection in step 5.
The contractor pastes their Meta Dataset ID into the facebook_pixel_id custom value and their Conversions API token into facebook_conversion_api_token (Settings > Custom Values), or hands both to admin to fill if their permissions hide Custom Values. The Meta action reads both by merge field, so once they are set the Facebook side needs no workflow edit.
Confirm the two values above are set and that facebook_test_event_code_dev_only is blank (a test code left in place silently stops real events from reporting).
Once their account is connected and their conversion exists: select the conversion (named TTS Lead), set value 1 and USD, then turn Custom Mapping on and map GCLID/GBRAID/WBRAID to ad_gclid / gbraid / wbraid. This cannot be pre-built in the snapshot, because the conversion dropdown only fills from the connected account, and it cannot be done by the contractor, because Workflows are hidden from their user. Full steps in the Wiring SOP, Part 2. The Facebook side needs no per-sub workflow edit.
Put the contractor's Meta test-event code in facebook_test_event_code_dev_only, create a test lead so it gets the Ad Lead tag (or add the tag to a test contact), confirm the event lands in Meta Events Manager (Test Events) and Google Ads (conversion diagnostics), then blank the test code so live events report.
Things the contractor does themselves that the snapshot cannot do for them. Walk these on the onboarding call.
app.ttscontractors.com URLs, the same for everyone. The NPS report and tile links carry the business_email and nps_token merge fields, and GHL resolves both inside a menu link, so one static link in the snapshot scopes itself per sub-account once Group 0 has set those two values.