Work out what it would take to give every business one booking destination that keeps working everywhere: their website, a social profile, an email, a code printed on a card.
I treated it as a naming and routing problem and researched it that way. What protects a booking today is the website address the request arrives from, and every new entrance in this plan is a place with no website address to check.
A security control can be made of something the product is about to stop having. The check works because booking happens on the merchant site, and this is the project that ends that.
The Build
Nothing shipped from this research. There is no Everwood booking page a customer can visit, no permanent link for a business, no short link, and no way for a business to claim a name. The roadmap node this came from is planned, and it is still planned.
The goal is easy to say. A business should have one booking destination that keeps working: on their website, in an Instagram bio, on a card in the window, in an email, on a sticker by the till. Today there is one way in. A business pastes a snippet into their own website and a booking widget appears on it.
I went in expecting the interesting problem to be permanence. Businesses rename themselves. A printed code cannot be recalled. I wanted to know how you hand somebody a link today that still works in five years.
That turned out to be the easy half.
The Problem
Here is what I found when I read our own widget instead of the research.
When a business installs the booking widget, they paste a snippet into their site, and that snippet carries a key that names their business. The key sits in the page source. Anyone who views the page can read it. That is not a mistake, it is what the design says: the key identifies, it does not authenticate.
So what stops somebody copying that key onto their own site and taking bookings against a business they have nothing to do with? Not the key.
The address the request came from. Every request the widget makes is checked against the list of websites that business has said its booking widget is allowed to appear on. Wrong address, refused. That is the whole check. No addresses configured at all, also refused, which I was glad to see, because the easy version of that code treats an empty list as no restrictions.
I knew this in the way you know things you wrote. What I had not done is put it next to the roadmap.
Because look at what the roadmap actually asks for. A booking page hosted by us. A permanent link. Something printed on a card in the window. Whatever sits in a social profile. Not one of those things is the merchant's website. Not one of them has a website address we could check against a list.
So the sentence I had been repeating for weeks, that Book from Anywhere is about routing every entrance into the same booking engine, is true and I had been hearing it wrong. Those entrances do not just need a route. Every one of them arrives at the door with the one credential missing that our booking system currently uses to decide whether to open it.
There is a way to say that makes it sound solved. We do already let our own pages through. Anything served from an Everwood address skips the per-business list, which is how the preview inside the dashboard works: a business can look at their own widget on our site without adding us to their list of allowed websites.
A hosted booking page would arrive on an Everwood address too. So the code path already exists, and it would work on the first day, and I want to be clear about why I do not think that settles it.
That path was built for a page where the visitor is a business owner, signed in, looking at their own widget. Point it at a page anybody can open and the check changes shape. It stops asking which business is this request for and starts asking is this one of our pages, and the answer for a public page is yes, always, for everyone, for every business. The list of allowed websites was a boundary between businesses. On our own pages it does not draw a line anywhere.
That is not the existing control being reused. It is a different control that happens to be written in the same place.
Assumption vs Reality
The hard, slow, one-way part of this project is the naming. Pick the wrong shape for a business's permanent link and you either break every printed code the day somebody rebrands, or you saddle every business with an ugly link nobody can read out loud. Get that right first, in one go, because you only get one go. The rest is plumbing.
The naming question is real, and the answer the research gives is the one I would have picked anyway. Keep an identifier for the business that never changes and route on that. Let the visible name be a separate, changeable thing that points at it. When a business renames itself, keep the old name pointing at the new one instead of deleting it. That is a good design and it is not a hard one, and I could not find a way to make it a one-way door. Nothing about it has to be decided before we know the rest. What is a one-way door is the thing the research does not raise. It never asks what replaces the address check. It spends its length on names, redirects, printed code density, browser cookie rules and social media browsers, and it never notices that the security model of the booking we already ship is made of exactly the thing the new entry points do not have. Two more places it argued from a product that is not ours. It lists sticking with an iframe embed as a structural commitment already made, and warns that moving off it later would break every existing installation. We are not on an iframe. Our widget mounts directly into the merchant's page in an isolated container, which means it shares the page's JavaScript with whatever else the business has installed. There is a real argument for moving to an iframe and I am not dismissing it. But it would be a migration of every existing install, not a commitment we have already made, and a decision described as already taken is a decision nobody re-examines. It also spends a section on how to keep the widget working when browsers stop letting embedded content use cookies. Our widget sends no cookies at all. That section is advice for a widget we do not have.
The Fix
What changed is the design, not the code. Three things I now believe.
The trust model is the first piece of work, not the routing. Before there is a hosted page, there has to be an answer to what proves a booking request is legitimately for this business when it did not come from that business's website. Everything else in this node waits on that, because everything else in this node is a new front door and the door is the part in question.
A shared address is not a boundary. When our own pages are the trusted thing, every business is behind the same gate, and a key that was always public is the only thing naming which business a request is for. Whatever we build has to keep a per-business line in it. What draws that line when there is no merchant website is the open question, and I would rather write that down as open than pretend the preview path answers it.
Record where a booking came from as a new thing, not as a value in the field we have. We already keep a source on a booking, and it does a useful job: it says how the booking was made, whether that was through the assistant, through the quicker flow, or entered by hand. A hosted page and a QR code are not more ways of that. A QR code is not a way of booking, it is a way of arriving. Push it into that field and it stops being able to answer either question, because a booking from a printed code is still made in one of the ways it already records.
One thing from the research I am setting aside. It recommends detecting when somebody has opened the booking page inside a social media app's built-in browser and turning off sign-in with Google and Apple Pay for them. We take no payment from customers anywhere in booking, so half of that is advice for a product we do not sell. The other half describes a constraint I could not verify and am not going to design around until I have, though I note that if it is right, it lands on a hosted page and never touched us before, because until now the booking widget has only ever run on a merchant's own site.
A security control can be made of something the product is about to stop having. The list of allowed websites is a good control. It is simple, it fails closed, and it has been doing real work quietly for as long as the widget has existed. It is also made entirely out of a fact about the current product: that booking happens on the merchant's website. That fact was never written down as an assumption, because it was not an assumption. It was just true. Book from Anywhere is a plan to stop it being true. Read as a routing project, it says nothing about security at all. Read as what it is, it is the removal of the only thing that currently keeps one business's bookings separate from another's. The general version. When a feature adds a new place a thing can happen, look at what protects it today and ask whether that protection is made of the old place. Sometimes the control is a rule somebody chose. Sometimes it is a side effect of the shape the product used to have, and those are the ones that disappear without anybody deciding to remove them.
For a salon owner, here is the honest position. Right now your customers can only book through the widget on your website. You cannot put a booking link in your Instagram bio, print one on a card, or send a customer somewhere that is not your site. If you do not have a website, you do not have online booking. That is the gap this work is meant to close and it is a real one. Part of why it works today is that your booking widget only answers requests coming from your own website. You tell us which sites it is allowed to appear on, and requests from anywhere else are turned away. It is quiet and you never see it, and it is the reason somebody cannot lift the snippet off your site and take bookings in your name from theirs. Every new place I want to put your booking link is somewhere that protection does not reach. A card in your window has no website. That does not mean it cannot be done safely. It means the safe version has to be designed, and it is the first thing to build rather than the thing we add afterwards. So I am not going to ship a booking link this month. What I would rather tell you in a few months is that your link works everywhere and nobody can pretend to be you, than tell you next week that it works everywhere.
Builder Notes
A research pass on multi-channel booking that turned into reading our own widget's trust model. Nothing was built. No hosted booking page, permanent link, or business naming scheme exists.
Technical Note 1
Shipped today: one booking entry point. A business installs a snippet on their own website and the widget renders into their page. The key in that snippet names the business and is public by design, readable by anyone who views the page source.
Technical Note 2
The real gate is the list of websites a business allows its widget on. Every widget request is checked against it. An empty list is refused rather than treated as unrestricted, which is the failure mode I would expect to find and did not.
Technical Note 3
Our own pages skip that per-business list. It exists so the preview inside the dashboard works, where the visitor is a signed-in owner looking at their own widget. The set of addresses that count as ours is configuration, with no blanket trust of anything sharing our name. That configuration is now also a step in the domain move, and I had not been counting it as one.
Technical Note 4
Not built: any booking page hosted by us, any permanent or short link for a business, any way for a business to claim a name, any redirect from an old name to a new one.
Technical Note 5
The widget mounts into the merchant's page in an isolated container rather than an iframe, so its styling is protected from theirs and its JavaScript is not. It also sends no cookies, which makes a long stretch of the research about browser cookie rules inapplicable to what we run.
Technical Note 6
We already record how a booking was made: through the assistant, through the quicker flow, or entered by hand. There is no record anywhere of where the customer came from. Those are two questions and one field, and adding hosted pages and printed codes to the values it accepts would leave it unable to answer either.
Technical Note 7
Everwood takes no payment from customers in booking. Anything in the research about payment behaviour inside social media browsers is for a product we do not have.
Technical Note 8
Cut from the research and kept in the ledger: every competitor link structure, the browser and operating system behaviours, the claim about which sign-in flows are blocked in embedded browsers, and the claim that shorter links produce codes that scan more reliably. Not one carried a source. The entire argument in this note comes from our own code, because that was the only evidence the research produced that I could check.
Technical Note 9
Second time now: the research came back with a finished announcement post declaring this feature is rolling out to all businesses this month. It describes permanent links, hosted pages and a rebuilt engine, none of which exist. It is fluent and it is confident and one copy and paste would have published it. I am recording it again because a research deliverable that arrives with the marketing already written is not a neutral document, and the parts I trusted least were the parts I had no way to check.
Before / After
- The hard part is choosing a link shape we can never change
- Book from Anywhere is a routing project
- The new entrances need to reach the same booking engine
- Our own hosted page is the easy case, because we already trust our own pages
- Where a booking came from is another value in the source we already keep
- The hard part is deciding what proves a request is for this business off their site
- Book from Anywhere removes the control booking currently depends on
- The new entrances arrive without the credential the door is checking
- Our own hosted page turns a line between businesses into one shared gate
- Where a customer came from is a different question from how the booking was made
What I'd Do Differently
I would have read our own trust model before commissioning research on the feature that changes it.
The research is competent about names, redirects and printed codes, and every one of those is downstream. It could not tell me the thing that mattered because it had no access to the only evidence that mattered, which was our code. I gave it a product description and it reasoned from a product it assembled out of common industry shapes, then it told me an iframe decision was already made and warned me not to reverse it.
The general version. When research is about extending something you already run, the first document is not the market. It is what you already built and what that quietly depends on. Otherwise you get careful reasoning about a plausible product that is not yours, and the more careful it is, the longer it takes to notice.