TBBNMerchantDocs
API

Connect your software to TBBN

If you make a POS, inventory or booking system, Businesses can connect it to their TBBN account. They choose what it can do, and can limit it to some of their locations. It can never reach their money, payouts or team.

1. Register your app

Sign in at account.tbbnetwork.com/apps and register your app with its privacy policy address, its https redirect addresses and what it needs to do. Copy the client secret: it's shown once. Until TBBN has reviewed the app, only Businesses you own can connect it.

2. Send the connection request from your server

curl -X POST https://api.tbbnetwork.com/v1/platform-oauth/par \
  -H "Content-Type: application/json" \
  -d '{ "client_id": "...", "client_secret": "...", "redirect_uri": "https://your.app/back", "scope": "locations:read bookings:write", "state": "...", "code_challenge": "...", "code_challenge_method": "S256" }'

Then send the person to https://account.tbbnetwork.com/oauth/authorize?client_id=...&request_uri=.... An owner or Admin picks the Business and any location limit, and confirms with an emailed code. They come back to your redirect_uri with code and your state, or error=access_denied.

3. Get tokens

curl -X POST https://api.tbbnetwork.com/v1/platform-oauth/token \
  -H "Content-Type: application/json" \
  -d '{ "grant_type": "authorization_code", "client_id": "...", "client_secret": "...", "code": "...", "redirect_uri": "https://your.app/back", "code_verifier": "..." }'

The access token lasts an hour. To refresh, send grant_type: refresh_token and refresh_token. A refresh token works once and comes back as a new one, so save it each time. Sending an old one again ends every token from that connection, and the Business has to connect again. POST /v1/platform-oauth/revoke ends a connection.

4. Call the API

Send Authorization: Bearer <access_token>.

ScopeWhat it reaches
locations:readGET /v1/locations
bookings:readReading Space bookings, search and availability
bookings:writeMaking, cancelling and moving Space bookings
checkins:writeFront-desk check-in and no-show
handovers:verifyFront-desk drop-off and pickup
listings:writeStore listings
inventory:writeListing availability, POST /v1/trade_ins
trade_credits:write/v1/trade_credits
analytics:readGET /v1/businesses/{id}/report

Anything else answers 403 SCOPE_NOT_GRANTED.

Webhooks. With webhooks:manage, POST /v1/webhooks/app-subscriptions with url and events adds a webhook and returns its signing secret once. GET lists yours and DELETE /v1/webhooks/app-subscriptions/{id} removes one. Your other scopes decide which events you can have: bookings:read for space_booking.* and booking.*, handovers:verify for handover.*, locations:read for location.* and device.*, trade_credits:write for trade_credit.*, inventory:write for tradein.* and listings:write for listing.*. Anything else answers 400 EVENTS_NOT_GRANTED. If the Business limited you to some locations, you only get events from those. Disconnecting stops them.

Locations. Name one with a Tbbn-Location header. The front-desk routes need it, and you can say who's working with Tbbn-Staff-Ref. A location the Business didn't allow answers 403 LOCATION_NOT_GRANTED.

Store routes act for one of the Business's Merchants. If it has more than one, name it with a Tbbn-Merchant header.

Bookings your app makes are charged to the guest, like any other paid booking.

5. When a Business disconnects

Your token stops working at once (401 APP_DISCONNECTED). If you gave a webhook address, it gets app.deauthorized with grantId and businessId, in a TBBN-Signature header of t=<timestamp>,v1=<HMAC-SHA256 of "timestamp.body"> using your webhook secret.