TBBN.MerchantDocs
API

Seller account linking

Linking connects a seller on your store to their TBBN account. Once linked, the items you send to TBBN for that seller show under their name with your store's logo, they can trade them, and their trades build one reputation across every store they sell through.

This guide is everything you need to build it: what to register, where to send the seller, what comes back, what your server sends to TBBN, and the webhook that confirms it.

Three ways a seller gets onto TBBN through your store

SituationUse
The seller already has a TBBN account, or is happy to make oneOAuth account linking (this guide, steps 1–5)
The seller has no TBBN account and you've verified their email and phonePOST /merchant/sellers/verify (step 6)
You trade for someone who won't have a TBBN accountA headless seller, POST /merchant/sellers/headless (step 6)

What you need

  • A Merchant account and a session for its Owner, an Admin or a Developer (OAuth clients), or an API key (the token exchange uses your client secret, not a key).
  • Your own stable id for each seller — your user or seller id. TBBN calls it merchant_seller_ref and gives it back to you, so you can match the link to your records.
  • A page on your site to send sellers back to (the redirect URI), served over https.

1. Register an OAuth client (once)

In the Merchant dashboard (merchants.tbbnetwork.com → Account linking), enter your redirect URIs and select Register client. Or with the API:

curl -X POST https://api.tbbnetwork.com/v1/oauth-clients \
  -H "Authorization: Bearer <session or API key>" \
  -H "Content-Type: application/json" \
  -d '{
    "merchantId": "<your merchant id>",
    "redirectUris": ["https://your-store.example/tbbn/callback"]
  }'

The response includes clientId (public, e.g. mc_ab12cd34ef56ab78) and clientSecret. The secret is shown only once; keep it on your server. POST /v1/oauth-clients/{id}/rotate-secret issues a new one; DELETE /v1/oauth-clients/{id} revokes the client (links it made stay).

2. Send the seller to TBBN

Make a fresh state and a PKCE pair for each attempt, store them against the seller's session, then redirect their browser to:

https://account.tbbnetwork.com/link/authorize
  ?client_id=mc_ab12cd34ef56ab78
  &redirect_uri=https%3A%2F%2Fyour-store.example%2Ftbbn%2Fcallback
  &scope=link:seller
  &state=Xh3k9Q...
  &merchant_seller_ref=store-user-77
  &code_challenge=E9Melhoa2OwvFrEMTJguCHaoeK1t8URWbuGJSstw-cM
  &code_challenge_method=S256
ParameterRequiredWhat to send
client_idYesYour client's clientId
redirect_uriYesOne of your registered redirect URIs, character for character, URL-encoded
scopeYeslink:seller
merchant_seller_refYesYour own id for this seller
stateRecommendedA random value you check when the seller comes back (protects against forged requests)
code_challengeRecommendedPKCE: base64url(SHA-256(code_verifier)), no padding. code_verifier is 43–128 random characters you keep
code_challenge_methodWith PKCES256

What the seller sees

  1. If they aren't signed in, the tbbnetwork.com sign-in page, where they can also create an account. They come straight back afterwards.
  2. A consent screen naming your store, with Approve and Deny.

If the redirect URI isn't one you registered, they see "This link looks malformed" and nothing is sent back.

3. Handle the redirect back

TBBN redirects the seller's browser to your redirect URI:

  • Approved: https://your-store.example/tbbn/callback?code=4f1c...&state=Xh3k9Q...
  • Denied: https://your-store.example/tbbn/callback?error=access_denied&state=Xh3k9Q...

Check state matches what you stored. Then, from your server, exchange the code.

4. Exchange the code (server to server)

The code works once and only for 5 minutes.

curl -X POST https://api.tbbnetwork.com/v1/link/oauth/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "authorization_code",
    "code": "4f1c...",
    "client_id": "mc_ab12cd34ef56ab78",
    "client_secret": "<your client secret>",
    "redirect_uri": "https://your-store.example/tbbn/callback",
    "code_verifier": "<the verifier you made in step 2>"
  }'

Response:

{ "sellerId": "7d0c…", "merchantSellerRef": "store-user-77", "linked": true }

Store sellerId against your seller. That's the link: nothing else (no access or refresh token) is issued. If this seller ref was already linked, you get the existing link back.

ErrorWhy
401 Invalid client / client credentialsWrong client_id or client_secret, or a revoked client
400 Invalid or expired authorization codeUsed already, or older than 5 minutes — start again
400 redirect_uri does not matchSend exactly the redirect URI used in step 2
400 Invalid PKCE code_verifierThe verifier doesn't match the challenge from step 2

5. The seller.linked webhook

Subscribe to seller.linked (see Webhooks) to be told about every new link — useful as a confirmation, or if your callback page failed after the seller approved:

{
  "type": "seller.linked",
  "sellerId": "7d0c…",
  "merchantId": "<your merchant id>",
  "merchantSellerRef": "store-user-77",
  "linkMethod": "OAUTH_AUTHORIZATION",
  "occurredAt": "2026-10-05T14:03:11.000Z"
}

linkMethod is OAUTH_AUTHORIZATION, INITIAL_VERIFICATION (step 6) or HEADLESS_CREATED.

6. Sellers without a TBBN account

  • Verified contact details: POST /merchant/sellers/verify with name, verifiedEmail, verifiedPhone, merchantSellerRef and merchantId. Send only details your store has verified. If no TBBN account uses that email or phone, TBBN creates the seller's profile and links it to your store (requiresConfirmation: false). If one already does, requiresConfirmation is true: knowing someone's email isn't consent, so send them through steps 2–4 instead.
  • Headless: if your plan allows it, POST /merchant/sellers/headless with merchantId, merchantSellerRef and an optional name creates a seller tracked only by you, with no TBBN account.

After linking

  • Send listings with the seller's sellerId (see the Trade Engine walkthrough). A listing's seller must be one of your own sellers.
  • The seller can unlink your store from their TBBN settings; you can unlink one with POST /v1/sellers/{id}/unlink. Either way, your listings for that seller come down, and unlinking is refused while a trade through your store is in progress.

Checklist

  • OAuth client registered; secret stored server-side only
  • Redirect URI registered exactly as you send it
  • Fresh state and PKCE verifier per attempt, checked on return
  • Code exchanged from your server within 5 minutes
  • sellerId stored against your seller; seller.linked webhook subscribed
  • error=access_denied handled (the seller chose not to link)