Field Service Connect puts the booking software a home-services business already runs — ServiceTitan's Scheduling Pro, Housecall Pro's booking page, a Jobber request form — onto its own website. The customer books on the shop's pages; the job lands in the system the office already works from. Nothing about dispatch, the pricebook, or the technician app changes.
The problem
A shop running ServiceTitan is a bigger shop, and its website was almost certainly built by an agency on a retainer. That agency's one irreplaceable job is keeping the Scheduling Pro button working — so "we'll rebuild your site" sounds like "we'll break your booking."
At the smaller end the problem is the mirror image. A shop on Housecall Pro or Jobber has a booking link it can only share: pasted into a Google Business Profile, texted to a customer, buried in a footer. It never becomes part of the site.
Either way the site and the booking flow are two separate things, and the shop is paying somebody to keep them stapled together.
The fix
A self-contained feature module under app/Features/FieldService/ that renders the shop's existing scheduler as an ordinary page row. It is deliberately not a booking system — Online Booking is that, and a shop with ServiceTitan should leave it off. This is the opposite choice: their flow, our pages.
Three ways to show it, picked once for the whole site under Dashboard → Field Service:
| Setting | What it renders | Who it's for |
|---|---|---|
| ServiceTitan — Scheduling Pro | The Schedule Engine widget, from the site's own Scheduling Pro API key | Shops on ServiceTitan |
| Another scheduler — embed its booking page | The shop's hosted booking page in a frame | Housecall Pro, Jobber, anything with a shareable booking URL |
| Another scheduler — link to its booking page | A button that opens the booking page in a new tab | Anything whose page refuses to be framed |
Whether it sits in the page or opens over it is chosen per placement, by which row you add — see below.
Setup
- Settings → Features → turn on Field Service Connect.
- Dashboard → Field Service → pick the booking software.
- ServiceTitan: paste the Scheduling Pro API key (ServiceTitan → Scheduling Pro → Widget → Installation), then email ServiceTitan support and ask them to add this website to your Scheduling Pro allowed origins. This step is not optional and it is the one people miss — see the warning below.
Anything else: paste the booking link the software gives you to share. It must be an
https://address; anything else is refused at save time rather than rendered into a broken frame. - Open the page you want it on → add a row → Contact → Scheduler.
Scheduling Pro fails silently on a site it doesn't know
The Schedule Engine script asks ServiceTitan for its configuration before it renders anything, and ServiceTitan answers only for an origin on the account's allowed list. On a site that isn't on that list the request is refused, the script throws to the browser console, and the page simply has no widget — no error, no placeholder, nothing a client would recognise as a problem.
So a blank spot where the scheduler should be almost always means the whitelisting request hasn't gone through yet, not that the key is wrong. The settings page carries this warning next to the key field for the same reason.
Putting it on a page
Two rows under Contact in the editor's row picker. Both are hidden unless the feature is on.
| Row | What it is |
|---|---|
| Scheduler | A heading, a line of copy, and the booking form sitting in the page. Use it on a dedicated booking page. |
| Book Online Band | A compact call-to-action strip — heading, one line, and a button that opens the scheduler over the page. Use it part-way down a service page or the home page. |
Which one you choose is the inline-vs-button decision; there is no site-wide switch for it, because a band's copy does not suit a full-page form and vice versa. Button text, colours and spacing are edited on the row itself like any other.
A booking page shown in a frame cannot open over the page — only ServiceTitan's widget can — so the band's button opens a framed or linked scheduler in a new tab instead.
Privacy and cookie consent
The Scheduling Pro widget loads a third-party frame and pushes events into window.dataLayer / Google Analytics, so on installs with Cookie Consent enabled it is gated behind the marketing category: the page renders a placeholder with an Accept button, and the vendor script is not fetched at all until the visitor consents. The same applies to an embedded booking page.
The link option is never gated — a link that opens in a new tab sets no cookies until the visitor follows it.
Content Security Policy
The site serves a script-src policy, and ServiceTitan's widget is injected by JavaScript rather
than written into the page — so the policy cannot see it coming. The scheduler component declares
embed.scheduleengine.net in the policy itself whenever the ServiceTitan widget is on the page.
Nothing to configure, but worth knowing if you are debugging a blank scheduler: a CSP refusal shows
as a console message naming script-src, while the whitelisting problem above shows as a 401 from
api.scheduleengine.net. A blank frame with neither message means the key is right and the
origin is approved, and the widget is simply still loading.
The embedded-booking-page and link options need no policy entry — a frame is not script.
What it is not
- Not a booking system. It does not hold availability, send confirmations, or take payment. That is Online Booking, which is the right choice for a shop that has no field-service software. Running both is possible but rarely what anyone wants.
- Not a sync. Bookings made through the widget go straight to the vendor and are never mirrored into this site's database, CRM, or dashboard. A shop's own software stays the record.
Settings reference
| Key | Meaning |
|---|---|
field_service.scheduler.provider |
servicetitan | embed_url | link |
field_service.servicetitan.scheduling_pro_key |
The Scheduling Pro widget key. Encrypted at rest, but published to visitors by design as data-api-key — it is on SecretField::BROWSER_PUBLIC for the same reason the Google Maps key is, and is shown readable in the dashboard so an admin can check which account is wired. |
field_service.scheduler.embed_url |
The hosted booking page. Absolute https:// only. |
Inline-vs-button, the button's text, and every class live on the row, not here: settings own which scheduler and its credential, rows own how it looks. A site-wide "how it appears" control would have had no visible effect once each row pins its own, which is worse than not offering it.