Think Build Implement Repeat
Case Study · Field-Service Automation

Every Booking Lands Straight on the Crew’s Route

A Danish ventilation-cleaning company took every booking by phone and e-mail, then re-typed it into the route planner their crews drive by. SpiderHunts replaced that with a custom WordPress plugin built for their existing site — not a platform they had to move onto. The customer’s address resolves to the technicians who actually cover it, the calendar only offers slots the crew can genuinely serve, and the confirmed job appears on the right route in the planner without anyone touching a keyboard. Nothing about how the office or the crews work had to change.

Field ServiceIndustry
Booking & DispatchProject Type
Denmark, nationwideCoverage
37 releasesAcross 4 milestones

Project Snapshot

The client (anonymised) cleans and services ventilation systems across Denmark with a small fleet of electric vans. Their crews are dispatched from a field-service route planner; their customers, however, could only book by calling the office during working hours. Every booking was taken by hand and typed into the planner a second time. SpiderHunts delivered a custom WordPress plugin — installed on the site they already had — that turns the website into the booking channel and keeps it in step with the planner in both directions. No migration, no new platform, no change to how the office and crews already work.

Industry
Ventilation cleaning · field service
Project Type
Booking & dispatch automation
Delivered As
Custom WordPress plugin on their existing site
Integrations
Route planner, address register, SMTP, maps, vehicle GPS
Languages
Danish + English, switchable
Scale
Live planner account with 5,400+ jobs
The Challenge

A Booking Channel the Crews Could Not Trust

Field service breaks the assumptions every off-the-shelf booking plugin is built on. A slot is not free because the office is open — it is free only if a technician who covers that postcode, performs that service, is working that day, and is not already booked somewhere else. Publish a calendar that ignores any of those conditions and the office spends its morning phoning customers back to move the appointment it just sold them.

Before SpiderHunts

  • Bookings only during office hours, by phone or e-mail — evenings and weekends went unanswered
  • Every booking typed twice: once into a note, once into the route planner
  • No way to tell a customer which technician covers their address, or whether that crew was free
  • Jobs the office created in the planner were invisible to the website, so the same hour could be sold twice
  • Quotes and the Danish craftsman tax deduction worked out by hand, per enquiry
  • Rescheduling and cancellations were phone calls, then more manual planner edits

After SpiderHunts

  • 24/7 self-service booking — four steps, in Danish or English
  • Zero re-typing — a confirmed booking is created in the route planner automatically
  • Postcode-matched crews — the system knows who covers the address and who does that service
  • One shared calendar — planner jobs consume website capacity within minutes
  • Priced instantly — size bands, per-unit pricing and the tax deduction calculated live
  • Customer-run changes — move, correct or cancel from a signed link in the e-mail
How It Works

Watch a Booking Travel From the Website to the Van

Five stages, all of them automatic. Nothing in this chain waits for the office to be at a desk. The walkthrough below runs on its own — hover to tilt the scene, or jump to any stage.

1

Service & price

Size bands, per-unit pricing and the tax deduction, calculated live.

2

Address → crew

Postcode matched to the technicians who actually cover it.

3

Real free slots

Only hours a covering crew can genuinely serve.

4

Planned in the field

Written into the route planner, on the correct route.

5

Confirmed & owned

Mails sent, and the customer can move or cancel it themselves.

Service & priceThe customer chooses a service and system size on the client’s own website.

Built Around Their Business

A Custom Plugin — So Nothing About How They Work Had to Change

The easy version of this project would have been to move the client onto a booking platform and let them adapt. We did the opposite: the whole system was written as a custom WordPress plugin for their existing site, wrapped around the tools and habits their office and crews already had. Nobody was asked to migrate, re-learn or re-key anything.

Their website stayed their website

No rebuild and no separate booking domain. The plugin installs on the WordPress site they already run, and the booking widget drops in through a shortcode or a floating button.

The crews kept their route planner

The planner the technicians already drive by stays the source of truth for the field. The website writes into it and reads back from it, rather than competing with it.

The office kept its habits

Staff can still create and edit jobs directly in the planner exactly as before — those jobs simply flow back and take capacity off the website calendar within minutes.

No new logins, no new software

Bookings, technicians, services, pricing and mail settings are all managed from the WordPress dashboard the client already logs into. There is no extra system to buy seats for.

Their rules, not a vendor’s

Danish pricing conventions, the craftsman tax deduction, per-unit pricing for multi-system homes, coverage by postcode range and route-density discounts are business rules a generic product simply does not have.

Owned outright, not rented

One plugin file, on their own hosting, with their own data and their own SMTP. No monthly platform fee, no vendor lock-in, and the source is theirs.

The Solution

What We Built

Everything ships as one WordPress plugin: the customer widget, the public REST API, the database schema, the e-mail engine and the office dashboard. There is no SaaS subscription in the middle and no second server to keep alive — install, activate, and the site is taking bookings.

01

Capacity-aware calendar

Availability is computed from real crews: coverage range, services performed, working hours, days off, and the jobs already on their route. Capacity drops as bookings land, and a fully-booked slot disappears rather than greying out.

02

Postcode-to-technician matching

Addresses resolve through the official Danish register; each technician holds a coverage range and the narrowest match wins. Postcodes nobody covers never reach the calendar — they get a call-back form instead.

03

Two-way route-planner sync

Website bookings are written into the planner as scheduled jobs; jobs the office creates there flow back and consume website capacity. A tail sync runs every few minutes, a full sweep nightly, resumable so a long import never dies half-done.

04

Route-density discount

