Space API guide
The Space API lets an organization run its own Spaces — meeting and board rooms, desks, offices, study rooms — from its own systems: an intranet, a room-booking screen, a front-desk app. A Space API key belongs to one Business and sees and books only that Business's Spaces. It can't search or book anyone else's.
You set your Spaces up once at space.tbbnetwork.com (locations, rooms, opening hours, capacity, calendars). The API then lists them, checks availability and books them.
1. Get an API key
- Create a Business at
business.tbbnetwork.comif you don't have one, and add your locations and Spaces. - Open
account.tbbnetwork.com/space-api-keys?businessId=<your Business id>. Switch on Test mode and select New test key, or leave it off and select New live key. The Owner, Admins and Developers can create test keys; live keys need the Owner or an Admin. - Copy the key when it's shown. You'll see it only once.
Test mode
A test key (tbbn_sk_space_sandbox_…) works like a live one — same calls, same checks on your Spaces,
availability and prices — but its bookings are test bookings: never charged, never holding the
Space, nobody notified, never on your hosts' bookings. They come back with "livemode": false,
and their paymentUrl, consentUrl or bookingUrl opens a test page where you give consent
or simulate a payment succeeding or failing. With Test mode on, the same page in
account.tbbnetwork.com lists your Test bookings. A test key lists and cancels only test
bookings; a live key only live ones. Test bookings are deleted after 90 days.
curl -X POST https://api.tbbnetwork.com/v1/space/api-keys \
-H "Authorization: Bearer <your session token>" \
-H "Content-Type: application/json" \
-d '{"businessId": "biz_...", "environment": "SANDBOX"}'
Send it as Authorization: Bearer tbbn_sk_space_... on every call below.
Limit a key to some locations with branchIds, when you create it or with
PATCH /v1/space/api-keys/{id}. It then finds and books only there. A request can name its location with a
Tbbn-Location header: one outside the key's list answers 403 LOCATION_NOT_GRANTED, and so does booking
a Space at another location.
Registers without a secret. Your server calls POST /v1/locations/{id}/connection_tokens with a live key and
your own id for whoever is working the register (staffRef), and hands the ten-minute token to the register. It
sends Authorization: Bearer <token> to the front-desk routes at that location, and nothing else works with it.
Withdrawing the key stops its tokens at once.
Locations. /v1/locations lists, imports (POST /v1/locations/batch, up to 500, by your own store number) and
changes your locations with the same key. A request naming a location with Tbbn-Location also has its own rate
limit, so one store's script can't use up the rest of the chain's.
A test copy. On your Business page, Make a test copy gives you a copy of your locations, Spaces and prices. A test key
made on the copy can change its locations through /v1/locations and book its Spaces as test bookings, so you can try a whole
integration without going near anything real.
2. Choose how bookings work
Each key has a booking mode:
bookingMode | What a booking made with the key does |
|---|---|
INTERNAL_FREE (default) | Reserves the room for someone in your organization. Nothing is charged, no commission or payout. It's booked at once. |
CHARGE_BOOKER | The person booked pays the Space's price on TBBN's hosted payment page, with its booking terms, processing fee and tax. Use this when you rent your own Spaces to outside people. |
curl -X PATCH https://api.tbbnetwork.com/v1/space/api-keys/<key id>/config \
-H "Authorization: Bearer <your session token>" \
-H "Content-Type: application/json" \
-d '{"bookingMode": "INTERNAL_FREE", "defaultCountry": "US"}'
Other settings on the same call:
defaultCountry,defaultRegion,defaultRadiusMilesfill in search filters you leave out.pinnedBranchIdssorts those locations first in search results (isPinned: true).consentMode(STRAIGHTorREQUIRE_CONSENT) applies only withCHARGE_BOOKER— see section 5.
You can change the mode in account.tbbnetwork.com too, under Bookings made with this key.
3. List your Spaces
curl "https://api.tbbnetwork.com/v1/space/search?query=board" \
-H "Authorization: Bearer tbbn_sk_space_live_..."
With a key, search returns your Business's live Spaces only, whatever their visibility —
PUBLIC, API_ONLY (shown only to your key; use it for internal rooms you don't want on the TBBN
site) or RESTRICTED_EMAIL. Each result is one bookable Space, with its id (used to book) and
its location's branchId.
Filters, all optional: country, region, postalCode, lat + lng (+ radiusMiles),
category, minCapacity, amenity, query (Space, location or city name).
GET /v1/space/spaces/{id} and GET /v1/space/branches/{branchId}/spaces work with the key too,
for your own Spaces.
4. Find an open time, then book
A Space with opening hours and a booking length is booked in slots: its open hours divided into bookings of that length, from opening (open 8:00 to 17:00 with 30-minute bookings: 8:00, 8:30 … 16:30); a booking a day or longer starts at opening. List them:
curl "https://api.tbbnetwork.com/v1/space/spaces/space_.../availability?from=2026-10-12&days=7" \
-H "Authorization: Bearer tbbn_sk_space_live_..."
Each day lists its slots with start, end, spotsLeft and a state: AVAILABLE, FULL,
BLOCKED (you or the host stopped bookings then), TOO_SOON, TOO_FAR or PAST. from is a date
in the Space's time zone (timeZone in the response); days is at most 62. Book with an
AVAILABLE slot's start as scheduledAt:
curl -X POST https://api.tbbnetwork.com/v1/space/bookings \
-H "Authorization: Bearer tbbn_sk_space_live_..." \
-H "Content-Type: application/json" \
-d '{
"spaceId": "space_...",
"serviceType": "WORKSPACE",
"scheduledAt": "2026-10-12T14:00:00Z",
"durationMinutes": 60,
"externalClientRef": "employee-042",
"guestName": "Ada Okafor"
}'
externalClientRefis required: your own identifier for who the booking is for.- When the Space has a booking length (
bookingLengthon the Space, e.g. 2 hours or 1 month), every booking lasts exactly that long anddurationMinutesis ignored; the booking's end is returned asendsAt. - Opening hours (
openingHourson the Space), lead time, blackout dates, your synced calendar and the Space's spots are checked as for any booking: a booking shorter than a day must start and end while the Space is open, a longer one must start while it's open, and a time when every spot is taken is refused. A clash returns400saying why —NOT_A_BOOKING_TIME(not a slot start),SLOT_FULL,SLOT_BLOCKED,SLOT_TOO_SOON,SLOT_TOO_FARorSLOT_PAST— with the next open times in the message and indetails.nextAvailable. Each booking is given a spot, returned asspotNumber. GET /v1/space/branches/{branchId}/spot-boardshows who should be in each spot now, who's next, and who's arriving in the next 24 hours.- A Space that isn't yours returns
404, the same as one that doesn't exist.
With INTERNAL_FREE the response is { booking, bookingUrl }. The booking is already confirmed
(status: PAID, every amount 0). bookingUrl is a booking page you can send the person; it
shows their check-in code (Coworking space), or the drop-off PIN for a drop-off.
5. Charging the person booked (CHARGE_BOOKER)
The same request returns a paymentUrl instead: send the person there to pay on TBBN's hosted
page. Payment always happens there, never in your app. With consentMode: REQUIRE_CONSENT (or
"requireConsent": true on a request) you get a consentUrl first; the booking waits as
AWAITING_CONSENT until they accept, then moves to payment.
A paid booking follows the Space's refund and no-show policy, and works only where TBBN Space takes payments.
6. See and cancel bookings
curl "https://api.tbbnetwork.com/v1/space/bookings?spaceId=space_...&from=2026-10-12T00:00:00Z" \
-H "Authorization: Bearer tbbn_sk_space_live_..."
curl -X POST https://api.tbbnetwork.com/v1/space/bookings/<booking id>/cancel \
-H "Authorization: Bearer tbbn_sk_space_live_..."
The list covers bookings at your own Spaces (filter by spaceId, branchId, from, to). It
never includes PINs or check-in codes. Cancelling an internal reservation simply ends it; a paid
one follows the booker's cancellation rules.
7. Team roles
The Owner, Admins and Developers manage keys and webhooks. See Team roles.
8. Drop-offs
For a drop-off booking, the person dropping off and the person picking up take the photos of the
item, through the booking's handover page; the host only checks each PIN. A Space's details
include hostAcceptsLiability and liabilityCapAmount, so you can show the terms before
booking.
9. Webhooks
Subscribe to space_booking.created, space_booking.consent_required,
space_booking.consented, space_booking.paid, space_booking.cancelled and
space_booking.completed:
curl -X POST https://api.tbbnetwork.com/v1/webhooks/business-subscriptions \
-H "Authorization: Bearer <your session token>" \
-H "Content-Type: application/json" \
-d '{"businessId": "biz_...", "url": "https://yourapp.example/webhooks/tbbn", "events": ["*"]}'
Deliveries are signed like Merchant webhooks (x-tbbn-signature: t=<ts>,v1=<hmac>, verify with
@tbbn/sdk-js's verifyWebhookSignature()), retried if your endpoint fails, and can be replayed
with POST /v1/webhooks/business-deliveries/{id}/replay.
Pricing
Calling the Space API costs nothing, and internal reservations are free. For bookings that charge the person booked, TBBN's commission is covered in Pricing.
