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
| Situation | Use |
|---|---|
| The seller already has a TBBN account, or is happy to make one | OAuth account linking (this guide, steps 1–5) |
| The seller has no TBBN account and you've verified their email and phone | POST /merchant/sellers/verify (step 6) |
| You trade for someone who won't have a TBBN account | A 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_refand 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
| Parameter | Required | What to send |
|---|---|---|
client_id | Yes | Your client's clientId |
redirect_uri | Yes | One of your registered redirect URIs, character for character, URL-encoded |
scope | Yes | link:seller |
merchant_seller_ref | Yes | Your own id for this seller |
state | Recommended | A random value you check when the seller comes back (protects against forged requests) |
code_challenge | Recommended | PKCE: base64url(SHA-256(code_verifier)), no padding. code_verifier is 43–128 random characters you keep |
code_challenge_method | With PKCE | S256 |
What the seller sees
- If they aren't signed in, the tbbnetwork.com sign-in page, where they can also create an account. They come straight back afterwards.
- 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.
| Error | Why |
|---|---|
401 Invalid client / client credentials | Wrong client_id or client_secret, or a revoked client |
400 Invalid or expired authorization code | Used already, or older than 5 minutes — start again |
400 redirect_uri does not match | Send exactly the redirect URI used in step 2 |
400 Invalid PKCE code_verifier | The 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/verifywithname,verifiedEmail,verifiedPhone,merchantSellerRefandmerchantId. 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,requiresConfirmationistrue: knowing someone's email isn't consent, so send them through steps 2–4 instead. - Headless: if your plan allows it,
POST /merchant/sellers/headlesswithmerchantId,merchantSellerRefand an optionalnamecreates 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
stateand PKCE verifier per attempt, checked on return - Code exchanged from your server within 5 minutes
-
sellerIdstored against your seller;seller.linkedwebhook subscribed -
error=access_deniedhandled (the seller chose not to link)