Skip to main content
The dermatologist is booked out for four months, the passport office for six weeks, and cancellations appear at random and go within the hour. Refreshing a booking page all day is the only way to get one. This program watches the page for you, reads every open slot the moment the page changes, picks the first one that fits your rules in your own code, and either books it or gets it to the last screen and hands you the live browser to confirm it yourself.

What you need

  • An Outcrawl API key in OUTCRAWL_API_KEY.
  • A profile signed in to the booking site with your details saved on the account, and its id in PROFILE. The monitor and every run use it, so they see the page as you do.
  • A server reachable from the internet (the monitor posts to it), and a long random string in HOOK_TOKEN for its paths.
  • A way to reach your phone. The program posts to an ntfy topic; any push or chat webhook works the same way.
Book for yourself, one appointment at a time. The program deletes its monitor once a booking is made (in hand-off mode, when you tap the done link), so it never takes a second slot.

How it works

1

A monitor watches the booking page

monitors.create checks the page every 10 minutes with your profile. It posts to your endpoint only when the page really changes, and a diff that only removes lines (a slot going) is ignored.
2

A first run lists every open slot

Your endpoint starts an agent run that books nothing: it answers a schema listing each open slot’s date, time, clinician and location.
3

Your code picks the slot

acceptable() applies your rules (weekdays, before 10:00 or after 16:00, within 21 days) to that list. The agent never decides which slot is good enough; your code does, before anything irreversible happens.
4

Book mode: a second run books exactly that slot

It books the slot your code approved and no other, and returns the confirmation number. Rules keep it on the clinic’s site and stop it making a payment.
5

Hand-off mode: you confirm it in the live view

The run picks the slot and goes through the form. When its event stream shows the slot being picked, your code calls control('take'), and your phone gets the live view link. You press take control there, confirm, and tap the done link, which ends the run and deletes the monitor.

The program

Run it once with watch to create the monitor, then run it as a server. Set SLOT_MODE=hand-off to confirm bookings yourself; it books on its own otherwise.

The limits of each mode

  • Book mode is two runs, so a slot can go in the seconds between them. The booking run is told to book that slot or nothing, and reports booked: false when it is gone; the next change starts a fresh hunt.
  • Hand-off mode holds the run at the agent’s next step boundary, not instantly. The step already under way finishes first. On a site where picking the slot and confirming are separate screens, that is one more field or a Continue button; on a site where one click books, it is the booking of a slot your rules already approved.
  • If the site asks for a deposit, Never make a payment. blocks the agent at the card form in either mode. Use hand-off mode and pay it yourself.

What you get back

In book mode, one push:
In hand-off mode, a push whose tap opens the live view:
The first run’s answer, which your code filters:
The first slot falls on a Sunday and the third at lunchtime, so the program takes the 08:40 on Tuesday.

What it costs

  • Watching is 1 credit per check, whether or not the page changed, per pricing. A check every 10 minutes is 144 checks a day, so 144 credits a day.
  • Listing slots is one agent run, billed for the model’s usage, browser time and proxy usage. A typical run costs about 15 credits a minute all in, and the real figure depends on the task and how heavy the pages are. About 40 s is about 10 credits each time new slots appear.
  • Booking is about a minute: about 15 credits, once.
  • Hand-off bills the agent’s part the same way. While you hold the wheel, whether after control('take') or by driving in the live viewer, the run bills browser time (1 credit a minute) and proxy usage only, with no model usage, until you hand it back. Here the done link cancels the run, which stops the clock: five minutes from the push to your tap is about 5 credits, plus proxy usage for the pages you load. caps.duration ends the run after 10 minutes if you never come back.
A page where new slots appear five times a day costs about 144 + 5 × 10 = 194 credits a day until the booking lands.

Make it yours

  • Watch several clinics at once: one monitor per booking page, all posting to the same endpoint, and delete every monitor once one books.
  • Change acceptable() to match your week: a particular clinician, a location near you, or a date before you travel.
  • Send the hand-off link to Slack or SMS instead of ntfy; it is one HTTP call.
  • Check every 5 minutes instead of 10 on a page where slots go fast. That is 288 checks a day, so watching costs 288 credits a day instead of 144.

Monitors

Schedules, notify targets and profiles.

Human in the loop

Take and release control of a live run.

Profiles

Stay signed in to the booking site.

Rules

Stop the agent paying for anything.