#016Everwood BookingLearningIntermediate

The Cancel Button Is the Easy Half. We Have No Rules to Put Behind It.

I expected this research to be about proving a customer owns their booking. Then I found that our customers can already cancel and reschedule, by talking to the booking assistant, while the account they sign into can only show them their appointments. The capability exists and the button does not. What is missing is smaller to describe and harder to skip: a business cannot set a cancellation rule anywhere in Everwood, so a cancel button today could only ever say yes.

By the Everwood founder · September 8, 2026 · 12 min read

Tools
SupabasePostgresNext.jsTypeScript
Concepts
Policy as ProductPasswordless IdentityAutomating JudgmentProgressive DisclosureSilent Failure
Mission Brief
Goal

Work out what a first version of customer self-service booking management should be for Everwood: what a customer may change on their own, how we know the booking is theirs, and what the business still controls.

Problem

I framed it as an identity problem and spent the research on secure links. Our customers can already cancel and reschedule through the booking assistant, gated by an emailed code, while the account surface that knows who they are stays read only. The thing we do not have is any cancellation rule at all.

Lesson

Adding a self-service action removes a human decision, and the human was doing more than answering the phone. They were making the exception. Automate the request and the judgment has to become a rule, written in advance, applying to everyone.

Read as

The Build

Nothing shipped from this research. No manage-booking page exists, no cancel or reschedule button was added anywhere a customer can see, and the roadmap node this came from is in beta because of what was built months ago, not because of anything in here. What changed is the order I think the work goes in.

The customer problem is the one every service business has. Something comes up on Wednesday, the appointment is Thursday, and the only way to move it is to reach a person during opening hours. That turns a thirty second change into a phone call, a voicemail, or a message somebody has to read and act on later.

I went into this expecting the hard part to be proving who somebody is. Letting a stranger with a link cancel an appointment is the kind of thing that goes badly in public. I came out thinking identity is the part we have mostly solved, and that we are missing something less interesting and more important.

The Problem

Here is the thing I did not expect to find in our own product.

A customer can already cancel and reschedule. They do it by talking to our booking assistant. Before it will touch an existing appointment, the assistant asks for the email on the booking, sends a one-time code to that address, and refuses to go further until the code comes back. Only then will it list what they have booked, move it, or cancel it.

Meanwhile the place where a customer signs into their own account, the surface that already knows exactly who they are, can only show them their appointments. It cannot change one.

So the capability exists and the button does not. We built self-service management into a conversation and never gave it a front door.

That inverts the way I had been describing this work to myself. I thought we were adding a customer capability. We are mostly adding a second, quieter entrance to a capability that already ships, and the interesting question is not who is allowed in, but what the room does when they get there.

Which brings me to the part that is actually missing.

There is no cancellation policy in Everwood. Not a weak one. None. A business cannot set a cutoff after which a customer may no longer cancel online, cannot attach a fee to a late cancellation, and cannot state a refund position, because there is nothing to state it about. The only time rule we have anywhere is a minimum notice for making a new booking, and it defaults to an hour.

Today that gap does not show, because the phone call is the policy. When a customer wants to cancel two hours before their appointment, they have to reach a person, and that person can say no, or say yes, or say yes this once. The friction everyone complains about is also the enforcement.

Put a cancel button on a page and the enforcement goes away. Not weakened. Gone, quietly, on a Tuesday, with nobody having decided anything.

I should follow that argument where it actually leads, because it convicts something we already ship. The assistant will cancel a verified appointment at any hour, for any reason, with no rule to consult, which means the phone call has already stopped being the policy for every customer who thinks to ask a chat window. The gap is open. It is just narrow, because it sits behind a conversation most people never start.

That makes writing the rules more urgent rather than less, and it changes what the first piece of work is. It is not a new front door. It is the rule that both doors should have been checking all along.

Assumption vs Reality

What I Thought Would Work

Build a secure manage-booking link, put it in every confirmation email, and let the customer cancel or reschedule from there. Solve the link security carefully, because that is the risky part, and let the merchant rules follow later as settings.

What Actually Happened

