Back to the build library
Any industry
Advanced

Multi-Location Routing & Reporting

One brand, many sites: every inquiry routed to the right location and owner, with roll-up reporting managers cannot peek past.

Industry
Any industry
Build effort
Advanced
Typical time to launch
5–8 weeks, with a two-location pilot before the full rollout
On this page
The problemWhat gets builtHow it runsAutomations in detailWhat changesBefore you start
Want this built for you?

Bring your stack to a call and we will scope it against how your business actually runs.

Book a call
01

The problem

A single-location business that grows to four does not get four times the problems. It gets a different problem. Inquiries arrive at one brand and have to reach one of several places, and nothing in the original setup knows how to decide which. So the business improvises. A general inquiry inbox that someone at head office forwards. A single phone number that rings a receptionist who asks "which branch?" and transfers. One shared calendar that nobody trusts. Four separate logins because each location bought its own tools. Leads land in the wrong place, get worked twice, or get worked by nobody because each location assumed another had it.

The money leaks in ways that are hard to see from the center. Misrouted leads are the obvious one: an inquiry sent to the wrong branch is usually dead by the time it arrives at the right one, and nobody logs it as a loss because nobody logs it at all. Double-contacted leads are worse, because the prospect notices and draws the obvious conclusion about how organized the business is. Then there is the unowned lead: in a shared pipeline, an opportunity with no named owner is everyone's and therefore nobody's, and it sits in the first stage until someone archives it. And there is the capacity problem running underneath. One location is turning work away while another has empty slots, and the routing has no idea because it was built on ZIP codes rather than on availability.

The reporting failure is the one that compounds. Head office wants one view: leads, bookings, revenue, speed to lead, close rate, per location, comparable. What it usually gets is four spreadsheets with different definitions, assembled late, by hand, by someone who then has to defend the numbers in a meeting. Meanwhile each location manager wants the opposite. Their own data, their own team, their own pipeline, and no visibility into their neighbor's performance or their neighbor's customers, which is both a trust matter and often a data protection one. Those two requirements sound contradictory and are not. One data model with a location field on every record, a permission layer that filters by it, and reporting that aggregates above the filter satisfies both. This build is that model.

02

What gets built

The location data model

Everything in this build depends on one decision: a single location field, mandatory, on every contact, opportunity, appointment, form submission, task and conversation. Nothing enters the system without it. Get this right first and the rest is configuration; get it wrong and no amount of workflow fixes it.

  • location: dropdown, the authoritative field. Values are short codes, not display names, so a rebrand does not break every filter: loc-north, loc-south, loc-east, loc-central.
  • location_assigned_by: dropdown: Form selection / ZIP code match / IP geolocation / Phone line / Round-robin overflow / Manual reassignment / Default fallback. This field is how you audit the routing later.
  • location_confidence: dropdown: Explicit / Inferred / Fallback. Only Explicit should ever skip the confirmation step.
  • location_previous: text, written on every reassignment, so transfers are traceable.
  • service_requested: dropdown; some services exist at only some sites, and this field drives the service-aware routing branch.
  • ZIP code: text, required on every form that routes geographically.
  • owner_user: user reference, the named human accountable.
  • speed_to_first_contact_mins: number, written by workflow on the first outbound touch.
  • routing_override_reason: text, required whenever a human moves a record between locations.
  • capacity_flag: dropdown on the location record: Open / Tight / At capacity / Closed. Set by the manager or by a rule reading calendar availability.

Pipelines

One pipeline definition, identical stages, replicated per location rather than shared. Identical stages are what make the roll-up possible; separate pipelines are what make the permissions clean.

Pipeline per location: "[Location] Sales"

  1. Unrouted: a holding stage that should normally be empty. Anything sitting here for more than 15 minutes is an alert, not a record.
  2. Routed: Awaiting Contact: location and owner assigned, no human touch yet
  3. Contacted
  4. Qualified
  5. Appointment Booked
  6. Appointment Held
  7. Quoted
  8. Won
  9. Lost: requires lost_reason
  10. Transferred Out: a terminal stage used when a lead moves to another location, so it does not vanish from this location's funnel count without explanation

Central pipeline: "Routing Exceptions", visible only to head office: Unresolved Location, Out of Area, Multi-Location Inquiry, Capacity Overflow, Duplicate Across Locations, Resolved.

