Skip to content

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.

  • 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.

On a computer with Node.js, run:

Terminal window
npx bookrail signup

Or 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.

Terminal window
npx bookrail init --template padel
npx bookrail push
npx bookrail services list

init 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.

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 server
functions 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:

Terminal window
npx bookrail webhooks create --url "<the address the agent gave you>" --events booking.created --events booking.cancelled

The 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.

Four checks you can do without reading the code:

  1. 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.
  2. 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.
  3. 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 list must still show one booking.
  4. 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.

When the test bookings behave, you switch to real ones. This is your decision, not the agent’s, and it takes four steps:

  1. Run npx bookrail push --live to create your courts, hours and service in the live environment: test and live share nothing.
  2. Run npx bookrail services list --live and note the live svc_ id.
  3. In the builder’s secrets, replace BOOKRAIL_SECRET_KEY with the live key and BOOKRAIL_SERVICE_ID with the live service id.
  4. 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.

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.