Space API Guide
TBBN Space is "calendly for space" — a standalone product with its own public API for
discovering and booking verified TBBN Spaces worldwide, independent of the TBBN marketplace.
Any business or organization can search Spaces globally, embed that search/booking capability
into their own product, and reserve a Space on behalf of their own clients — even clients who
have no TBBN account at all. See docs/business/conflict-resolution-log.md item 26 for the
founder directive and the design decisions behind this.
This is deliberately a different surface from the marketplace's own Space picker
(GET /v1/branches/nearby-spaces, used when a trader is arranging a peer-to-peer trade
exchange) — that endpoint always defaults to a 200-mile radius and stays scoped to the
marketplace's own trade flow. This guide's endpoints are unbounded (unless you ask for a
radius) and open to any consumer, not just TBBN's own marketplace.
1. Global search — no account required
curl "https://api.tbbnetwork.com/v1/space/search?country=US&query=downtown"
Filters (all optional, combine freely): country, region (state/province), postalCode,
lat+lng+radiusMiles (omit radiusMiles for unbounded-but-sorted-by-distance; omit
lat/lng entirely for no distance filtering at all), query (free-text against the Space's
name, its Branch's city, or the host Business's name). Each result is a Space — a single
bookable room (a Branch can host several: "Study Room A," "Meeting Room B," etc.) — not a whole
Branch, so branchId and id (the Space's own id, used for booking) are both present on every
result. Every returned Space's Branch has spaceStatus: SPACE_ENABLED — this is this pass's
de-facto "verified Space" gate, and a Business must additionally be verificationStatus: VERIFIED before it can even create a Space (see section 6) — there is no separate
moderation/review workflow beyond that yet, since ops-console (TBBN's internal ops tool) has no
real staff-authentication principal type to operate one against.
Visibility. A host sets each Space's visibility to PUBLIC (shown here to anyone),
API_ONLY (never shown to an unauthenticated or session-only viewer — only returned when a valid
sk_space_* key is presented), or RESTRICTED_EMAIL (only shown to a signed-in TBBN member
whose verified email matches an exact allowlist or a domain, e.g. @cornell.edu, that the host
configured). Search results are filtered to exactly what the presented credential is allowed to
see — an unauthenticated call only ever sees PUBLIC Spaces.
2. Get an API key
Register a Business at business.tbbnetwork.com if you don't have one (any registered TBBN user
can — a Business needs no Merchant relationship at all), then create a Space API key at
account.tbbnetwork.com/space-api-keys?businessId=<your Business id>. You'll see the full key
exactly once — store it like any other secret.
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"}'
Presenting this key on a search call (Authorization: Bearer sk_space_sandbox_...) applies your
saved configuration automatically — no need to repeat your defaults on every request.
3. Configure default filters and "primary results"
curl -X PATCH https://api.tbbnetwork.com/v1/space/api-keys/<id>/config \
-H "Authorization: Bearer <your session token>" \
-H "Content-Type: application/json" \
-d '{
"defaultCountry": "US",
"defaultRadiusMiles": 50,
"pinnedBranchIds": ["branch_id_1", "branch_id_2"]
}'
defaultCountry/defaultRegion/defaultRadiusMilesapply to any search call made with this key that doesn't explicitly override them.pinnedBranchIdsalways sort first in search results (flaggedisPinned: true) regardless of other filters — use this to feature your own preferred locations. (Pinning is still by Branch id — a pin surfaces every Space at that Branch first.)consentMode(STRAIGHTorREQUIRE_CONSENT) — see section 5.
4. Book on behalf of a real TBBN member
If the person being booked already has (or is willing to create) a TBBN account, have them
authenticate normally and call POST /v1/space/bookings with spaceId (the specific room from
your search results, not a branchId) and their own session token — this is the same booking
flow the marketplace itself uses, and it always books+pays straight through (there's no consent
step on this path — the booker is always the payer).
5. Headless booking — on behalf of a client with no TBBN account
Present your sk_space_* key instead of a session token, and include externalClientRef — your
own opaque identifier for that client (never a TBBN identity):
curl -X POST https://api.tbbnetwork.com/v1/space/bookings \
-H "Authorization: Bearer sk_space_live_..." \
-H "Content-Type: application/json" \
-d '{
"spaceId": "space_...",
"serviceType": "MEETUP",
"externalClientRef": "your-internal-client-id-042"
}'
You decide whether this needs an explicit consent step first. By default (consentMode: STRAIGHT, or requireConsent: false on the request) the response includes a paymentUrl
straight away — the same "select a location and pay/reserve it" flow as before. Set your key's
config to consentMode: REQUIRE_CONSENT (section 3), or pass "requireConsent": true on a
specific booking, to instead get back a consentUrl: the booking is created AWAITING_CONSENT
with no payment intent yet, and only after your client visits that link and accepts does the
booking move to PENDING_PAYMENT and produce a real paymentUrl. This mirrors the TBBN
marketplace's own rule that both parties must accept a Space before the person who picked it
pays — third-party integrators get to choose which behavior fits their own product.
Redirect your client to whichever URL comes back (consentUrl or paymentUrl), or embed it in
an iframe. TBBN Space payment (and, when required, consent) must happen on TBBN's own site
(this is a firm rule, not a preference — see TBBN_Flow.docx §7.3), so these hosted links are
the only way a headless booking gets accepted and paid; there is no way to collect that payment
yourself and report it back. Once your client pays, the host is notified and can confirm the
exchange — from the host's own space.tbbnetwork.com session, or via the same hosted payment
link (which also authorizes confirm/cancel with no TBBN session, the same way it authorizes
payment).
Even a free Space still requires this hosted step. If the Space's host listed it as free
(isFree: true), the booking's grossAmount is 0 and no real charge happens, but your client
still lands on the hosted page and must click through an explicit "Confirm free reservation"
action before the reservation is finalized — TBBN never auto-confirms a reservation without a
visit to its own page, free or not.
This repo's own Stripe integration in this environment is a dev simulation — a real production deployment replaces the hosted page's "Simulate payment" button with an actual Stripe payment element (skipped entirely for a free booking), and has Stripe itself call the payment webhook rather than a button click.
6. Getting your Business verified
A Business cannot create any Space until TBBN verifies it — register at
business.tbbnetwork.com, then wait for review. There's no self-service verification flow yet;
until admin.tbbnetwork.com ships, TBBN staff review new Businesses manually. Attempting to
create a Space before verification returns an error naming this requirement.
7. Team roles
More than one person can manage a Business's Spaces and API keys — invite teammates with a role
(ADMIN, DEVELOPER, or ACCOUNT_MANAGER) at account.tbbnetwork.com/team?businessId=....
ACCOUNT_MANAGER can create/edit Spaces and pricing; DEVELOPER can create sandbox API keys and
manage search/consent config (production keys need ADMIN); ADMIN can also manage the team
itself. The Business's original creator is always the implicit OWNER and can do everything.
8. Receiving webhooks
Register a webhook subscription for Space booking lifecycle events — space_booking.created,
space_booking.consent_required, space_booking.consented, space_booking.paid,
space_booking.cancelled, 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 the same way as Merchant webhooks (x-tbbn-signature: t=<ts>,v1=<hmac>,
verifiable with @tbbn/sdk-js's verifyWebhookSignature()) and retried up to 3 times before
landing in DEAD_LETTER (replayable via POST /v1/webhooks/business-deliveries/:id/replay).
You'll receive a delivery both when you're the host of the Space being booked and when you're the
API-key holder who made a headless booking against someone else's Space.
What's not built yet
- Space API monetization — general usage of this API is currently free; if TBBN introduces
its own pricing for it (separate from Merchant SaaS billing), that will be documented in
docs/business/pricing.mdfirst. The one exception is the free-listing fee (section 9). - Free-listing fee collection — a free Space (
isFree: true) currently generates aPENDINGcharge record against your Business, but TBBN does not yet actually collect it or let you see it; that ships withadmin.tbbnetwork.com. - Real Business verification workflow /
admin.tbbnetwork.com— see sections 1 and 6. Verification review is a manual TBBN-staff action today, not a self-service or automated flow.