The research spent most of its length on link security, and the more I read the less of that work turned out to be in front of us. There is a real hazard in that section, and I want to describe it properly because it is the sort of thing that only shows up after launch. Company email systems inspect links before a person ever reads the message. Microsoft's own documentation says its scanner rewrites links by default and checks them before the message is delivered. So if a link is designed to be usable exactly once, and it does its work the moment it is opened, the security scanner can spend it on the way through. The customer opens their email, clicks a perfectly good link, and is told it has already been used. Nobody did anything wrong and the feature looks broken. We do not have that problem, and not because we were clever. We send codes, not links. The assistant asks the customer to type six digits from their inbox, and typing is something a scanner cannot do on their behalf. Signing into a customer account works the same way. That design was already there for a different reason, and it happens to dodge the hazard entirely. We are also not starting from zero on signed links. We already send one, on the calendar file attached to a confirmation. I read it while I was in there, and it does its job, but it has no expiry, which is fine for handing somebody a copy of their own appointment and not fine for anything that changes one. If we ever put a change behind a link, it does not get to inherit that pattern. So the access work is smaller than advertised. The policy work does not exist at all.

The Fix

What changed is the design, not the code. Three things I now believe.

The rules come before the button. A cancellation policy is not a settings screen we bolt on once the flow works. It is the thing the flow is enforcing, and without it the only honest label for the feature is cancel anything, any time, for free. Square, which has been running this for years, sells it as one idea: a switch that lets clients reschedule or cancel before a cut-off time, a cut-off the merchant picks from an hour up to two weeks or turns off, and a fee structure sitting next to it. That is not three features. That is one feature with a rule inside it.

When the rule says no, say so and say why. The tempting implementation hides the cancel button when a customer is inside the cutoff, which reads as a broken page and produces the phone call you were trying to avoid. Show the button, disable it, and name the reason and the alternative in a sentence. The customer who cannot cancel online still learns something they did not know, which is that this business needs a day of notice.

Reschedule is not an edit. It looks like changing a field on a booking, and every platform I could verify treats it as something heavier. Calendly has no way to reschedule an appointment through their interface for developers at all. A reschedule there is recorded as the old booking being cancelled, flagged as a reschedule and pointing at its replacement, plus a new booking created alongside it. That framing is worth stealing, and not for tidiness. Build Note #015 ended on the finding that Everwood has no single moment meaning a slot became sellable. If a reschedule is a cancellation plus a booking, then every reschedule produces that moment too, and the two features stop being separate projects.

One thing the research recommended that I am going to skip. It suggests blocking self-service cancellation on prepaid appointments, which is what Square does once a merchant is taking money up front. We take no money from customers at all. Deposits are a different roadmap idea, and importing its hardest rule into a feature with no payments in it would be borrowing a constraint we have not earned.

Lesson Unlocked

Adding a self-service action removes a human decision, and the human was doing more than you think. The phone call was slow, awkward, and it was also where the exception lived. A customer explained, a person judged, and the judgment never had to be written down. Automate the request and the judgment has to become a rule, in advance, applying to everyone, including the regular of nine years who has never missed an appointment. That is a real cost, and it is not an argument against building this. It is an argument for building the rule first, and for being honest that the rule is coarser than the person it replaces. The general version. Before removing a step where somebody used judgment, find out what that judgment was protecting, and decide who is going to make it now.

Business Translation

For a salon owner, here is where this stands today. Your customers can already cancel and reschedule without calling you, but only by talking to the booking assistant, and only after it emails them a code to prove the appointment is theirs. If they sign into their Everwood account instead, they can look at their bookings and nothing else. That is not a decision anybody made. It is an accident of the order things were built in. What we do not have is your rules. There is no place for you to say you need twenty four hours of notice, no way to charge for a late cancellation, and no refund setting, because Everwood does not take deposits from your customers in the first place. I could ship a cancel button next month. I do not want to, because until your rules exist that button says yes to everything, including the customer cancelling at eight in the morning for a nine o'clock appointment. Right now that customer has to ring you, and you get to decide. A button with no policy behind it takes the decision away from you and hands it to nobody. So the order is your rules first, then the button. When it does arrive, a customer who is inside your window should not meet a dead page. They should see plainly that this business needs a day of notice, and that they can call you.

Builder Notes

A research pass on customer self-service that turned into an audit of what our customers can already do, and where the rules for it were supposed to live. Nothing was built. No manage-booking surface exists.

Technical Note 1

Shipped today: passwordless customer accounts, where signing in means typing a one-time code emailed to the customer. The code is never stored in a form we could read back, comparisons are constant time, and attempts are rate limited. A booking made as a guest can be attached to an account afterwards, using the booking reference plus a code sent to the same address.

Technical Note 2

Also shipped, and the surprise of this research: the booking assistant can list, cancel and reschedule an existing appointment, gated behind that same kind of one-time code sent to the email on the booking. The signed-in account surface, by contrast, is read only. The place that knows who you are cannot change anything, and the place that has to ask can.

Technical Note 3

