Geographic decision engine
Put your business logic on the map.
Know whether you serve an address, who owns it, and what should happen next. One versioned ruleset answers the same way for your website, your CRM, your call centre and your API.
The problem
One address. Three different answers.
Geographic logic ends up split across a spreadsheet, a CRM automation, your website and the knowledge of whoever has been there longest. Nothing reconciles them, so the disagreement only surfaces as a misrouted lead or a franchise dispute.
HVAC service requested at 123 Main Street, Richmond, VA 23219
-
The territory spreadsheet
Richmond South
Last edited 7 months ago by someone who has left.
-
Your CRM assignment rule
Richmond Central
A ZIP list pasted into a workflow, never reviewed since.
-
The website form
Tri-County
Hard-coded in a page nobody on the ops team can edit.
Three systems, three owners, one customer. Somebody on your team is the tiebreaker, every time.
The answer
Give every address an answer.
One published ruleset, asked the same way by every system you run, returning the same decision with the reasoning attached.
-
Serviceable
Do we serve this address?
Coverage and eligibility are different answers. A territory can cover a point and still be unable to do the job, and saying so is not the same as saying no.
-
Ownership
Who owns it?
One assignee, chosen by explicit precedence rather than whichever row the database returned first. When two claims genuinely tie, you hear about it instead of getting a coin flip.
-
Action
What should happen next?
Route the lead, quote the pricing zone, pick the queue, hand off to the right branch, carried out by whichever system asked.
How it fits
One ruleset. Every system that asks.
MapLogics does not replace your website or your CRM. It becomes the thing they all ask, so the answer stops depending on which one a customer happened to reach.
Change a territory once. Every one of them is already using the new version, and the old version still explains every decision it made.
How it works
From spreadsheet to published ruleset.
Setup is a sequence, not a project. Most teams get to a first published version the same day.
-
Add your locations
Branches, franchisees, dealers or reps, with the services each one can actually perform. Import a spreadsheet if that is where they live today.
-
Draw your territories
Draw polygons, group postal areas, or set a radius. Overlaps are surfaced while you work rather than discovered later by a customer.
-
Write the rules
Eligibility, ownership, priority, fallback and business hours, built from typed conditions. No code, and nothing that can silently mean two things.
-
Test before anyone sees it
Run real addresses through a draft and read the full trace. Save the ones that matter and re-run them before every publish.
-
Publish a version
Publishing is atomic. Every system asking gets the new answer at the same moment, and every past decision still names the version that produced it.
Why it decided that
Every answer shows its work.
Anyone can draw a territory on a map. When a franchisee asks why a lead went to the branch across town, you need the reasoning: which territories were in play, which were ruled out and why, which rule won, and which version of your configuration produced it.
The trace
-
Geocode
123 Main St, Richmond VA normalised to 37.5407, -77.4360 at high confidence
-
Candidate query
Territories trr_017 and trr_021 both cover the point
-
Exclusions
No exclusion rule matched
-
Eligibility
trr_021 eliminated: its assigned location does not provide the requested HVAC service
-
Assignment
trr_017 matched rule_primary_owner at priority 100
-
Fallback
Not evaluated: a primary eligible candidate exists
-
Decision
Resolved to Richmond Central
reason_code PRIMARY_ELIGIBLE_TERRITORY
What the API returns
{
"request_id": "res_01J8ZQ...",
"status": "resolved",
"ruleset_version": "cfg_00042",
"location": { "id": "loc_004", "name": "Richmond Central" },
"territory": { "id": "trr_017", "name": "Richmond Central" },
"serviceable": true,
"outputs": {
"pricing_zone": "B",
"lead_queue": "richmond-central"
},
"trace": {
"candidates": 2,
"matched_rules": [
"rule_hvac_required",
"rule_primary_owner"
],
"reason_code": "PRIMARY_ELIGIBLE_TERRITORY"
}
} The same trace is available in the app, in a batch export and over the API. The reason code is stable, so your own systems can branch on it instead of parsing prose.
What you get
Built for decisions people will argue about.
Territory changes are contentious. Every capability here exists so a decision can be defended afterwards, not just made.
-
Versioning
Configuration is published as immutable versions. A decision from March is still explained by the ruleset that was live in March.
-
Overlap detection
Territories that overlap are flagged while you edit, with the conflicting pair named, rather than resolved silently at request time.
-
Explicit precedence
Exclusion, then eligibility, then ownership override, then priority. A fixed order, so the same inputs cannot produce a different winner tomorrow.
-
Fallback
Say what happens when the primary owner cannot take the work. Fallback loops are rejected before they can be published.
-
Ambiguity you can see
When two candidates genuinely tie and no rule breaks it, you get an ambiguous answer and the candidates. Not a coin flip presented as a decision.
-
Batch resolution
Run an account list or a lead export through the same engine. Every row comes back with its decision and its reason, exceptions included.
-
Embeddable checker
A service-area check on your own site that answers from the same published ruleset your CRM uses. No developer needed to install it.
-
Audit trail
Who changed what, when, and what it did to the decisions. The record a franchise dispute actually turns on.
Who it is for
The question you came here with.
-
Franchise operations
Which franchise owns this customer, and can I prove it?
Territory ownership with an audit trail, so a dispute is settled by the record instead of by whoever argues hardest.
-
RevOps and CRM admin
I need one source of geographic truth my integrations can call.
Stop maintaining brittle ZIP-list automations in three systems. Keep ownership synchronised from one published ruleset.
-
Marketing and growth ops
Am I wasting paid leads because a ZIP table is stale?
Route inbound leads correctly on arrival, and see which addresses you are turning away so you know where demand is going unserved.
-
Operations manager
Which branch can actually do this job, at this time?
Serviceability is geography plus capability plus hours, not geography alone. A territory covering a point does not mean the work can be done.
-
Product and engineering
Give me a stable API and deterministic behaviour.
One documented endpoint, opaque IDs, stable reason codes and the same decision every time for the same inputs and version. No spatial infrastructure to build.
Jobs to be done
Find your situation.
A lead lands on my website…
It is routed to the correct owner immediately, and the assignment can be explained if anyone asks.
Territories change…
You stage the change, review it and publish it, without silently rewriting what past decisions were based on.
A customer asks whether we serve them…
They get an immediate, accurate answer based on where they are and what they are asking for.
Two territories overlap…
Explicit precedence decides, and genuine ties are surfaced as ambiguous rather than hidden behind a silent winner.
I import a list of accounts…
Every row is assigned in bulk, and the ones that could not be are handed back as an exception file rather than dropped.
Another system needs the answer…
The same decision is available through the API, a webhook, the embeddable widget or a CRM integration.
Somebody disputes a decision…
You show which rules, which geometry and which published version produced it.
We expand…
Model coverage gaps and proposed territories against a draft, without touching what is live.
Fits your stack
It slots in. It does not take over.
MapLogics decides; your systems keep doing what they already do. Nothing here asks you to migrate your CRM or rebuild your website.
-
REST API
AvailableThe contract everything else is built on.
-
Service-area widget
AvailableA checker on your own site, no developer needed.
-
Webhooks
AvailableSigned events when configuration is published.
-
HubSpot
In buildRoute and update owners on contacts and deals.
-
Zapier and Make
In buildA resolve action for everything else.
-
Salesforce
PlannedFor enterprise franchise and dealer networks.
-
ServiceTitan
PlannedServiceability inside the field-service flow.
For developers
One endpoint. One decision. Same answer every time.
No spatial database to run, no geometry to maintain, no PostGIS to learn. Send an address or a coordinate and get back a decision you can branch on.
- Deterministic: same inputs and same published version, same decision.
- Opaque IDs and stable reason codes, so your code never parses prose.
- Every response carries a request ID that matches your logs and ours.
- Draft and published are separate endpoints, so you cannot test against production by accident.
Requestcurl
curl https://api.maplogics.com/v1/resolve \
-H "Authorization: Bearer ml_live_..." \
-H "Content-Type: application/json" \
-d '{
"address": {
"line1": "123 Main Street",
"city": "Richmond",
"region": "VA",
"postal_code": "23219",
"country": "US"
},
"context": {
"service": "hvac",
"channel": "website"
},
"trace": "summary"
}' Response200 OK
{
"status": "resolved",
"territory": { "id": "trr_017", "name": "Richmond Central" },
"serviceable": true,
"trace": { "reason_code": "PRIMARY_ELIGIBLE_TERRITORY" }
} Bring your territory spreadsheet.
The fastest way to see whether this is worth anything to you is to run your own addresses through it. Send us the spreadsheet you actually use and the locations you actually have, and we will show you what MapLogics decides, including the ones it gets wrong.