Catalog feed (scheduled sync)
If you already export a product feed, you can point TBBN at a feed file instead of writing API-calling code. It's the lower-effort alternative to direct listing sync. You can also use both: bulk catalog through the feed, and fast-moving items through the API. Once ingested, a listing looks the same to TBBN whichever path created it.
Your obligation is the listing's status, not its sales. If you list only for reach (not through the trade engine), you never report sales to TBBN. You do keep each item's status current. With a feed, that means the feed itself: mark sold-out items out of stock or drop them, and TBBN follows on its next pull.
Read this before you build around a feed. Three things to plan around:
- Map your field names. TBBN's feed uses its own column names (table below), and they aren't
identical to Google's or Meta's (
item_id, notid;original_price, notprice). Most feed tools can export a second feed with renamed columns. Your categories also need to map onto TBBN's taxonomy. - Sellers are optional. A row with no
external_seller_idis your store's own item, shown under your store's name (or goes todefaultSellerId, if you set one). - Multi-seller catalogs: name the seller on each row. One feed covers your whole catalog. Put
your own reference for each item's seller in
external_seller_id, the same attribute Google's marketplace feeds use — any stable value per customer; it needn't be your customer id. Until that customer links their TBBN account (with the same reference asmerchant_seller_ref), the row is listed under your store and the sync result says how many are waiting; when they link, those items become theirs. You can also put a linked customer's TBBN seller id inexternal_seller_id. See Seller account linking. - Delisting follows the pull, not the moment. Each pull takes a listing down (it becomes
UNAVAILABLE) when its row hasavailabilityset toout_of_stock(or "out of stock"), aquantityof 0, or anitem_idthat's no longer in the feed. Pulls happen every 24 hours, so an item that sells elsewhere can stay visible until the next pull. When that gap matters — one-of-a-kind items, stock that also sells in store — update the feed file and trigger a pull withPOST /v1/merchant/feed-source/fetch-now, or sync those items through the API instead, wherePOST /merchant/listings/{id}/availabilitytakes an item down the moment it sells.
How delisting behaves:
- It applies only to listings the feed manages. A listing you created through the API is never taken down by the feed.
- A listing reserved in a trade isn't taken down mid-trade.
- A listing the feed took down comes back once its item is in stock and in the feed again. One you marked unavailable yourself stays that way.
- If a pull fails or looks incomplete, TBBN leaves your listings as they are and reports it in the sync result. Check that the feed file is complete.
TBBN never replaces your own stock check: whatever a listing shows, re-check availability at your checkout.
Set up a feed source
POST /v1/merchant/feed-source
{
"feedUrl": "https://yourstore.example.com/feeds/tbbn.xml",
"feedFormat": "XML",
"feedUsername": "...",
"feedPassword": "..."
}
feedUrlmust be a public address (http or https) — TBBN fetches it, so an address on a private network is refused with400 FEED_URL_NOT_ALLOWED, and so is a redirect to one.feedFormatisXML(RSS 2.0-shaped) orCSV. A tab-separated file works asCSV.feedUsername/feedPasswordare sent as HTTP Basic Auth when TBBN fetches your URL. Never embed credentials in the URL itself.defaultSellerIdis optional. When set it must be one of your own sellers (403SELLER_NOT_LINKEDotherwise), and it's credited with every row that has noexternal_seller_id. Without it those rows are your store's own items.
TBBN pulls the feed every 24 hours. Trigger an immediate pull any time with:
POST /v1/merchant/feed-source/fetch-now
The response, and GET /v1/merchant/feed-source afterwards, shows the sync result: items synced,
rows skipped and why, listings taken down or put back. Monitor it. A live feed on a Business still
on the free Sandbox plan adds and changes nothing — the result says so — but still takes items
down; choose a plan to sync it (see Pricing).
Feed fields
| Field | Required | Notes |
|---|---|---|
item_id | Yes | Your unique key; identifies this listing across pulls. |
category | Yes | A TBBN category name (GET /v1/catalog/categories). Common other names are recognised; anything else is placed in Other — see Listing kinds. |
original_price | Yes | Amount and ISO 4217 currency code, e.g. 19.99 USD. Must be your store's country's currency. |
listing_type | Yes | SALE / TRADE / BOTH. A SALE listing is discovery-only and never receives offers — visitors follow product_link to buy on your site. |
title | No | Shown on the listing. Without it the listing shows item_id, so send it. |
sub_category, brand, condition | No | Improve search and matching. sub_category is one of the category's subcategories. |
image_link, additional_image_link | No | One primary image and optional extra images, as https links. A listing shows the first five; TBBN copies each into its own storage within minutes and drops any that can't be fetched or aren't images. |
product_link | No | The item's page on your site. Send it for every SALE listing — it's the only way a visitor can buy. |
availability, quantity | No | out_of_stock, or a quantity of 0, takes the listing down until the item is back in stock. |
external_seller_id | No | Your reference for this item's seller, or their TBBN seller id (see "Multi-seller catalogs" above). Without it, defaultSellerId, else your store. |
location_id | No | The store number you gave the location this stock is at. |
<want> (XML feeds only) | No | What the seller would take in trade: repeated <want> elements with category, sub_category, brand. |
A row missing a required field is skipped. Every other row goes through the same validation as a direct API call, including the prohibited-items screen; a matching row is held for review rather than published.
Vehicles, homes, services and tickets
Add a kind column (GOODS, VEHICLE, PROPERTY, SERVICE or TICKET) and one
detail_<field> column per detail, the field name written in snake case: detail_vehicle_type,
detail_make, detail_model, detail_year, detail_mileage; detail_offering,
detail_property_type, detail_bedrooms. In an XML feed they're elements of the same names. The
fields and their allowed values are in Listing kinds; option values
aren't case-sensitive, and a yes/no field takes true, yes or 1.
item_id,title,category,original_price,listing_type,kind,detail_vehicle_type,detail_make,detail_model,detail_year,detail_mileage,detail_mileage_unit
car-1042,2019 Toyota Corolla LE,Vehicles,14500.00 USD,BOTH,VEHICLE,Car,Toyota,Corolla,2019,48000,mi
A row with no kind keeps the kind its listing already has (GOODS for a new one). A row whose
details are missing a required field, or carry a value that isn't allowed, isn't published and
counts as failed in the sync result, like any other invalid row.