Missing entirely: any cancellation policy. No cutoff, no fee, no refund rule, nothing to show a customer at booking time. Minimum notice for a new booking exists and defaults to an hour, and it is not the same rule. The assistant cancel path consults nothing, so the policy gap is already live wherever a customer thinks to ask.

Technical Note 4

We already run two kinds of signed link, and they are not equally strong. The calendar file link is signed with a shared secret and never expires. The token behind party planning carries an expiry, is compared in constant time, and requires the caller to independently confirm the business it names. Only the second pattern is a candidate for anything that changes a booking, and even then the delegation question has to be answered first.

Technical Note 5

Concurrency is not the risk here that it would be elsewhere. Two people cannot end up in the same slot, because the database refuses overlapping appointments for a staff member rather than trusting an application check. What is undecided is what the customer sees when their reschedule loses that race.

Technical Note 6

Square, from their own documentation: a merchant switch reading clients may reschedule or cancel their own appointments before the cut-off time, a cut-off selectable from one hour to two weeks or none, no online self-service on a prepaid appointment once it has been accepted, and no-show fees charged flat per appointment, flat per service, or as a percentage of the service price.

Technical Note 7

Calendly, from their developer documentation: no endpoint reschedules an appointment. A reschedule arrives as a cancellation carrying a reschedule flag and a pointer to the replacement, plus a separate creation event.

Technical Note 8

Microsoft, from their own documentation: link rewriting is on by default and links are checked before the message reaches the recipient. Any single-use link we build has to survive being opened by something that is not a person. We send codes instead, so this is a hazard we avoid rather than one we solved.

Technical Note 9

Payments: nothing in the booking flow charges a customer. The payment code we run is for businesses subscribing to Everwood. That makes the prepaid cancellation rules in the research inapplicable for now.

Technical Note 10

Cut from the research and kept in the ledger: a named survey with no citation, the access models of six platforms with nothing primary behind them, and a claim about which kind of request email scanners issue. The general scanner behaviour is documented and survived. The specific mechanism did not.

Technical Note 11

Worth flagging, because it is the most useful thing in the whole pile: the public blog post that came back with this research announces that self-service management is rolling out to all merchants this week. None of it exists. It is a well written page describing a product we have not built, and publishing it would have taken one copy and paste. A research deliverable that arrives with marketing copy attached needs every sentence treated as a claim wanting a source, exactly like the rest.

Before / After

How I was framing it
  • The hard part is proving the customer owns the booking
  • Self-service management is a new customer capability
  • The manage-booking link is the product
  • Merchant rules are settings we add after the flow works
  • Reschedule is an edit to an existing appointment
How I frame it now
  • The hard part is deciding the rules for when nobody is there to judge
  • The capability exists in the assistant and has no visible front door
  • The policy behind the button is the product
  • The rules are the flow, and there is no honest version without them
  • Reschedule is a cancellation and a new booking, which our waitlist thinking needs anyway

What I'd Do Differently

I would have checked what our own customers could already do before researching how to give them the ability.

Every framing I started with treated self-service change as something Everwood does not have. It has it, in the assistant, guarded by a verification step somebody built carefully. That single fact reorders the project: the work is not build a capability, it is give an existing capability a second entrance and finally write down the rules it should obey.

The general version. When research says add something, check whether a corner of the product already does it badly, or does it well and invisibly. What you find there tells you whether you are building a feature or finishing one.

Next Experiment

The first step is not code, and it is not a customer-facing change. Write the policy model and put it in front of a few owners. One cutoff for customer changes, expressed the way a person would say it, plus what should happen inside that window, plus whether a business wants a different answer for cancelling than for rescheduling. My guess is that most want a longer window for cancelling and a shorter one for moving an appointment, because a moved appointment keeps the customer. That is a guess, and asking five owners would settle it. Then the smallest visible piece. Show the policy on the appointment: at booking, in the confirmation, and on the customer's account page. No buttons yet. A customer who reads that this business needs twenty four hours of notice is better off than one who finds out when they call, and displaying the rule is a genuine test of whether businesses will set one. Only then the button, on the account surface where we already know who is signed in, doing exactly what the assistant already does, and refusing when the rule says to refuse. There is a fourth thing I want to be honest about, because it is the assumption underneath the whole idea. I believe people avoid phoning a business to cancel, and that some of them simply do not turn up instead. I have no data for that. If it is wrong, self-service is a convenience rather than a way to turn a silent no-show into a slot somebody else could have taken, and it belongs lower on the roadmap than I have been putting it.

ResearchSaaS ArchitectureBooking WidgetSecurity

The information on this website is provided for general educational purposes only and may not apply to your specific setup or environment. It should not be considered professional advice. Always consult a qualified technician when appropriate.