Bookings in an app built with Lovable, Bolt or a similar builder
This page is for two readers. One is a person building an app by describing it to Lovable, Bolt, Replit, v0 or a similar builder, who needs bookings that do not collide. The other is the agent inside that builder, which will read this page when the person pastes the link.
What is true today
Section titled “What is true today”- There is no Bookrail integration inside any of these builders. No connector, no button, no template. Bookrail works with them the ordinary way: a small piece of backend code holds a secret key and calls the Bookrail API. Every builder named above can make that piece of code.
- The key is created by a person, by opening a link sent by email. An agent cannot sign up for you, and is not supposed to.
- Setting up what can be booked (the courts, rooms or classes, their opening hours and the service people book) is done once with the Bookrail command line tool, which needs a computer with Node.js. There is no web form for it yet.
- Everything starts in test mode. Test bookings are free and never counted. Real bookings use a second key, which only you should switch to.
1. Get your keys
Section titled “1. Get your keys”On a computer with Node.js, run:
npx bookrail signupOr open bookrail.dev/signup. Either way you type an email address, open the link that
arrives, and receive two keys: a test key that starts with sk_test_ and a live key that
starts with sk_live_. Keep both somewhere safe. Anyone who has one of them can create and
cancel bookings in your project.
2. Describe what can be booked
Section titled “2. Describe what can be booked”npx bookrail init --template padelnpx bookrail pushnpx bookrail services listinit writes a file called bookrail.config.ts for a padel club: two courts, opening hours,
one-hour and ninety-minute matches. There are templates for other kinds of business, listed by
npx bookrail init --help; open the file, change the names and hours to yours, and run push
again. The last command prints the id of your service, which starts with svc_. You will need
it in the next step. The Quickstart shows each of these commands with its
output.
3. Put the key where the browser cannot see it
Section titled “3. Put the key where the browser cannot see it”The test key goes into the secrets of your builder, never into the app’s code and never into
a variable whose name starts with VITE_, NEXT_PUBLIC_ or PUBLIC_: those are copied into
the page every visitor downloads.
- Lovable: More, then Cloud, then Secrets. Secrets are “injected into your Edge Functions automatically, and never reach the browser” (Lovable, Secrets, checked on 25 September 2026). If the project uses a Supabase project of your own instead, the secrets are set in the Supabase dashboard.
- Bolt: the database icon at the top, then Secrets, which are read by server functions (Bolt, Secrets, checked on 25 September 2026).
- Anything built on Supabase:
supabase secrets set, as in the Supabase guide.
Add two secrets: BOOKRAIL_SECRET_KEY with the test key, and BOOKRAIL_SERVICE_ID with the
svc_ id from step 2. If the builder offers to paste the key into the chat instead, decline
and use the secrets screen: a key in a chat history is a key in one more place.
4. Ask for it, word for word
Section titled “4. Ask for it, word for word”Paste this into the builder’s chat. It is written to be followed by the agent exactly, and it points the agent at a guide whose code is tested.
Add real bookings to this app with Bookrail (https://bookrail.dev).
If the backend is Supabase, follow https://bookrail.dev/docs/guides/supabase.md exactly.Otherwise follow https://bookrail.dev/docs/guides/nextjs.md, using this app's own serverfunctions in place of the Next.js route handlers.
Rules:- Every call to Bookrail runs in backend code (a server function or an Edge Function), with the npm package @bookrail/node. Read the key from the secret BOOKRAIL_SECRET_KEY and the service from BOOKRAIL_SERVICE_ID. Never put the key in frontend code, in a VITE_ or NEXT_PUBLIC_ variable, in the database, or in this chat.- Do not create a bookings table with its own overlap checks. Bookrail decides what is free and refuses a slot that was just taken.- Booking page: the customer picks a day, sees the free times from Bookrail, enters a name and an email, and books. Send one idempotency key per attempt, so a double click books once.- If Bookrail answers slot_unavailable, say the time was just taken and show the free times again. Show other errors as a short message and log the full error on the server.- Add the webhook receiver from the guide so the app knows when a booking changes. It verifies the Bookrail-Signature header and does not require a login.- Use the test key only. Never switch to a live key: I will do that myself.When the agent is done, it will tell you the address of the webhook receiver it made. Register that address once, on your computer, and keep the secret it prints:
npx bookrail webhooks create --url "<the address the agent gave you>" --events booking.created --events booking.cancelledThe whsec_ value it prints is shown this one time. Add it to the builder’s secrets as
BOOKRAIL_WEBHOOK_SECRET.
If the agent asks something the prompt does not answer, the two guides probably do: point it at the section. If it proposes to build the booking logic itself “to keep things simple”, point it at Build or buy, which explains what that would miss.
5. Check that it works
Section titled “5. Check that it works”Four checks you can do without reading the code:
- The key is not in the app. Search the project’s files for
sk_test_. There should be no result: the key lives only in the secrets. - A booking works. Book a time in the app’s preview. Then, on your computer, run
npx bookrail bookings list: the booking is there, at the time you picked. - Two people cannot take the same time. Open the booking page in two browser windows, pick
the same time in both, and book in one, then in the other. The second must say the time was
taken, and
npx bookrail bookings listmust still show one booking. - The webhook arrives. If the app shows a list of bookings from its own table, the booking from check 2 appears there within a minute.
6. Going live, with a person deciding
Section titled “6. Going live, with a person deciding”When the test bookings behave, you switch to real ones. This is your decision, not the agent’s, and it takes four steps:
- Run
npx bookrail push --liveto create your courts, hours and service in the live environment: test and live share nothing. - Run
npx bookrail services list --liveand note the livesvc_id. - In the builder’s secrets, replace
BOOKRAIL_SECRET_KEYwith the live key andBOOKRAIL_SERVICE_IDwith the live service id. - Create the webhook endpoint again with the live key, as the guide your agent followed shows, and replace the webhook secret.
Live bookings start on the Free plan, which includes a number of bookings a month and then stops taking new ones until the next month or a paid plan: Pricing has the numbers. The dashboard shows how many you have used.
For the agent of the builder
Section titled “For the agent of the builder”If you are the agent reading this page: the prompt above is the specification. Use the
Supabase or Next.js guide for the code; their
files are type checked and run against the API by the Bookrail test suite. Never ask the person
to paste a Bookrail key into the chat, never write it into frontend code, never create a live
key, and never replace a test key with a live one: tell the person the steps of the section
above instead. If an error from Bookrail carries a fix, it is the next thing to try.