Calendars

  • One calendar group per location, with the location code in the name. Staff availability sits on the individual, service duration sits on the calendar, and no calendar spans two locations.
  • Round-robin within a location, never across locations. An appointment at the wrong site is worse than a slightly later one at the right site.
  • Service-specific calendars where a service is offered at only some sites. The booking widget reads service_requested plus location and only offers legitimate combinations, which prevents the single most common multi-site booking error.
  • Time zones set per location, not per account, if the brand spans them. Every reminder, quiet-hour check and report boundary reads the location's zone.
  • Holiday and opening-hours calendars per location, feeding both the booking widget and the voice routing.

Routing engine

Five mechanisms, evaluated in strict order of confidence:

  1. Explicit selection. A location picker on the form, defaulted to nothing. The most accurate signal available; make the field required and the problem mostly disappears.
  2. ZIP code match. A lookup table mapping ZIP code prefix to location code, maintained as data rather than as workflow conditions so a manager can edit it without touching automation. Handle overlaps explicitly: where two sites both serve a prefix, the table names a primary and a secondary.
  3. Dedicated inbound channel. A phone number and a form per location, each hard-coded to its code. Any lead from that channel skips inference entirely.
  4. Page or campaign context. Location landing pages, ad campaign parameters and tracking tags carry the code into the submission.
  5. Round-robin fallback. Only for genuinely unidentifiable leads, only across locations whose capacity_flag is Open, and always with location_confidence = Fallback so the first message asks rather than assumes.

Forms

  • Central Inquiry: one form on the main site: name, email, mobile, ZIP code (required), service_requested, location picker with "not sure" as an explicit option, consent checkbox. "Not sure" plus ZIP code routes geographically; "not sure" with an unmatched ZIP code goes to Routing Exceptions.
  • Location Inquiry: one per site, identical fields, location hard-coded hidden, deployed on that location's page.
  • Transfer Request: internal only, used by staff to move a record. Requires routing_override_reason and the receiving location; triggers the handoff workflow rather than letting someone silently edit the field.

Voice and call routing

  • One brand number that answers with a location menu, plus a direct number per location for repeat customers and local listings.
  • The voice agent on the brand number asks for ZIP code or town first, confirms the matched location by name, then transfers to that location's line. It creates the contact with location and location_assigned_by = Phone line before the transfer, so a dropped call is still a captured lead.
  • Guardrails: never quotes a price, never books outside the matched location's calendar, never promises a callback time it cannot see availability for. If the caller's town is not in the table, it takes a message and creates a Routing Exception rather than guessing.
  • Out of hours, missed-call text-back fires from the location's own number, not the brand number, so the reply lands with the right team.

BO, per location

  • One agent configuration, with location-specific context injected: address, hours, parking, services offered, team names, and the location's own calendar.
  • Role: confirm location before anything else when location_confidence is not Explicit; answer location-specific logistics; book into that location's calendar only; chase unanswered inquiries.
  • Guardrails: never discusses another location's pricing or availability; never books across locations; never asserts a location when the field is Fallback: it asks. If the customer names a location different from the one assigned, BO stops and triggers the transfer workflow rather than editing the field itself.
  • Handoff: to the assigned location's team channel, never to a central inbox.

Tags

One location tag per site (loc-north and so on, mirroring the field for reporting convenience), plus routing-explicit, routing-inferred, routing-fallback, transferred, multi-location-inquiry, out-of-area, capacity-overflow, duplicate-cross-location, sla-breach.

The permission model

This is the part that makes the build viable politically as well as technically. Four roles:

  • Location staff. See and act on contacts, opportunities, appointments, conversations and tasks where location equals their assigned location. No access to other locations' records, no cross-location search, no exports. Their pipeline view shows one pipeline. Their calendar view shows one calendar group.
  • Location manager. Everything location staff can do, plus their own location's reporting dashboard, their team's performance figures, the ability to set capacity_flag, and the ability to raise a Transfer Request. Explicitly not: other locations' dashboards, the roll-up report, or any cross-location benchmark unless the brand chooses to publish a league table deliberately.
  • Regional manager (optional tier). A named subset of locations, read and write across them, with a combined dashboard filtered to those sites.
  • Head office. All locations, the roll-up report, the Routing Exceptions pipeline, the ZIP code table, workflow configuration, and the audit log of every reassignment.

