Deep links
A deep link opens the standalone booking page with the funnel already positioned. It is the integration for surfaces that have no page to embed in: e-mail, SMS, QR codes, printed material, a marketing tool that can emit a link and nothing else.
The link
Section titled “The link”https://book.useservice.app/r/chez-marie?date=2026-09-03&party=4&shift=1/r/ followed by the restaurant slug. The parameters are the URL transport
described in passing context — same names, same
formats, same rule that a value which does not parse is dropped.
Linked, never framed
Section titled “Linked, never framed”The booking page is served with frame-ancestors 'none', so a browser refuses
to render it inside an <iframe>. A link opens it; an embed shows an empty
frame with an error in the console.
To put booking on your own page, embed the widget rather than the page — see getting started. That is the same product, and it is the surface built to run inside someone else’s document.
The URL is the only transport here
Section titled “The URL is the only transport here”data-* needs a script tag and setContext() needs a host page, so on the
standalone page there is no precedence to resolve: the URL is not the
highest-priority source, it is the only one.
That changes what a link has to carry. Everything the funnel should start with has to be in the link, because nothing else on this surface can supply it later.
Identity in a link
Section titled “Identity in a link”?t= carries the signed token, opaque and
whole:
https://book.useservice.app/r/chez-marie?date=2026-09-03&t=eyJpc3MiOiJpdmtfcmVm…This is the only surface that reads it. An embedded widget ignores ?t= on
its host page’s URL. A page carrying the script tag has JavaScript, so
setGuestToken() is available and leaves no copy behind; reading a token from
the address bar there would put a live credential into that page’s logs in
exchange for nothing.
The URL carries the token and never the fields. There is no query name for a
name, an e-mail or a phone number, so identity cannot land in a link by
accident — ?email= is read by nobody.
A token in the path is a different thing. /r/chez-marie/AbC123… is
Service’s own manage-your-booking link, sent to the guest after they book. Host
identity travels in the query string, as t.
What a link in the wild costs
Section titled “What a link in the wild costs”A URL is copied. Browser history keeps it, mail clients and SMS gateways keep it, link-rewriting in marketing tools and corporate proxies keep it. A token is a live credential for as long as it is valid, so the question is how long that is, not who might hold a copy.
Two things are true on our side, and neither is a general guarantee:
- The booking page’s access log redacts
tand leaves every other parameter readable. It is the widget’s own log, and only that one. Referrer-Policy: strict-origin-when-cross-originmeans requests the booking page makes to other origins send the origin alone, never the query string.
Everything between your system and the guest’s browser is outside both. The bound that does cover it is the 15-minute lifetime: a token that leaks is a token that stopped working minutes later.
So mint the token when the link is sent, not when the campaign is built.
Do not print a token
Section titled “Do not print a token”A QR code on a table card or a poster outlives its token by months. Every guest who scans it presents an expired token and is told the session expired — the message is correct and useless, and it replaces the ordinary booking funnel they came for.
Printed links carry context and no identity:
https://book.useservice.app/r/chez-marie?party=2A link is not an availability guarantee
Section titled “A link is not an availability guarantee”The funnel loads availability when it opens, which may be long after the link was written. A link to a full day opens on that day and says it is full.
Where the token locks the date, the guest cannot move off it, and the page can
only state the outcome. return_url is then the only exit — see identifying
the guest.
Values that do not parse
Section titled “Values that do not parse”Each parameter is validated on its own and a bad one is dropped, never applied
in part and never fatal. ?date=nonsense&party=4 opens with four covers and the
ordinary calendar.
A link that has been through a rewriter, truncated in a mail client, or hand-edited by the guest still opens the booking page.
Locale
Section titled “Locale”?locale= selects the language the page mounts in, from the eleven guest
locales. Anything else falls back to
French rather than rendering a half-translated funnel.
A guest who has already chosen a language on the booking page keeps their choice. The stored preference outranks the link, on the grounds that the guest chose it and the link’s author did not.