If the customer’s address sits close to work the crew already has that day, the price drops automatically and the day is marked as a cheaper one. The discount is judged against live planner data and held through checkout, so what was promised is what is charged.

05

Instant, rule-based pricing

Size bands, per-unit pricing for multi-system homes, and the Danish craftsman tax deduction are all computed in the widget and repeated on the confirmation, so the customer sees the real number before committing.

06

Customer self-service

A signed link in the confirmation opens a page where the customer can move the booking to another genuinely free slot, fix details or cancel. Everything is pushed to the planner and re-confirmed by e-mail to both sides; changes inside the lead time are refused politely.

07

Branded transactional e-mail

Confirmations, change notices and office alerts are sent over the client’s own SMTP with a responsive HTML design — date and time tiles, price bar, referral offer and review badges built from text so they survive image blocking.

08

Office dashboard inside WordPress

Bookings, technicians, coverage, services, durations, pricing, opening rules, call-back requests and mail settings are all managed from the WordPress admin the client already logs into. Bookings can be edited from their card, and the planner and customer follow.

Technology

Tech Stack

Chosen so the client owns the whole thing: a standard WordPress install, one plugin, no external runtime.

WordPress Plugin (PHP 8) WP REST API React 18 + Vite MySQL / SQLite Previsto Field-Service API DAWA Danish Address Register Google Maps Geocoding Keatech Vehicle GPS API SMTP / PHPMailer WP-Cron background jobs HMAC-signed manage links Node + Express (dev harness)
What Changed

Results

The system runs on a live WordPress install wired to the client’s production route-planner account, and has been exercised against their real job data and real crews throughout the build.

Office hours → 24/7
When a customer can book
2 entries → 0
Manual re-typing per booking
5,400+ jobs
Live planner account kept in sync
~5 minutes
Until a planner change reaches the website
Nationwide
Postcode coverage, crew by crew
Move / cancel
Handled by the customer, not the office
DA / EN
Bilingual widget and admin
1 plugin
No SaaS, no second server to run
Engineering Notes

The Details That Decided Whether It Worked

Integration work is won or lost on the parts nobody specifies. Four that mattered here:

A job with no execution time lands on today’s route

The planner lays work out by an explicit execution timestamp, not by the date label on the record. Bookings pushed without it were created successfully, then filed on the day they were created — so a booking for next month appeared on this morning’s route and looked, to the office, like it had gone missing entirely.

The address has to be split before it can be driven to

Leaving the postcode inside the street line made the planner mark the job unresolvable: never geocoded, never route-planned. Splitting street, postcode and city sends it through geocoding normally. The planner also re-geocodes from its own text and overwrites any coordinates it is sent, which had to be designed around rather than fought.

A discount promised at step three must survive checkout

The route-density discount is judged from live planner data. An early version re-checked it at checkout with a short-lived cache, which opened a window where a customer could be shown a discounted price and charged the full one. The quoted decision is now carried through to the booking, and the price the customer accepted is the price that is written.

Two crews can cover one postcode — and both must be bookable

Assigning every booking to the single best-matching technician meant the calendar never counted the second crew, so one person could be booked twice at the same hour. Assignment now picks a covering technician who is actually free in that window, and the booking is only refused when every covering crew is busy — refused before anything is written locally or in the planner.

Questions

Frequently Asked Questions

Why build a custom booking system instead of using a booking plugin?

Off-the-shelf booking plugins sell time slots from a fixed opening-hours table. A field-service business does not have fixed capacity: a slot is only real if a technician who covers that postcode, performs that service, is working that day and is not already on another job somewhere else. That rule cannot be expressed in a generic plugin — and the moment the calendar shows a slot the crew cannot serve, the office is back on the phone rescheduling.

How does the system decide which technician a customer gets?

The customer types an address, which is resolved against the official Danish address register to a postcode. Each technician carries a coverage range, and the narrowest range containing that postcode wins. The chosen service narrows it further, because technicians can be restricted to specific services. If nobody covers the postcode, the widget stops asking for a date and offers a call-back request instead.

What does two-way sync with the route planner actually mean?

Bookings taken on the website are pushed into the planner as scheduled jobs — correct execution time, split address, task duration — so they appear on the crew’s route rather than on the day they happened to be created. Jobs the office creates directly in the planner flow back into the website calendar and consume capacity there. A tail sync runs every few minutes and a full sweep runs nightly.

Can customers change a booking without calling the office?

Yes. The confirmation e-mail carries a signed link to a self-service page where the customer can move the booking to another genuinely free slot, correct their phone number or comment, or cancel. Every change is written locally, pushed to the planner immediately, and confirmed by e-mail to both the customer and the office. Changes inside the configured lead time are refused, and the page asks the customer to call.

How is the system delivered and hosted?

As a single self-contained WordPress plugin. There is no external SaaS to subscribe to and no separate server to run: the booking widget, the customer pages, the REST API, the database schema, the e-mail templates and the office dashboard all ship inside the plugin and install on the client’s existing WordPress site.

Do you build systems like this outside Denmark?

Yes. We deliver field-service and scheduling automation for clients across the UK, USA, Canada, Europe, South Africa and the UAE. The country-specific pieces here were the address register, the language and the local craftsman tax deduction; the architecture, the capacity engine and the planner sync are the same wherever the crews drive. See our automation services or other case studies.

Do Your Crews Still Get Their Jobs by Hand?

If your customers book by phone and someone re-types it into a scheduler, there is a system waiting to be built. We deliver fixed-scope automation projects in milestones, on your own infrastructure.

Book a Free Discovery Call WhatsApp Us