TBBN.MerchantDocs
API

Trade Engine integration walkthrough

This is the story to read once, end to end, before touching the API reference. It's the mental model; endpoint-level detail lives there.

1. Create a Business, then get approved

Every Merchant links to a Business profile first: register an account and create a Business at business.tbbnetwork.com, then pass its id as businessId when you apply for a Merchant account. Your business rep gets a temporary account link by email. It lasts 7 days and lets you upload documents, track review status, and resubmit if something's missing. Once approved, that temporary account becomes your permanent Merchant Dashboard login — same email, same one-time-code login, now persistent. ("Merchant Dashboard" here is the app for a specific integration; the Business profile itself — which can run more than one Merchant — is managed separately.) Invite developers and account managers from the dashboard; they get scoped roles (DEVELOPER for API/integration work, ACCOUNT_MANAGER for seller/billing management) — see Team roles.

2. Get your keys

From the dashboard, generate a sandbox API key first — free, unlimited (rate-limited) usage, no production data. Get one instantly with no application at all if you just want to explore the API before applying. Build your integration against sandbox, then generate a production key (sk_live_...) once you're approved — that's what starts counting against your plan's included usage. See Pricing.

3. Link your sellers — or trade for them directly

TBBN accounts are created by the person themself, on tbbnetwork.com — a merchant can't create one on a seller's behalf. You have two options for a seller who trades through your store:

Option A — link their existing TBBN account. Have them approve a link via the OAuth account-linking handshake: redirect their browser to account.tbbnetwork.com/link/authorize?client_id=...&redirect_uri=...&scope=link:seller&merchant_seller_ref=... (register an OAuth client first via POST /v1/oauth-clients), and once they approve, your backend exchanges the resulting code for a link via POST /v1/link/oauth/token — server-to-server, never a password. POST /merchant/sellers/verify still exists for reporting a match by email/phone ({name, verified_email, verified_phone, merchant_seller_ref}), but a cross-merchant match only ever returns requires_confirmation: true — completing that link requires the OAuth handshake above.

Option B — no account needed. If your plan tier allows it (Growth/Enterprise), call POST /merchant/sellers/headless with {merchantId, merchantSellerRef, name} to create a "headless" Seller — a trade participant tracked entirely by you, with no linked TBBN account at all. This can't accumulate a cross-merchant reputation history the way a linked account can, since there's no single identity behind it across merchants.

4. Sync your listings

POST/PUT/DELETE /merchant/listings — you own listing content, TBBN just mirrors it. Set visibility per your plan tier: PRIVATE (internal only), GLOBAL (TBBN Marketplace + other global merchants), BOTH, or ENTERPRISE (only your hand-picked enterprise trading merchants — Enterprise tier only). Set listingType (SALE/TRADE/BOTH) — a SALE listing is discovery only, never offer-able; TBBN redirects visitors to merchantItemUrl (set it, or visitors see a plain "not available for TBBN checkout" message) instead of orchestrating a trade for it. Include wants if you want your sellers' listings to show up in match recommendations, not just search.

If you'd rather not write API-calling code — e.g. you already export a Google Merchant Center or Meta Commerce Manager-style feed for your own catalog — see the catalog feed guide for the scheduled feed-pull alternative: point your existing feed URL at POST /v1/merchant/feed-source and TBBN pulls it on a 24-hour cycle (plus an on-demand POST /v1/merchant/feed-source/fetch-now).

5. Handle offers and trade sessions

Offers and trade sessions happen on TBBN's side (or your embedded widget, or TBBN Marketplace) — you don't build negotiation UI unless you want full API control instead of the widget. You'll receive webhooks (offer.created, offer.accepted, trade.accepted) as things progress. See Webhooks & events.

6. Handle checkout — this is the part you must build

When a trade session reaches RESERVED, you'll receive a checkout.started webhook for your side whenever one of your sellers owes money to the other side's item. Read that again: you receive checkout redirects for trades where your seller owes money, and your checkout endpoint must accept {tradeSessionId, originalPrice, tradeAmount, currency} and compute your own taxes, commissions, and fees on top, exactly as you would for any other sale. After payment, call back with payment.completed or payment.failed. Do not wait for the other side to pay first — both sides' checkouts are live simultaneously the moment the session is RESERVED.

Traders see and explicitly agree to the applicable hold terms (below) before this step — nothing about that consent step needs building on your end, it happens on TBBN's own checkout page.

7. Fulfill

Your side's fulfillment starts the moment your own checkout reports payment.completed — same independence as checkout above. There's no joint "both sides paid" gate: report your own fulfillment status with side: 'A' | 'B' as soon as you're ready, independent of the counterparty. Fulfillment, shipping, tracking, returns — all yours, same as any other order. The trade session auto-completes once both sides have separately reported fulfillment.completed — that's a bookkeeping milestone, not something either merchant needs to coordinate.

8. Equal-value trades — no cash difference

An even swap runs through exactly the same checkout flow as any other trade. TradeSessionPayment still gets created for both sides — when the two sides' values are equal, both rows carry amount: 0 instead of one side owing the other. Your checkout endpoint still receives the callback, still has nothing to collect from the buyer on TBBN's behalf, and still reports back payment.completed the same way — you're confirming the exchange, not processing a $0 charge. Two things don't disappear at $0: the $1.50 per-side checkout-orchestration fee still applies (a $0 swap between two of your own sellers still costs $1.50–$3 total — see Pricing), and tax on the item's value, your own service fee, and any other charge you set are still yours to collect, same as section 6.

9. Two sellers under the same merchant trading with each other

Available on Growth and Enterprise plans, checked when an offer is accepted. Billing already handles this correctly — the checkout-orchestration fee bills at the normal $3.00 total, not the 4× cross-merchant rate, whenever the same merchant appears on both sides.

10. Locking your own inventory (Trade Engine listings only)

TBBN's own reservation only locks the item inside TBBN — it does nothing to your storefront or POS on its own. For any TRADE-type listing (the real barter engine, as opposed to SALE-type listings, which are discovery-only and were never reserved through TBBN), subscribe your webhook endpoint to reservation.created, reservation.expired, and reservation.failed, and treat them as a load-bearing part of your integration: place a real-time hold on your own inventory the moment reservation.created arrives, and release it on reservation.expired/reservation.failed. Your hold should follow TBBN's own holding rules — see Trade session states for the full policy and the effective-hold-window figure this checkout page shows the trader.

11. If the other side never pays

Once you've reported payment.completed for your own side, your own fulfillment proceeds independently (section 7) — it does not wait on, and is not undone by, what the other side does. If the other side never completes their own checkout:

  • The unpaid side's own seller can release their own reservation via POST /v1/trade-sessions/:id/close-unreciprocated — but only once the applicable minimum hold has elapsed, and only the seller on the unpaid side may call it. This frees their item back up; it does not touch or reverse the paid side's already-independent fulfillment.
  • A rep of the paid side's Merchant can also excuse that side from fulfilling entirely, once the hold has elapsed, via POST /v1/trade-sessions/:id/excuse-fulfillment — letting the seller who already paid keep their own item rather than being committed to ship into a trade the other side never completed.
  • There is no TBBN-mediated refund for a side that already paid and shipped before the counterparty failed to reciprocate — TBBN holds no escrow on a Merchant-checkout trade. Recourse, if any, runs through your own return/refund policy, exactly as it would for any other order.

See Trade session states for the exact state machine and Webhooks & events for every payload shape.