Implementation notes that matter: the permission filter must apply to search, to exports, to saved reports and to notification routing, not only to the pipeline view, which is the one place people remember to check. Test it by logging in as a location user and trying to find a contact you know exists at another site. Shared assets (email templates, snippets, the brand's social accounts) stay centrally owned and read-only to locations, or four teams will quietly fork the brand. And every workflow notification must be addressed to owner_user or the location's channel; a single central notification channel destroys the whole model on day one.

Reporting

  • Location dashboard (one per site, visible to that manager): leads this period by source, speed to first contact, contact rate, booking rate, show rate, quote rate, win rate, pipeline value by stage, lost_reason breakdown, and an SLA breach list.
  • Roll-up dashboard (head office): the same metrics with a location dimension, side by side, plus routing accuracy, transfer volume, exception volume, and capacity utilization per site.
  • Routing health report: distribution of location_assigned_by, distribution of location_confidence, reassignment rate, and the top ten ZIP codes producing exceptions, which is your maintenance list for the lookup table.
  • Attribution: source and campaign captured at submission and preserved across transfers, so a lead transferred from north to south still credits the campaign that generated it. Report cost per booked appointment by location and by campaign.
03

How it runs, step by step

  1. Tuesday, 7.48pm. A prospect searches the brand name, lands on the main site rather than a location page, and submits the Central Inquiry form. She enters her ZIP code, selects a service, and leaves the location picker on "not sure". Consent box ticked.
  2. 7.48pm, immediately. The record is created in Unrouted on the central holding pipeline. The routing workflow runs. Explicit selection: none. ZIP code lookup: her prefix maps to loc-south as primary, loc-central as secondary.
  3. 7.48pm. Service check: the service she selected is offered at south. Capacity check: south's capacity_flag is Open. So location = loc-south, location_assigned_by = ZIP code match, location_confidence = Inferred. Tag routing-inferred applied.
  4. 7.48pm. The opportunity is created in South Sales at Routed: Awaiting Contact. Owner assigned by round-robin among south staff who are on shift, excluding anyone over their open-lead cap. owner_user set. The holding record closes.
  5. 7.49pm. Because confidence is Inferred, the first message confirms rather than assumes. Email and SMS, both from south's own number and sender name: "Thanks {{first_name}}, based on your ZIP code I have you down for our {{location_name}} branch at {{location_address}}. If you would rather come to {{alternate_location_name}}, just reply with that name and I will switch it. Otherwise here are our next available times: {{calendar_link}}." speed_to_first_contact_mins = 1.
  6. 7.52pm. She replies: "Central is actually closer to my work." BO recognizes a named alternate location, does not edit the field, and triggers the transfer workflow.
  7. 7.52pm. Transfer runs: location_previous = loc-south, location = loc-central, location_assigned_by = Manual reassignment, routing_override_reason = "Customer requested at first contact". The south opportunity moves to Transferred Out; a new opportunity opens in Central Sales at Routed: Awaiting Contact with the full conversation history and the original source and campaign intact. A new owner_user is assigned from central's on-shift staff. Both location channels are notified; the south owner's task is closed automatically so nobody works a lead they no longer own.
  8. 7.53pm. Confirmation from central's number: "Switched you to {{location_name}}, {{location_address}}. {{owner_first_name}} looks after inquiries there. Here are their next times: {{calendar_link}}."
  9. 8.07pm. She books Thursday 2pm on central's calendar. Stage moves to Appointment Booked. Confirmation and calendar invite carry central's address, parking notes and direct number.
  10. Wednesday 8.00am. The central owner's morning task list shows the appointment with the full inquiry context. She does not see any of south's leads, and the south owner can no longer see this one.
  11. Wednesday 2.00pm. Twenty-four-hour reminder from central's number, with central's reschedule link.
  12. Thursday 2.00pm. Appointment held. Stage moves to Appointment Held, then Quoted that afternoon.
  13. Thursday 4.30pm. Meanwhile at north, a different lead has sat in Routed: Awaiting Contact for 22 minutes. The SLA workflow fires: tag sla-breach, reassign to the next available north staff member, and notify the north manager, not head office, and not the other locations.
  14. Friday 9.00am. A third lead arrives with a ZIP code outside every mapped prefix. The routing workflow writes location_confidence = Fallback, routes it to the Routing Exceptions pipeline at Out of Area, and head office handles it, either adding the prefix to the table or sending a polite out-of-area reply with the nearest alternative.
  15. Monday 7.00am. Each location manager receives their own dashboard email: their leads, their speed to lead, their conversion rates, their SLA breaches. Head office receives the roll-up with all four sites side by side, plus routing accuracy, transfer volume, and the ZIP code prefixes that generated exceptions last week. Nobody sees anything they should not.
04

Automations in detail

Workflow 1: Location Routing

Trigger: any inbound lead event. Form submission, inbound SMS, inbound call completed, chat conversation started, or manual contact creation without a location.

Actions, in strict order: each step exits the workflow on a match:

  1. Create or update the contact. Create a holding record in Unrouted. Capture source, campaign and landing page before anything else, so attribution survives every later transfer.
  2. Step 1: Explicit selection. If the form's location picker holds a value other than "not sure": set location, location_assigned_by = Form selection, location_confidence = Explicit, tag routing-explicit. Go to step 6.
  3. Step 2: Dedicated channel. If the lead arrived on a location-specific number, form or chat widget: set location from the channel mapping, location_assigned_by = Phone line, location_confidence = Explicit, tag routing-explicit. Go to step 6.
  4. Step 3: ZIP code match. Look ZIP code up in the prefix table. On a single match: set location, location_assigned_by = ZIP code match, location_confidence = Inferred, tag routing-inferred. On an overlap: take the primary. On no match: go to step 5.
  5. Step 4: Campaign or page context. If a campaign parameter or landing page carries a location code: set it, location_assigned_by = Form selection, location_confidence = Inferred.
  6. Step 5: Unresolved. Move the holding record to the Routing Exceptions pipeline at Unresolved Location or Out of Area, notify head office, and send the customer one message asking the question directly: "Thanks for getting in touch. Which of our locations works best for you: {{location_list}}? Reply with the name and I will put you through to that team." Do not round-robin a lead you could simply ask. Round-robin fallback applies only to inbound calls that disconnect before a location is captured.
  7. Step 6: Service check. If service_requested is not offered at the matched location: branch. If exactly one other location offers it, reassign there, set location_assigned_by = Manual reassignment, routing_override_reason = "Service not available at matched location", and tell the customer in the first message. If several do, route to Routing Exceptions at Multi-Location Inquiry.
  8. Step 7: Capacity check. Read the matched location's capacity_flag. Open or Tight: proceed. At capacity or Closed: if a secondary location from the ZIP code table is Open, reassign, tag capacity-overflow, set location_assigned_by = Round-robin overflow, and say so in the first message. If no secondary is open, proceed to the original location anyway and notify its manager, overflowing a lead to a site the customer cannot reach is worse than a wait.
  9. Step 8: Duplicate check. If the email or mobile already exists on an open opportunity at a different location: do not create a second one. Route to Routing Exceptions at Duplicate Across Locations, tag duplicate-cross-location, and notify both locations' managers plus head office. A prospect contacted by two branches of the same brand is the single most damaging routing failure, so this check runs before owner assignment, not after.
  10. Step 9: Owner assignment. Create the opportunity in that location's pipeline at Routed: Awaiting Contact. Assign owner_user by round-robin among staff at that location who are on shift per the staffing calendar and below their open-lead cap. If nobody qualifies, assign the location manager. Apply the location tag. Close the holding record.
  11. Step 10: Notify. Post to that location's channel and create a task for owner_user due in 10 minutes. Never notify a central channel.
  12. Step 11: Hand to Workflow 2.

Stop conditions: contact already has an open opportunity at the correctly matched location (append the conversation, do not duplicate); contact tagged do-not-contact; the submission is a known internal test record.

Workflow 2: First Contact and Confidence Confirmation

Trigger: opportunity enters Routed: Awaiting Contact.

  1. Immediately: branch on location_confidence:
    • Explicit: confirm without asking: "Thanks {{first_name}}. You are booked in with our {{location_name}} team at {{location_address}}. {{owner_first_name}} will be in touch within the hour, or grab a time now: {{calendar_link}}."
    • Inferred: state and offer the correction, as in the walkthrough above. The correction sentence costs one line and prevents the most expensive routing error there is.
    • Fallback: ask outright: "Before I put you through to the right team, which location suits you: {{location_list}}?" Do not send a calendar link until a location is confirmed.
  2. Write speed_to_first_contact_mins on send. All messages originate from the assigned location's number and sender name.
  3. Wait 10 minutes. Condition: stage still Routed: Awaiting Contact. SMS from the location's number with the calendar link.
  4. Wait 12 minutes. Condition: stage unchanged and no human touch logged. Fire Workflow 3.
  5. Wait 4 hours. Condition: stage unchanged. BO opens a chat with the location's context loaded and offers three specific slots from that location's calendar.
  6. Wait 20 hours, then 2 days, then 4 days. Standard follow-up ladder (email, SMS, call task) all from the location, all stopping on reply or booking. At day 6 move to Lost with lost_reason = No response.
  7. On a reply naming a different location: do not edit location inline. Fire Workflow 4.

Stop conditions: appointment booked; stage advances; customer replies (pause and notify owner_user); transfer initiated; opt-out.

Workflow 3: Speed-to-Lead SLA

Trigger: opportunity has been in Routed: Awaiting Contact for 15 minutes with no logged human touch (call, manual message or note) during that location's opening hours. Outside opening hours the timer starts at open.

  1. Apply sla-breach. Notify owner_user directly: "{{contact_first_name}} has been waiting 15 minutes. Their inquiry: {{service_requested}}."
  2. Wait 5 minutes. Condition: still untouched. Reassign owner_user to the next on-shift staff member at the same location, log the previous owner, and notify the location manager. The manager, not head office.
  3. Wait 10 minutes. Condition: still untouched. Assign to the location manager personally and notify the regional manager if that tier exists.
  4. Wait 30 minutes. Condition: still untouched. Escalate to head office. This is the only rung that leaves the location, and it should fire rarely; if it fires often, the problem is staffing or the open-lead cap, not the workflow.
  5. Log every breach with the location, the owner at breach time, the hour of day and the source, and feed it to the weekly routing health report. Breach patterns by hour are usually a rota problem with an obvious fix.

Stop conditions: any human touch logged; stage advances; appointment booked; contact asks for a specific later callback time (set a snooze and clear the flag).

Workflow 4: Cross-Location Transfer

Trigger: Transfer Request form submitted by staff, or a customer reply naming a different location, or head office resolving a Routing Exception.

  1. Require routing_override_reason. A transfer with no reason is refused. The field is what makes the routing auditable, and without it the weekly routing accuracy figure is fiction.
  2. Write location_previous = current location; set location to the receiving site; set location_assigned_by = Manual reassignment; apply transferred.
  3. Move the originating opportunity to Transferred Out: never delete it. The sending location keeps a visible record and its funnel math stays honest.
  4. Create a new opportunity in the receiving location's pipeline at Routed: Awaiting Contact, carrying the full conversation history, all custom fields, the original source and campaign, and any files.
  5. Assign a new owner_user at the receiving location by the same on-shift round-robin.
  6. Close every open task belonging to the previous owner and remove their access by virtue of the location change. Two owners on one lead is how a customer gets called twice.
  7. Immediately: notify both location channels, and message the customer from the receiving location's number: "You are all set with {{location_name}} at {{location_address}}. {{owner_first_name}} looks after inquiries there and will pick this up. Their next available times: {{calendar_link}}." Sending that confirmation from the old number is a small detail that confuses customers badly.
  8. If an appointment existed: cancel it on the sending location's calendar, apologize explicitly, and offer the receiving location's availability in the same message. Never silently move an appointment between sites.
  9. Write an audit entry: who, when, from, to, reason. Surface transfers in both locations' dashboards and in the roll-up.

Stop conditions: receiving location rejects the transfer (routes to Routing Exceptions for head office to arbitrate); customer declines the move.

Workflow 5: Routing Exception Handling

Trigger: record enters any Routing Exceptions stage.

  1. Immediately: notify head office with the stage, the ZIP code, the service requested and the raw submission.
  2. Branch: Unresolved Location: send the customer the direct question from Workflow 1 step 5. Create a head office task due in 30 minutes. On the customer naming a location, route there with location_confidence = Explicit and close the exception. Wait 1 day with no answer → head office call task. Wait 3 days → Lost, lost_reason = No response.
  3. Branch: Out of Area: send an honest reply naming the nearest site and the travel reality: "Our closest location to you is {{nearest_location}}, which is {{distance}} away. Happy to see you if that works: {{calendar_link}}. If it does not, say so and I will point you at someone closer." Create a head office task to decide whether the prefix belongs in the table.
  4. Branch: Multi-Location Inquiry: ask the customer which site, do not pick. Head office owns it until answered. Commercial inquiries that genuinely span sites get a head office owner permanently, with each site's work tracked as a child opportunity.
  5. Branch: Capacity Overflow: head office reviews within the hour. Either confirm the overflow site or return the lead to the original location with a wait-time message. Log it, because repeated overflow from the same site is a hiring signal, not a routing signal.
  6. Branch: Duplicate Across Locations: head office decides the single owning location (default to whichever contacted the customer first) closes the other opportunity as Transferred Out, and messages the customer once, from the surviving location, acknowledging it plainly: "Apologies: two of our branches picked up your inquiry. {{owner_first_name}} at {{location_name}} has it now and is your single point of contact." Never let both locations keep working it.
  7. On resolution: move to Resolved, record which mechanism should have caught it, and add the fix to the weekly routing health report.

Stop conditions: routed successfully; customer out of area and declining; duplicate resolved.

Workflow 6: Capacity-Aware Overflow

Trigger: schedule, hourly, during opening hours, per location.

  1. Read each location's next 7 days of bookable availability as a percentage of total slots.
  2. Write capacity_flag: above 40 percent free → Open; 15 to 40 percent → Tight; under 15 percent → At capacity. A manager can override manually, and a manual override holds for 24 hours before the rule resumes. Otherwise the automation and the manager fight each other all day.
  3. On any location moving to At capacity, notify its manager and head office with the first available date.
  4. On any location sitting At capacity for 3 consecutive days, add it to the roll-up report's attention list.
  5. Workflow 1 step 7 reads this field. Nothing else should.

Workflow 7: Appointment Lifecycle, Location-Aware

Trigger: appointment booked on any location calendar.

  1. Stamp the location on the appointment record; verify it matches the opportunity's location. On mismatch, halt, alert both managers, and do not send a confirmation until a human resolves it.
  2. Immediately: confirmation from the location's number and sender, carrying that location's address, parking or access notes, direct phone number, and reschedule link to that location's calendar only.
  3. 24 hours before: reminder by email and SMS, in the location's time zone, respecting that location's quiet hours.
  4. 2 hours before: SMS reminder with the address again. Multi-site brands generate a specific failure mode: the customer drives to the branch they went to last time.
  5. On no-show: recovery sequence from the location, rebooking into that location's calendar, and the no-show counted against that location only.
  6. On held: advance the stage and prompt the owner for the outcome; the review request, if your build includes one, points at that location's review profile, never the brand's aggregate one.

Workflow 8: Location Dashboard Delivery

Trigger: schedule, Monday 7am in each location's own time zone.

  1. For each location, compute from records where location equals that site: leads by source; median and 90th-percentile speed_to_first_contact_mins; contact rate; booking rate; show rate; quote rate; win rate; pipeline value by stage; lost_reason counts; SLA breaches with owner and hour; transfers in and out.
  2. Email it to the location manager and the location channel. The template contains no other location's figures, and the underlying report is permission-filtered so a forwarded link still shows only that site.
  3. Include this location's own prior-period comparison. Never a ranking against siblings, unless the brand has explicitly decided to run a league table. That is a culture decision for the owner to make deliberately, not a default the build imposes.
  4. Flag, for the manager only: opportunities in Routed: Awaiting Contact over 2 hours, Contacted over 5 days, Quoted over 10 days, and any record still Unrouted.

Workflow 9: Roll-Up and Routing Health Report

Trigger: schedule, Monday 7.30am, head office only.

  1. Every metric from Workflow 8, with a location dimension, side by side, for the trailing 7 and 28 days, plus totals.
  2. Routing accuracy: distribution of location_assigned_by; distribution of location_confidence; reassignment rate as a share of all leads; mean time from creation to final location.
  3. Exception analysis: volume by stage, time to resolution, and the ten ZIP code prefixes generating the most exceptions. The maintenance list for the lookup table.
  4. Transfer analysis: volume by sending and receiving pair, with reasons grouped. A persistent one-way flow between two sites means the ZIP code table is wrong, not that customers are indecisive.
  5. Capacity: days at each flag per location, overflow volume, and first-available-date trend.
  6. Attribution: cost per lead and per booked appointment by campaign and by location, using the source captured at submission and preserved through transfers.
  7. Flag any location whose median speed to first contact exceeds the SLA, any location with a reassignment rate above 10 percent, and any exception older than 48 hours.

Workflow 10: New Location Provisioning

Trigger: manual, run by head office when a site opens.

  1. Add the location code to the location dropdown and to the ZIP code table, reassigning prefixes from neighbouring sites deliberately rather than by overlap.
  2. Clone the pipeline, calendar group, dashboard and BO configuration from the template location; inject the new address, hours, services, team names and time zone.
  3. Provision the location's phone number, register it on the existing A2P campaign, and add it to the brand number's menu and the voice agent's lookup.
  4. Create the staff users against the location permission filter and verify, by logging in as one, that no other location's records are reachable by search or export.
  5. Publish the location landing page and its hard-coded Location Inquiry form.
  6. Run three test leads (explicit, ZIP code-inferred, and unresolvable) before any traffic is pointed at it.

This workflow is what makes the build scale. Without it, location five is three weeks of manual configuration and two weeks of routing bugs.

05

What changes

What is different

  • Every record carries a location from the moment it exists. There is no bucket of unassigned leads, because Unrouted is an alert state rather than a resting place.
  • Routing follows a documented order of confidence instead of a receptionist's judgment, and inferred routing says so out loud, which turns a potential misroute into a one-line correction from the customer.
  • Every lead has one named owner at one location. Two branches cannot work the same prospect, because the duplicate check runs before owner assignment.
  • Transfers are a workflow with a required reason and an audit trail, not an edited field. The sending location keeps a visible Transferred Out record, so nobody's funnel quietly improves by losing leads.
  • Location managers see their own site and their own team, and genuinely cannot see their neighbors'. Head office sees everything, in one report, with consistent definitions, without anybody assembling a spreadsheet.
  • Routing failures become data rather than anecdote. The weekly exception list is a maintenance queue for the ZIP code table instead of a recurring argument.
  • Opening a new site is a provisioning workflow measured in days, not a rebuild.

Metrics to watch

  • Routing accuracy: the share of leads whose final location equals their first assigned location. This is the headline number for the whole build. Watch it weekly for the first two months; it should climb as the ZIP code table matures.
  • Reassignment rate, and the directional matrix of transfers between site pairs. A persistent one-way flow is a table error with a specific fix, not customer indecision.
  • Confidence distribution: the share of leads routed Explicit versus Inferred versus Fallback. Pushing explicit share up, by making the location picker prominent and required, is the cheapest accuracy improvement available.
  • Speed to first contact: median and 90th percentile, per location, per hour of day. The 90th percentile is where the rota problems hide; the median will look fine while a fifth of your leads wait an hour.
  • SLA breach rate by location, owner and hour. Breaches clustered at specific hours are a staffing fix; breaches clustered on specific owners are a caseload fix.
  • Unrouted dwell time: should be seconds. Anything that lingers means a routing mechanism failed silently.
  • Duplicate-across-location rate. Target zero. Every instance is a customer who saw the brand look disorganised.
  • Exception volume and time to resolution, plus the recurring ZIP code prefixes behind them.
  • Per-location conversion ladder (contact, booking, show, quote, win) compared like for like. Because the stages are identical by construction, differences are real rather than definitional, which is the whole point of replicating one pipeline rather than letting each site invent its own.
  • Capacity utilization and overflow volume per site. Sustained overflow from one location is a hiring or hours decision; sustained slack at another is a marketing allocation decision.
  • Cost per booked appointment by campaign and location. With source preserved through transfers, this finally becomes answerable, and it usually redistributes the ad budget.
06

Before you start

Prerequisites

  • The location list, frozen, with short codes. Decide the codes before anything is built and never reuse one for a different site. Renaming a location is cosmetic; recoding one breaks history.
  • The ZIP code or territory table, built and signed off by the managers who will live with it. This is the single most underestimated task in the build. Expect a couple of sessions of argument about border areas, and resolve overlaps by naming a primary and a secondary rather than splitting them. Maintain it as editable data, not as workflow conditions.
  • A service-by-location matrix. Which services exist at which sites, written down. Workflow 1 step 6 and every booking widget depend on it.
  • One agreed pipeline definition with identical stage names and identical stage-entry criteria across all sites. If one location insists on its own stages, the roll-up report dies. This needs to be settled by the owner, not negotiated per site.
  • Agreed SLA for speed to first contact, and agreement from the managers that breaches reassign the lead. The reassignment is the part people resist and the part that works.
  • A staffing or shift calendar per location, kept current, because round-robin assignment to someone who is off that day is the fastest way to generate SLA breaches.
  • Baselines captured before launch: current misroute rate if you can estimate it, current speed to lead per site, current conversion per site.

Integrations

  • Calendar sync per location, two-way, for every member of staff, with the location's time zone set on the calendar rather than inherited from the account.
  • Telephony: one brand number with menu and voice routing, one direct number per location, and call recording configured to the strictest consent rule across your jurisdictions, not the most convenient one.
  • Website: a page per location with its own hard-coded form and chat widget, plus the central form. Tracking parameters must survive the redirect from an ad to a location page, or attribution breaks at exactly the point you need it.
  • Email authentication: SPF, DKIM and DMARC on the brand domain. If each location sends from its own subdomain or address, authenticate every one and verify deliverability per sender before launch.
  • Review profiles: one per location, connected individually. Routing review requests to a brand-level profile wastes the strongest local search signal a multi-site business has.
  • Reporting destination: if figures feed a warehouse or BI tool, replicate the permission filter there too. A dashboard that leaks what the platform protects is a leak.

Number provisioning

  • One local number per location, non-negotiable. A local number lifts answer rates, and more importantly it means a reply lands with the team that owns the lead. Every outbound message in this build sends from the assigned location's number.
  • One additional brand number for the menu and the voice agent, used for inbound only.
  • Enable inbound on every location number and route replies to that location's inbox and channel. Verify, per number, that a reply reaches the right place: test all of them, individually, before launch.
  • Register every number on the same A2P campaign under one brand, and add each new number to the campaign as sites open. Numbers sending on an unregistered campaign get filtered.
  • Configure keyword handling identically on every number, and make sure an opt-out on one number suppresses the contact across all of them. A customer who stops messages from north should not start receiving them from south.

Consent and compliance

  • A2P 10DLC registration: register the brand once under the legal entity and EIN, then one campaign covering the use case, then associate every location number with it. Submit the central and location form URLs, a screenshot of the consent checkbox and its wording, and sample messages including a routing confirmation and an appointment reminder. Allow one to three weeks and build every SMS step disabled until approval. Where locations are separate legal entities, each needs its own brand registration and campaign. Confirm the corporate structure before you start, because discovering it mid-rollout costs weeks.
  • Express written consent on every form, central and per location: unticked checkbox, its own line, naming the brand, stating the message types, that rates may apply, and the opt-out instruction. Store timestamp, IP and exact wording. Consent is given to the brand, not to a branch, so a transferred lead does not need re-consenting, but the record must show which form and which wording produced it.
  • Opt-out handling, brand-wide. STOP, UNSUBSCRIBE, CANCEL, END and QUIT suppress SMS across every location number, not just the one that received the reply. This is the most commonly botched requirement in multi-site builds: a per-number suppression list is a compliance failure waiting to happen. Apply a brand-level do-not-SMS flag that every workflow checks as a stop condition, and test it by opting out on one number and attempting a send from another.
  • Quiet hours per location time zone, read from the location record rather than the account default. A brand spanning time zones that enforces one window will message somebody at 6am. No SMS before 8am or after 9pm locally, queue rather than drop, and tighten where a jurisdiction requires it.
  • Frequency cap at brand level, not per location, so a transferred lead does not receive the follow-up ladder twice. Cap centrally and have the transfer workflow reset rather than restack the sequence.
  • Call recording consent: if any location sits in a two-party consent jurisdiction, apply that rule everywhere or configure per location. Mixed rules with one shared announcement is the arrangement that gets a brand in trouble.
  • Data access and privacy: the permission model is a compliance control, not a convenience. Location staff seeing other sites' customer records is an access-control problem under most privacy regimes. Document the roles, the filter, who can export, and who can see the audit log. Where locations are separate legal entities, the lawful basis for sharing a customer record between them at transfer needs to be established and written down before launch, not improvised afterwards.
  • Audit log retention: every reassignment, every permission change and every export, retained for the period your regulator or insurer requires.

The permission model, in practice

  • Build the filter on the location field, applied at the user level, and verify it against all six surfaces: pipeline views, calendar views, contact search, exports and saved reports, notification routing, and conversation inboxes. Most builds secure the first two and leak through the other four.
  • Test by logging in as a real location user and deliberately trying to reach another site's data. Search a known contact by email, attempt an export, open a forwarded dashboard link, click a notification for another site. Document the result of each attempt. Do this again after every configuration change and after every new location is provisioned.
  • Keep shared assets (templates, snippets, brand social accounts, the ZIP code table) centrally owned and read-only at location level. Editable shared templates become four divergent brands within a quarter.
  • Decide deliberately whether managers see a cross-location league table. The default in this build is no. It is a culture decision with real consequences either way, and it should be the owner's explicit choice rather than an accident of configuration.
  • Agree in advance who can override routing and who can transfer. Giving every staff member transfer rights produces churn between sites; restricting it to managers plus head office keeps the audit trail meaningful.

Rollout

  • Pilot two locations: ideally two with a contested border, because that is where the routing will fail. Run four weeks, measure routing accuracy, fix the table, then extend.
  • Migrate historical data with the location field populated, or the first month of comparisons is meaningless. Records whose location genuinely cannot be determined get a loc-unknown value rather than a guess.
  • Train managers on their dashboard before launch day, and staff on the transfer workflow rather than letting them learn by editing fields.
  • Run Workflow 10 as a dry run on a test location before the first real site opens on it.

The territory table, the permission model and the roll-up definitions are worked out on a call, against your actual sites and corporate structure. Book one and bring your location list.

Build it with us.

Every build on this page is something we configure, test and hand over with the SOPs your team needs to run it.

Book a call