If your booking system is not one of the PMSs BetterSTR connects to, you can push bookings yourself through the BetterSTR API. Create a credential with Write access, send a few JSON calls, and your guests get their personal guidebook link, the TV greets them by name and your check-in automations fire, exactly as they would from a PMS sync. This article walks through the basics; the full reference and a “try it out” console are at api.betterstr.com/user-api/docs.
What you can do with a write key
- Properties – create, update and delete the properties you manage without a PMS (address, timezone, check-in and check-out times, capacity, picture, tags).
- Bookings – push a booking with the guest’s name, dates, contact details and door code; update it, cancel it, or import up to 50 at a time.
- TVs – list your BetterSTR TVs, check power, switch them on or off, put a message on screen, change settings.
- Everything else the API already does – guidebook entries, tags, map locations, SMS to guests, payment links, the WiFi guest list.
Bookings that come from a connected PMS stay read-only, because the PMS is their source of truth. The write calls only touch properties you added yourself.
Step 1: create a credential with Write access
- Log in and open Profile → API Credentials (gb.betterstr.com/members/profile/api-keys.php).
- Click Create, give it a name, and tick Write access.
- Copy the
client_id(starts withbsc_) and theclient_secret(starts withbss_). The secret is shown once.
Existing credentials stay read-only
Write access is set when a credential is created and cannot be added to an old one. If you made a credential before this feature existed, create a new one with the box ticked and revoke the old one when you no longer need it.
Every request uses HTTP Basic auth with the two values. The examples below use placeholders; put your own in.
Step 2: find your property
curl -u "bsc_your_client_id:bss_your_client_secret" \
https://api.betterstr.com/user-api/v1/properties{"data":{"properties":[{
"uuid":"4f0c9a2e-6b1d-4c8e-9f3a-2d7e8b1c5a60",
"name":"Harbour View Apartment",
"city":"Auckland","country":"NZ",
"timezone_iana":"Pacific/Auckland",
"guide_url":"https://gb.betterstr.com/26/g/4f0c9a2e-6b1d-4c8e-9f3a-2d7e8b1c5a60"
}],"total":1}}The uuid is what every other call uses. If you have no property yet, add one in the dashboard first (see Add a Property Manually). Booking times you send are read in the property’s timezone_iana, with daylight saving handled for you.
Step 3: push a booking
reference is your own booking number. Sending the same reference again updates the booking instead of creating a second one, so re-sending your whole calendar every night is safe.
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X POST https://api.betterstr.com/user-api/v1/reservations \
-H "Content-Type: application/json" \
-d '{
"property_uuid": "4f0c9a2e-6b1d-4c8e-9f3a-2d7e8b1c5a60",
"reference": "BK-1001",
"first_name": "Ana", "last_name": "Silva",
"email": "ana@example.com", "phone": "+64211234567",
"check_in": "2026-12-20 15:00", "check_out": "2026-12-23 10:00",
"guests": 2, "door_code": "4821",
"total_amount": 540, "currency": "NZD"
}'HTTP 201
{"data":{"reservation":{
"id":"manual_u12345_bk-1001",
"reservation_code":"BK-1001",
"status":"accepted",
"guide_url":"https://gb.betterstr.com/26/g/r/manual_u12345_bk-1001",
"arrival_date":"2026-12-20 15:00:00","departure_date":"2026-12-23 10:00:00",
"nights":3,"guest_name":"Ana Silva","guests":2,"door_code":"4821"
},"created":true,"notified":true}}Required: property_uuid, reference, first_name, check_in, check_out. Optional: last_name, email, phone, guests, status (accepted, pending or cancelled), door_code, notes, total_amount, currency, notify.
A brand-new booking triggers your guest automations (the guide link by SMS or email, if you have set them up), exactly like a booking from a channel. When you import old bookings add "notify": false so nobody gets a welcome message for a stay that has already happened. The guest shows on the TV automatically during their stay, and guide_url is their personal guide link.
Step 4: update or cancel
Address a booking by your reference or by our id:
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X PATCH https://api.betterstr.com/user-api/v1/reservations/BK-1001 \
-H "Content-Type: application/json" \
-d '{"guests": 3, "door_code": "5678"}'
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X POST https://api.betterstr.com/user-api/v1/reservations/BK-1001/cancel
curl -u "bsc_your_client_id:bss_your_client_secret" \
"https://api.betterstr.com/user-api/v1/reservations?checkin_from=2026-12-01&checkin_to=2026-12-31"Step 5: import many at once
Up to 50 bookings per call. Bulk calls never send notifications and report success or failure per row, so one bad date does not stop the rest.
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X POST https://api.betterstr.com/user-api/v1/reservations/bulk \
-H "Content-Type: application/json" \
-d '{
"property_uuid": "4f0c9a2e-6b1d-4c8e-9f3a-2d7e8b1c5a60",
"reservations": [
{"reference":"BK-1002","first_name":"Marc","check_in":"2026-12-27 15:00","check_out":"2027-01-02 10:00"},
{"reference":"BK-1003","first_name":"Yuki","check_in":"2027-01-05 15:00","check_out":"2027-01-08 10:00"}
]}'Step 6: your TVs
curl -u "bsc_your_client_id:bss_your_client_secret" \
"https://api.betterstr.com/user-api/v1/android-tv?include=power"
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X POST https://api.betterstr.com/user-api/v1/android-tv/<device_id>/message \
-H "Content-Type: application/json" \
-d '{"text":"Welcome! The ski bus leaves at 8:30."}'
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X POST https://api.betterstr.com/user-api/v1/android-tv/<device_id>/power \
-H "Content-Type: application/json" \
-d '{"state":"on"}'Listing always works. Calls addressed to one TV need that TV to be on a plan; the free trial counts.
Update your property details
curl -u "bsc_your_client_id:bss_your_client_secret" \
-X PATCH https://api.betterstr.com/user-api/v1/properties/4f0c9a2e-6b1d-4c8e-9f3a-2d7e8b1c5a60 \
-H "Content-Type: application/json" \
-d '{"timezone":"Pacific/Auckland","currency":"NZD","checkin":"15:00","checkout":"10:00"}'Other fields: name, street, city, state, postcode, country, latitude, longitude, max_capacity, bedrooms, beds, bathrooms, picture, tags.
What needs a paid plan
- Reading is free, as always.
- Pushing bookings to a property, or changing its details, needs that property on Guidebook Premium or BetterSTR Simple. Without it the call returns
402 paid_property_required. - Creating properties through the API needs Premium with the flat-rate option covering all properties, because each new property joins your next bill automatically (the response tells you the monthly cost). On other plans, add properties in the dashboard.
- Limits: 5,000 new bookings and 1,000 new properties per account per day. If your first sync is bigger, contact support and we will lift them for the day.
Errors you may see
| Code | Meaning |
|---|---|
401 invalid_credentials | Wrong client_id or client_secret. |
403 insufficient_scope | The credential has no Write access. Create a new one with the box ticked. |
402 paid_property_required | The property is not on a paid plan. |
409 not_manual_property | That property is synced from a PMS and cannot be written to. |
409 property_locked | A booking cannot move to another property. Cancel and re-create it. |
422 invalid_reservation | Check errors in the response, for example “check_out must be after check_in”. |
429 rate_limited | Slow down and retry after the Retry-After header. |
All responses are {"data": ...} on success and {"error": {"code", "message"}} on failure.