πŸ“¦ FTSeller Wholesale Market Log in Β· Register

The marketplace

XGM_KERNEL=amazon runs the desk's market as one continuous online marketplace with a fulfilment network, seen from the seat of a third-party wholesale seller: you buy products from suppliers, ship them into the fulfilment network, set your own prices (or let the default repricer do it), and the network sells, ships and returns them hour by hour, charging the marketplace's published fee card. The money is held in a seller balance and released to your cash by settlement statements. Everything else on the site (carts, checkout, payments, agents, the record, the console, owned goods and the exchange) works as it does on the platform's other markets.

One market and the marketplace clock

There is one market, the US Marketplace (id us). It runs on a marketplace clock: one tick is one marketplace hour, and the clock runs XGM_TIME_SCALE times faster than real time β€” by default 24, so one real hour is one marketplace day, a marketplace week passes in 7 real hours and a tick closes every 2 minutes 30 seconds of real time (interval "2m30s"). At time scale 1 the marketplace runs in real time. Every date the marketplace shows is a marketplace date: tick t opens at the marketplace's epoch (2026-01-01 00:00, a Thursday) + t hours, and the market's seasons (the peak surcharge, fourth-quarter storage, slow receiving) follow the weeks of that marketplace year. A marketplace day runs from midnight to midnight: ticks 24d to 24d + 23 are day d.

GET /api/v1/markets/us says where the clock is: current_tick, tick_sim_at (the marketplace date and time the open hour began), sim_now, time_model: "continuous", ticks_per_day: 24, time_scale, and when the open hour closes in real time (tick_closes_at, seconds_to_close). The menu, history and tape rows, orders and the record carry sim_at next to their tick. Things a person must act on stay in real time: an order's payment deadline (closes_at), the notice of a fee amendment, the monthly participation fee, payouts and refunds of real money, and the terms.

What happens every marketplace hour (at the close of each tick):

  1. new supplier offers appear (each stays open for days, below) and the desk decides on each once, when it appears;
  2. every order paid in this hour or before fills as a lot; unpaid orders whose payment window or offer ended expire;
  3. for every account's stock: lots due arrive (and become sellable), removals requested this hour are carried out, the price in effect meets the hour's buy box and the stock sells its share of the hour's sales, first in first out; customer refunds and returned units due this hour are worked. The money of these events accrues on the lot (accrued_today, by kind) until the day closes.

What happens at the end of every marketplace day (the close of its last hour, 23:00–24:00):

  1. each lot's money of the day is posted to the seller balance β€” one ledger entry per lot and kind (sale_credit, referral_fee, fulfilment_fee, …, note day N) β€” together with the day's storage, aged-inventory and utilization charges of its on-hand units;
  2. the record gets its daily entries (units sold and the buy box of the day), and lots with nothing left and no return still on its way settle;
  3. every 14th day, settlement statements release the seller balance (below).

Until a day closes, what a lot earned that day shows as accrued_today on GET /api/v1/positions and on the stock view; its cash_flows, pnl_so_far and the seller balance count posted money only.

The listings and what an offer shows

The market itself is the wholesale market's: about a thousand listings in twelve categories, built on real FMCG products of a real wholesale seller's assortment (real titles, brands, product types, reference prices, size tiers and case packs; every ASIN, MSKU, FNSKU and UPC lightly altered, so none is a real identifier; no real sales, sellers or costs). Products ramp up, sell and phase out over years; a listing's next product takes over under a new SKU. Each listing carries its category's typical crowd of competing sellers with their repricers, a sticky buy box price that sinks when the crowd grows and recovers when it thins, and a sales rank among every product of the marketplace category. Demand follows the hour of the day and the day of the week (quiet nights, an evening peak) and the buy box: the buy box and the crowd change at some hour of the first marketplace day of each week (the epoch's weekday, Thursday), and from that hour the listing's demand moves with the new price. The categories' demand seasons follow the marketplace calendar like the fee seasons. The rank is published an hour late (rank_as_of); sales_rank_avg and rank_drops cover the last 30 days, rank_drops_long the last 90. Sales velocities are never published, in any form.

A deal is a supplier's offer of a product (a single item, a multipack or a bundle). Offers appear at every hour and stay open for days β€” from one day to three weeks, never beyond the product's time on the listing; the menu (GET /api/v1/markets/us/deals) shows every offer open now, each viewed at the current hour. The offer's terms (unit_cost, max_qty) are fixed when it appears; its facts (the buy box, signals, fees, lead time, net margin) are those of the current hour. Besides the wholesale facts (unit_cost, list_price = the hour's buy box price, sales_rank, rank_as_of, sales_rank_avg, rank_drops, rank_drops_long, nsellers, sku, asin, msku, fnsku, upc, family, listing_type, category, category_code, brand, pack, case_pack, max_qty) it shows:

field meaning
key, tick the offer's key (us-<hour it appeared>-<n>) and the hour it appeared
valid_until, hours_left, sim_valid_until the first hour it is no longer open (a tick), the marketplace hours left, and that time as a marketplace date
size_tier small_standard, large_standard, small_bulky or large_bulky (from the product's weight and dimensions)
unit_weight_lb, dimensions_in, cubic_feet, shipping_weight_lb the product's physicals (below)
units_per_carton units in one inbound carton
prep {label, kit, per_unit}: whether the unit needs a label (and kitting, for multipacks and bundles) and the seller-side prep charge per unit (below)
referral_rate, referral_fee, referral_min the referral fee at the buy box price (the rate is the fee / price, the minimum included)
fulfilment_fee, fulfilment_base, peak_surcharge, fuel_surcharge the fulfilment fee per unit sold at the buy box price this hour, and its parts
fba_fee the same fulfilment fee (the key the wholesale pages read)
fees_at_price referral + fulfilment per unit sold at the buy box price
storage_per_day, storage_per_month the storage of one unit on hand for a marketplace day (and a month), at this week's rate
peak_season, fee_schedule whether the peak surcharge applies this week; the fee schedule version in force
inbound_route, inbound_per_unit the default route and its inbound cost per unit for the offer's max_qty
inbound_routes[] every route: {route, label, available, per_unit, lead_typical, lead_max, reason?}, lead times in days
lead_time {typical, min, max, distribution, unit: "days"}: the product's lead time in days by the default route for an order filled now
return_threshold the category's returns-processing threshold (below)
net_margin list_price βˆ’ fees_at_price βˆ’ unit_cost βˆ’ inbound_per_unit: before storage, returns and anything unsold

GET /api/v1/markets/us β†’ rules publishes the whole rule book: the fee schedule in force (rules.fees.schedule, its schedule_version and digest), storage per cu ft and month and day, the categories with their referral tiers and return thresholds, the calendar of the marketplace year, the inbound routes and lead times in days, the stock, pricing and payout rules in days and hours, the capacity rule and the pending fee amendments.

Buying: the payment window and the fill

You order an open offer (POST /api/v1/orders or a cart line) with a quantity, an inbound route and, if you like, a starting pricing rule. An account may order at most the offer's max_qty across all its orders of that offer. The order is a reservation: it must be paid within one real hour of placing it and while its offer is still open, whichever comes first β€” closes_at is the real time that window ends and expires_tick the first marketplace hour starting at or after it. Once paid (the hour it was paid in is its paid_tick), it fills at the close of that marketplace hour as a lot, at the offer's unit cost plus the route's inbound fee. An unpaid order expires at the close of the hour before expires_tick. The fulfilment-network capacity (below) is checked when you order and again when you pay, before any money moves (a card is charged, or a hosted payment opened, only once it fits); a payment confirmed by the provider is never refused for capacity.

The fee card

The fees below are the defaults (2026 approximations of a large marketplace's US fee card, in the desk's currency). The schedule in force is always the one in rules.fees.schedule; it changes only by announced amendments (below). Per-event fees are rounded to the cent per unit; storage, aged-inventory and utilization charges accrue hour by hour on the units on hand and are posted once a day in whole cents (the fraction of a cent is carried to the next day, so a month of daily charges adds up to the month's charge).

Referral fee β€” per unit sold

A share of the whole sale price at the rate of the tier the price falls in (so a price just over a tier's limit pays the higher rate on all of it), never less than the minimum per unit:

category rate minimum
Grocery & Gourmet Food (GRO) 8 % up to 15.00, 15 % above none
Beauty & Personal Care (BPC), Health & Household (HHS), Baby Products (BAB) 8 % up to 10.00, 15 % above 0.30
Automotive (AUT) 12 % 0.30
every other category (TLS, ACS, OFF, PET, HOM, GAR, SPO) 15 % 0.30

For example, grocery at 15.00 pays 1.20 and at 15.01 pays 2.25; beauty at 3.00 pays the 0.30 minimum.

Fulfilment fee β€” per unit sold

By size tier, shipping weight and the sale price's band (under 10.00 / 10.00–50.00 / over 50.00). The shipping weight is the unit weight for small standard; for the other tiers the greater of the unit weight and the dimensional weight (length Γ— width Γ— height / 139, bulky sides counted at least 2 in).

small standard, up to < 10 10–50 > 50
2 oz (0.125 lb) 2.43 3.32 3.58
4 oz 2.50 3.39 3.65
6 oz 2.56 3.45 3.71
8 oz 2.67 3.57 3.83
10 oz 2.77 3.68 3.94
12 oz 2.83 3.77 4.03
14 oz 2.89 3.87 4.13
1 lb 2.95 3.96 4.22
large standard, up to < 10 10–50 > 50
0.25 lb 2.91 3.73 3.99
0.5 lb 3.20 4.02 4.28
0.75 lb 3.49 4.31 4.57
1 lb 3.78 4.60 4.86
1.25 lb 4.10 4.92 5.18
1.5 lb 4.43 5.25 5.51
1.75 lb 4.75 5.57 5.83
2 lb 4.97 5.79 6.05
2.25 lb 5.19 6.01 6.27
2.5 lb 5.41 6.23 6.49
2.75 lb 5.63 6.45 6.71
3 lb 5.85 6.67 6.93
20 lb 6.15 + 0.08 per started 0.25 lb above 3 lb 6.97 + 0.08 … 7.23 + 0.08 …
bulky, up to 50 lb < 10 10–50 > 50
small bulky 6.73 + 0.38 per started lb above 1 lb 7.55 + 0.38 … 7.81 + 0.38 …
large bulky 8.53 + 0.38 per started lb above 1 lb 9.35 + 0.38 … 9.61 + 0.38 …

Peak surcharge from mid-October to mid-January (weeks 41 to 1 of the marketplace year inclusive, counted 0–51 as rules.calendar.week_of_year from the marketplace date: week 0 is 1–7 January, week 51 runs from 24 to 31 December): small standard +0.19 up to 0.25 lb, +0.23 up to 1 lb; large standard +0.26 up to 1 lb, +0.33 up to 3 lb, +0.48 up to 20 lb; small bulky +0.80; large bulky +1.30. A fuel and logistics surcharge of 3.5 % applies to the base fee and the peak surcharge. Example: a small-standard unit of 0.1 lb sold at 8.00 pays 2.52 (2.71 in peak season), at 12.00 pays 3.44.

Storage β€” per cubic foot of units on hand

January–September October–December (weeks 39 to 51)
standard tiers 0.78 per cu ft and month 2.40
bulky tiers 0.56 1.40

Storage is charged per marketplace day on the units on hand hour by hour (from the hour a lot arrives to the hour its units leave): cu ft Γ— the month's rate Γ— 12 / 365 a day. A 0.1 cu ft standard unit pays 0.0026 a day off-season and 0.0079 in the fourth quarter. The rate follows the week of the marketplace year (rules.calendar); rules.fees.storage_per_cuft_day publishes the day's rate.

Aged-inventory surcharge, on top of storage, by the age of the units since they arrived (per cu ft and month; from a year on at least a minimum per unit and month):

age (days) 181–210 211–240 241–270 271–300 301–330 331–365 366–455 456 +
per cu ft / month 0.50 1.00 1.50 5.45 5.70 5.90 6.90 (min 0.30 / unit) 7.90 (min 0.35 / unit)

The age is the lot's whole marketplace days in stock at the end of the day.

Storage utilization surcharge, on top of storage, when the account's stock is slow for its sales: the weeks of supply = the average cu ft on hand over the last 90 days / the average cu ft shipped per week over them. Above 22 weeks every unit on hand pays per cu ft and month:

weeks of supply above 22 28 36 44 52
standard tiers 0.44 0.76 1.16 1.58 1.88
bulky tiers 0.23 0.46 0.63 0.76 1.30

Exempt: accounts storing under 25 cu ft on average, and accounts within 52 weeks (364 days) of their first lot on the market.

The monthly invoice view. Storage, aged-inventory and utilization charges are posted daily; the stock view (GET /api/v1/stock β†’ invoices, and the console) groups them by marketplace month: {account_id, market, month ("YYYY-MM"), days, from_tick, to_tick, by_kind, total}.

Low-inventory-level fee β€” per unit shipped

When a SKU's days of supply run short β€” days of supply = the unit-days on hand / the units shipped, over the last 30 days and over the last 90 (today's hours included), taking the greater of the two β€” every unit shipped pays:

days of supply under 14 21 28
small standard (up to 1 lb) 0.89 0.63 0.32
large standard up to 3 lb 0.97 0.70 0.36
large standard up to 20 lb 1.11 0.87 0.47
small bulky 1.85 1.02 0.51
large bulky 2.09 1.15 0.57

Exempt while the SKU shipped fewer than 20 units over the last 7 days, for a new product β€” within 26 weeks (182 days) of the first arrival of the SKU on the account, however often it sold out since β€” and for a new seller: within 52 weeks (364 days) of the account's first lot on the market. Keeping stock in the pipeline avoids it; keeping too much brings the storage and utilization charges.

Removal and disposal β€” per unit

shipping weight up to 0.5 lb 1 lb 2 lb above 2 lb
standard tiers 0.84 1.53 2.27 2.89 + 1.06 per started lb above 2 lb
shipping weight up to 1 lb 2 lb 4 lb 10 lb above 10 lb
bulky tiers 3.12 4.43 6.82 10.12 13.84 + 1.06 per started lb above 10 lb

Disposal costs the same as removal by default (its own table in the schedule).

Returns β€” refund administration and returns processing

When a customer returns a unit, the sale price is refunded (refund), the referral fee is refunded (referral_refund) less the refund administration fee β€” 20 % of that referral fee, at most 5.00 per unit (refund_admin_fee) β€” and the fulfilment fee is not refunded.

Returns processing fee, per returned unit: charged only on a SKU whose return rate over the last 28 days (returned / shipped) is above its category's threshold, with at least 25 units shipped in that window, and only for the returns above the threshold.

category GRO OFF BPC HHS GAR HOM TLS SPO AUT BAB PET other
threshold 2.9 % 4.4 % 5.5 % 5.5 % 7.7 % 8.1 % 8.7 % 8.7 % 9.1 % 9.3 % 10.2 % 4.8 %

The fee: small standard 1.78 / 1.89 / 2.05 / 2.21 up to 0.25 / 0.5 / 0.75 / 1 lb; large standard 2.36 / 2.62 / 2.89 / 3.15 / 3.62 up to 0.5 / 1 / 1.5 / 2 / 3 lb, then 3.91 + 0.07 per started lb above 3 lb; bulky tiers the fulfilment fee's base at the unit's price band.

Inbound β€” charged with the order

The order debit is the units at unit_cost plus the inbound fee per unit of the route you choose (the order's fee_amount):

  • carrier: parcel and express charge per billable lb (the greater of the weight and the dimensional weight at 1,728 / 139 lb per cu ft) plus per carton (every carton shipped, a partial last one too: cartons = units Γ· units per carton, rounded up), with a minimum per unit; LTL charges per pallet (pallets = units Γ— cu ft Γ— 1.15 / 60, at least one);
  • placement: free ("optimized") from 5 identical full cartons, otherwise the minimal-split fee per unit (small standard 0.21 / 0.25 / 0.30 up to 0.375 / 0.75 / 1 lb; large standard 0.30 / 0.38 / 0.47 / 0.60 / 0.85 / 1.20 up to 0.75 / 1.5 / 3 / 5 / 12 / 20 lb; bulky 1.60 / 2.60 / 3.90 / 5.10 / 6.50 up to 5 / 12 / 28 / 42 / 50 lb);
  • seller-side prep for units that need a label: 0.30 small standard, 0.40 large standard, 0.60 small bulky, 0.75 large bulky, plus 0.35 for kitting (multipacks and bundles). The marketplace offers no prep or labelling service under the 2026 rules: this is what a prep service charges you to label and kit the units before they ship, collected with the order so the order shows its whole landed cost (it is not a marketplace fee; its days are part of the lead time).

Shipments may arrive with a defect (labels, packaging, carton contents): the route's defect risk is 1 % for parcel, 5 % for express and 3 % for LTL, and a defective shipment pays an inbound_defect_fee per unit when it arrives (small standard 0.32; large standard 0.42 / 0.62 / 1.74 up to 1 / 3 / 20 lb; bulky 2.50). Now and then a lot loses part of its units in the network; they never become sellable. Units lost on a partnered route (parcel, ltl) are reimbursed when the lot arrives, at their landed cost (unit cost + inbound per unit), as a reimbursement credit to the lot; on your own carrier (express) the loss is yours.

Product physicals

Every product has a weight, dimensions, a size tier and a carton, synthesized deterministically (no real measurements): from the title's net content where it states one (ounces, fluid ounces, pounds, grams, millilitres, "Pack of N", …), packed densely like the packaged goods it is, and otherwise from the size tier's typical weights and densities. One product has one size everywhere; a multipack weighs its units plus packaging, a bundle its parts. The tiers:

tier weight longest Γ— median Γ— shortest side
small standard ≀ 1 lb ≀ 15 Γ— 12 Γ— 0.75 in
large standard ≀ 20 lb ≀ 18 Γ— 14 Γ— 8 in
small bulky ≀ 50 lb ≀ 37 Γ— 28 Γ— 20 in, length + girth ≀ 130 in
large bulky ≀ 50 lb ≀ 59 Γ— 33 Γ— 33 in, length + girth ≀ 130 in

Units per carton: the supplier's case pack where there is one (multipacks: the case pack Γ· the pack), otherwise as many units as fit 1.5 cu ft and 50 lb; one per carton for bulky units. Units need a marketplace label unless the product ships under its manufacturer's barcode (its FNSKU is its ASIN); multipacks and bundles need a label and kitting.

Inbound routes and lead times

route cost eligible defect risk
parcel partnered parcel (default) 0.40 per billable lb + 1.00 per carton, at least 0.15 per unit always 1 %
express express, own carrier 1.10 per billable lb + 2.50 per carton, at least 0.40 per unit always 5 %
ltl partnered LTL pallets 225.00 per pallet from 5 identical full cartons 3 %

A lot's lead time, in days from the hour its order fills, is the supplier's processing (7 days) + dispatch (0–3 days) + prep (0–2 days, for labelled or kitted units) + transit + receiving at the fulfilment centre + now and then a delay (6–14 extra days on 15 % of lots, 12–20 on 4 %), the trip capped at 28 days (35 for LTL; 49 / 56 in peak season). The lot arrives β€” and starts selling β€” at the hour fill hour + 24 Γ— the lead days. By the default route, for a labelled unit off peak, lead times run 9–35 days, typically 12:

lead time (days) ≀ 14 ≀ 21 ≀ 28
share of lots (parcel, labelled, off peak) 62 % 86 % 97 %

Express is faster (71 % within 14 days), LTL slower (11–42 days, typically 15). From mid-October to the end of the year the fulfilment centres receive slowly: lead times run 15–56 days (typically 23; LTL up to 63). An offer's lead_time and inbound_routes[] give the distribution for that product for an order filled now; GET /api/v1/markets/us/deals/{key}/inbound?qty= quotes every route for a quantity (below). The drawn lead time is revealed when the lot arrives; until then you know its window (arrives_window in ticks, arrives_window_days).

Example (a large-standard unit of 1.2 lb and 0.08 cu ft, 6 per carton, labelled): 30 units by parcel 1.05 per unit (optimized placement); 24 units by parcel 1.43 (4 cartons: minimal split); 30 by express 2.14; 30 by LTL 7.90 (one pallet for 30 units); LTL is not available for 24.

Your stock and your price

A paid order fills at the close of its paid hour as a lot on the account's trading account. The lots of one SKU form the account's stock of it: once a lot arrives it sells, first in, first out (the oldest lot first), at your price, hour by hour, for as long as it takes β€” there is no horizon. A lot is

  • inbound while in transit: it sells nothing and pays no storage;
  • on hand from its arrival hour: it sells, pays storage and ages;
  • awaiting returns when it has no unit left but customer returns of its sales are still on their way;
  • settled at the end of the first day on which nothing is left and every return has come back: its realized_pnl = its cash flows βˆ’ its cost basis, exactly as its trade on record shows.

Pricing rules

You set a pricing rule per market and MSKU, at any time; it takes effect from the next marketplace hour (effective_from_tick: the hour already running keeps the price it opened with, and past hours never change). The kinds:

kind price parameters
default (or no rule) the default repricer: the buy box price, never under your break-even, never over 2 Γ— the newest lot's list price none
featured_offer follows the buy box: buy box Γ— (1 + offset_pct) + offset offset, offset_pct (βˆ’0.9 … 1.0), min_price (required), max_price
fixed your price price, min_price (required), max_price
beat_lowest an alias of featured_offer that many under the buy box: {"kind": "beat_lowest", "offset_pct": 0.03} = 3 % under as featured_offer, non-negative

Every price is clamped to [min_price, max_price] and rounded to the cent. The break-even of the default repricer is the lowest price from which every higher price covers the unit-weighted landed cost of your units on hand (unit cost + inbound) after the referral and fulfilment fees (it accounts for the referral tiers' cliffs and the price bands); a product that no price covers is not offered. An order or a cart line can carry the starting rule (pricing): it applies to the SKU from the hour after the fill if the SKU has no rule yet.

The guardrail. An offer priced above 1.5 Γ— the median buy box of the product's last 13 weeks (91 days) is deactivated as a potential pricing error for that hour: it sells nothing (its price is still reported to you). An offer is also inactive without stock on hand, without a buy box price (rules that follow it), or once the product has left the listing.

Your share of the buy box. The listing's sales go round its sellers; every account is one more seller against the listing's crowd of competing sellers (accounts never compete with each other). At the buy box price your weight is one seller's β€” on average 1 / (nsellers + 1) of the listing's sales, with some luck from week to week; under it you win more of them (up to a cap), a little above it you keep a reduced share, further above a small and quickly vanishing one. The rivals' repricers follow an undercut: for a few weeks after an hour you sold under the buy box, they match any price you set under it, so it wins no more than the buy box itself β€” a permanent undercut only lowers your price; an occasional one wins some extra share. The size of the effect is not published: the record and your own sales show it.

Prices are private. Your own price, rule and rule history are yours: the public record of your trades shows the units sold and the buy box, never your price.

Customer returns

A share of the units sold comes back (the share depends on the product and its category; it is not published):

  1. the refund 3–21 days after the sale (refund = βˆ’units Γ— the sale price, referral_refund, refund_admin_fee, and the returns processing fee where the SKU is above its threshold);
  2. the unit 5–14 days after the refund: sellable units go back into the stock of the lot they came from (and sell again from the next hour); unsellable ones are disposed of at the disposal fee.

Both fall on the sale's hour of the day; their money accrues and is posted at that day's close like every other.

Seller balance and disbursements

Every money flow of your lots β€” sale credits, fees, refunds, storage β€” is posted at the day close to the account's seller balance of the market, not to its cash. The seller balance is held and reaches your cash (what orders and payouts spend) only by settlement statements:

  • Scheduled: every 14 marketplace days (rules.stock.settlement_period_days), at a day close, a statement releases the entries posted up to 7 days before (funds_hold_days = 7): money reaches your cash 7–20 days after the day that earned it. GET /api/v1/account β†’ wallets[].next_release_tick (and next_release_at, real time) says when.
  • Reserve: a statement keeps back a reserve for the refunds still to come: the account's refund rate on the market over the last 91 days (refunds / gross sales) Γ— the gross sales of the last 14 days. It is released by the next statements as it falls.
  • Negative balance: if a statement's entries plus the reserve and carry are negative, the deficit is carried to the next statement; if that one is negative too, it is charged to your cash (negative_balance_charge; your cash may go negative, and then orders and payouts wait until it is positive again).
  • On demand: once per marketplace day and market you may ask for a disbursement (POST /api/v1/disbursements, or the console): it releases everything posted before the start of the day seven days ago (the same 7-day hold, counted back from today), and the reserve too when you have no lot on that market any more; refused (400) when nothing would be paid, 409 when it was used today (marketplace day) or when a raised hold leaves its cutoff where the last release ended. wallets[].eligible_now and on_demand_available say what it would pay. A raised hold never releases a day twice: a wallet's next statement is the first whose cutoff passes the last one released.

Every statement lists its entries by kind with the opening reserve and carry, the net, the new reserve and carry, and what was disbursed or charged (GET /api/v1/statements: from_tick, to_tick = its cutoff, close_tick). The transfer appears in both wallets of the ledger (disbursement), so cash + seller balance is always the account's whole money.

Removals and maximum age

You may have units removed (shipped back to you: they become owned goods in your inventory, at the lot's unit cost; on a competition account they are gone like a disposal) or disposed of, at the fees above: POST /api/v1/removals {market, msku, qty, kind: removal|disposal, position_id?} (the oldest units first, or the named lot). Only units on hand can be ordered out: a request for more units than are on hand and not already in your pending requests is refused (400, with the number you can order out), and so is one naming a lot that has not arrived yet (400; request it again once it is on hand). A removal is carried out within the marketplace hour β€” at the close of the hour it was requested in (effective_tick) β€” on the units on hand; if fewer are left by then (units sold in the meantime), the rest of the request stays open for the following hours. A request may be refused (400) while the market is catching up on its closes (try again in a moment); a request can be cancelled while nothing of it has been worked (409 once a close worked it). On an account without an account holder a removal is a disposal. Its fee accrues on the lot and is posted at the day close.

Stock has no horizon, but a safety maximum age: units still on hand 546 days (78 weeks) after their lot arrived are removed automatically to the account holder's owned goods (disposed of on an account without a holder), at the removal fee (auto_removal_at_tick). Competition accounts write their lots off 112 days after the fill, without a fee, so a competition can end.

Fulfilment-network capacity

An account may hold at most max(400, 6 Γ— the cu ft it shipped over the last 91 days) cubic feet per market: on hand + inbound + every order of the account not yet filled (unpaid or paid) + the new line. A line beyond it is refused (400) with the numbers, when it is ordered and again when it is paid; GET /api/v1/account β†’ fulfilment reports capacity_cuft, used_cuft, inbound_cuft and ordered_cuft per market.

Fee amendments

The fee card changes only forward, by amendments the operator schedules with at least 30 days' notice in real time: an amendment names the real time it takes effect from and applies from the first marketplace day that starts then (midnight, marketplace time: a day's storage and surcharges are charged under one schedule); it is published in rules.pending_amendments ({version, effective_tick, effective_at, effective_sim_at, digest, note}) as soon as it is scheduled. From that day on every fee of every account is charged under the new schedule (rules.fees.schedule_version, and each offer's fee_schedule); nothing already posted or accrued changes, and the market itself (its demand, prices and the desk's record) never moves with the fees.

The record and the desk

The desk's record of executed trades works as on the wholesale market, by marketplace days: the desk decides on each offer once, when it appears, and its lots use the default repricer and the genesis fee schedule, are held 112 days and show what they sold each day, the buy box and their result once settled. Your trades appear in the record with their units and the buy box per day, open until the lot settles (with no fixed horizon: open_ended), never with your price. The series of the record (/trades, /history, a lot's reveal) have one entry per marketplace day (step_hours: 24); the tape, the trade statistics and a listing's signals are served by day by default (resolution=hour|day|week, up to 120 days of tape or statistics and 400 days of signals per call).

Determinism

The market β€” every listing's demand hour by hour, the crowd, the buy box, ranks, the offers and the desk's record β€” is a pure function of the market's seed and the marketplace hour: no account, order or price of yours moves it, and fee amendments do not either. What happens to your stock is deterministic given the market and what the accounts did: every draw (lead times, inbound issues, your share of the buy box, returns) comes from a stream keyed by the account, the SKU, the lot and the hour, so re-running an hour β€” or catching up on a day of hours after a restart β€” gives the same result, ledger entry for ledger entry.

Renamed fields and the API version

The API stays /api/v1; a client recognises the continuous marketplace by time_model: "continuous" in GET /api/v1/markets/{id} (and in rules). What changes for a client written for the classic markets, where a tick is the period of one menu:

was on the continuous marketplace
four market ids m15, m45, h2, h10 one market us; the old ids are accepted as aliases in paths and parameters, answers say us
a tick = the period of one menu a tick = one marketplace hour: ticks_per_day 24, time_scale, tick_sim_at, sim_now; sim_at on the menu, history and tape rows, orders and the record
one menu per tick offers open for days: valid_until, hours_left, sim_valid_until
an order fills at the close of its tick expires_tick (payment window), paid_tick; fills at the close of the paid hour
storage_per_session storage_per_day, storage_per_month; rules storage_per_cuft_day, storage_per_unit_day
lead times in ticks in days: lead_time.unit / lead_unit = "days", arrives_window_days, lead_time_days
sales_by_tick, buy_box_by_tick, price_by_tick, nsellers_by_tick, revealed_ticks sales_by_day, buy_box_by_day, price_by_day, nsellers_by_day, revealed_entries, with step_hours 24
settlement_horizon_ticks only also settlement_horizon_days, path_step_hours
signal rows' rank_drops_prev rank_drops_step (the rank drops over the row's hours); rows by day with to_tick, ticks
tape, statistics and signals per tick a resolution parameter: hour, day (the default) or week; answers add resolution, step_ticks
rule periods in ticks max_age_days, competition_writeoff_days, settlement_period_days, funds_hold_days, capacity_window_days, guardrail_window_days, days_of_supply_windows_days, publication_delay_hours, drops_window_days, drops_window_long_days
money posted at every close posted once per lot and kind at each day close; accrued_today on lots until then; invoices (by marketplace month) on the stock view
on demand once per tick once per marketplace day
amendments from a tick effective_tick is the first marketplace hour of a day; effective_sim_at

Configuration

XGM_TIME_SCALE (default 24; a divisor of 3600) sets the clock. XGM_AMAZON_CONFIG=/path/to/amazon.json overrides any field of the engine's configuration (lists stand for tuples): every market field of the wholesale configuration (categories, catalogue, demand, sellers, buy box, rank, supply, the desk β€” these generate the calibrated weekly series the hourly market is drawn from), the fee schedule, physicals and returns of the weekly fields below, and the marketplace's own, in marketplace days and hours:

group knobs
clock time_scale (must equal XGM_TIME_SCALE), sim_epoch (the marketplace date and time of tick 0, a whole hour), hours_per_tick (1)
the market hour by hour hour_profile (24 values), weekday_profile (7, Monday first), change_hour_span, rank_delay_hours, rank_scatter_blend_hours, drops_window_days, drops_window_long_days
supplier offers offer_life_days, offers_alive, deal_share, supplier_processing_days, supplier_spread_hours
the desk desk_horizon_days, desk_coverage_days, desk_period_days, desk_threshold_continuous, desk_explore_prob
stock and pricing max_age_days, competition_horizon_days, dos_short_days, dos_long_days, utilization_window_days, guardrail_window_days, guardrail_factor, default_max_vs_list, capital_holding_rate (per week)
returns returns (per category: the share of units returned and the share of returns sellable again; a list of [code, rate, sellable] replaces, a dict {code: [rate, sellable]} merges), refund_lag_days, return_back_lag_days
fee schedule fees: a partial schedule β€” a dict keyed by category code, size tier or route code merges into the default table entry by entry, a list replaces the table (the fields are listed in rules.fees.schedule); the windows and periods it counts in weeks (rules.fees.schedule_week_fields) are read as weeks of seven marketplace days
physicals physicals_from_titles, large_bulky_share, unit_weight_lb, density_lb_cuft, content_density_lb_cuft, content_factor, content_tare_lb, multipack_slack, multipack_tare_lb, bundle_slack, bundle_tare_lb, bundle_pad_in, carton_max_cuft, carton_max_lb

For example:

{
  "fees": {"referral": {"GRO": {"tiers": [[15.0, 0.08], [null, 0.15]], "min_fee": 0.0}},
           "storage_standard": [0.78, 2.40],
           "routes": {"parcel": {"per_lb": 0.45}}},
  "returns": {"PET": [0.05, 0.6]},
  "max_age_days": 364,
  "refund_lag_days": [3, 14],
  "guardrail_factor": 1.6
}

The configuration β€” the clock included β€” is part of the market's frozen identity: changing it, or XGM_TIME_SCALE, needs a fresh XGM_DB_PATH β€” to change the fees of a running market, schedule an amendment instead (xgames amazon fees amend, see Deploying). A fresh database records the market's history back to XGM_HISTORY_DAYS (real days) before now; at time scale 24 that is 24 marketplace days per real day, and a history of more than 20,000 marketplace hours is refused at start unless XGM_ALLOW_LONG_BACKFILL=1. xgames amazon report and xgames amazon calibrate print what a configuration produces and how its public series, aggregated to weeks, compare with a real marketplace's.

API

Everything of the wholesale market's API applies (GET /api/v1/stock per SKU and lot, positions with stage, the signals of a listing). The seller's endpoints β€” reads with your key, writes with the same access as placing orders (an agent with trade access, or a competition account):

Method & path Description
GET /markets/us/deals/{key}/inbound?qty= every route's inbound quote for qty units (default and at most the offer's max_qty): {market, offer_key, tick, qty, max_qty, unit_cost, default_route, quotes[] {route, label, available, reason, cartons, identical_cartons, pallets, placement, carrier, placement_fee, prep, per_unit, total, lead, lead_typical, lead_min, lead_max, lead_unit, defect_fee, defect_risk, default}}, lead times in days (404 when the offer is not open now)
POST /orders, POST /cart/items {…, route?, pricing?} an order or a cart line with its inbound route (default parcel) and a starting pricing rule; the order answers with expires_tick and closes_at
PUT /pricing/{market}/{msku} {kind, offset?, offset_pct?, price?, min_price, max_price?, note?} set the rule: {market, msku, sku, rule, effective_from_tick, effective_from_at, preview {price_at_current_buy_box, active, reason, default_min, default_max, buy_box, …}}; 400 with the reason when the rule is invalid; 403 for a min_price under break-even (default_min) unless autonomous funding is on; set again in the same hour, it replaces the pending rule
DELETE /pricing/{market}/{msku} back to the default repricer from the next marketplace hour
GET /pricing?market=, GET /pricing/{market}/{msku} your rules; one rule with its history
POST /removals {market, msku, qty, kind, position_id?} request a removal or disposal of on-hand units (201); 400 for more units than are on hand and not already in pending requests, or for a named lot not arrived yet; a disposal is 403 unless autonomous funding is on (the account holder disposes on the console)
GET /removals?status=&market=, DELETE /removals/{id} your removal requests; cancel one still requested (409 once any of it is done)
GET /stock your stock per SKU and lot (accrued_today, lead_time_days, arrives_window_days, today, days_of_supply) and the monthly invoices
GET /statements?market=&limit=, GET /statements/{id} settlement statements, one with its entries
POST /disbursements {market} disburse on demand: 201 with the statement and the new available_balance; 409 already used this marketplace day; 400 nothing to pay
GET /ledger?wallet=&kind=&statement_id= your ledger by wallet (cash, us for the seller balance, or all); seller-balance entries carry the day's last tick and day N
GET /account adds available_balance (cash), seller_balance, reserve, wallets[] (per market, with eligible_now, next_release_tick, next_release_at and on_demand_available) and fulfilment {market: {capacity_cuft, used_cuft, inbound_cuft, ordered_cuft}}

Smoke clients

client/smoke/ holds dependency-free clients (the standard library and xgames_client) for a local test deployment (local payments, agent keys issued with its own key secret β€” never a live one), run at a fast XGM_TIME_SCALE. They trade as five separate agents, each with its own simulated account holder who registers, accepts the terms and pays on the web pages, and they act twice a marketplace day (at 02:00 and 14:00), not every hour:

strategy what it does
default the default repricer, partnered parcel; the holder pays each order's checkout by card twelve marketplace hours after the order was placed (inside its payment window); one order is left unpaid and must expire
undercut follows the Buy Box 3 % under it, never under the break-even the pricing preview quotes, on the cheapest available route; proposes into its cart, the holder pays the cart
manual a fixed price re-set from the Buy Box it observes at every pass, back to the default repricer now and then; paid from the topped-up balance
liquidator lists over the Buy Box, then orders the slow stock out (removals to owned goods, disposals by the holder on the console); cancels one request
cash the default repricer; disburses on demand whenever something is eligible (once a marketplace day), reads its statements

They check from the outside, as the marketplace days pass: no server error; the fields of every answer (with the marketplace-time ones); no hidden word, no marketplace mark and no time named the weekly engine's way in what is served; each wallet's ledger (every balance_after follows from the entry before; the sums are the reported balances); the seller balance = the entries no statement released yet + reserve + carry; an order's expires_tick = the end of its payment window or of the offer, whichever comes first; a paid order fills at the close of the hour it was paid in (its lot opens in that hour); an unpaid one expires and costs nothing; a lot arrives its lead time in days after the fill and sells nothing before; a lot's money reaches the seller balance only at a day close, once per kind and day (day N); the monthly invoices add up to the month's postings of every charge, by kind, by SKU and in total; every statement (its released entries add up to net; opening reserve + carry + net = reserve + carry + disbursed βˆ’ charged; its transfer appears on both sides; a scheduled one closes a day d with (d βˆ’ 7) mod 14 = 13 and releases through the end of day d βˆ’ 7, an on-demand one through the end of the day before the hold); units per lot; a lot's entries = its cash flows, and once settled its entries + the order's debit = its realized P&L; a lot's past daily sales and prices never change; a rule set in one hour prices from the next (checked hour by hour on the last settled hour of each pool); removals are carried out within the hour and become the holder's owned goods; one on-demand disbursement per marketplace day; another agent never sees your lots, rules or statements, and the public record of your lots carries no price of yours. A run that exercised too little β€” a strategy that never ordered on its order days, no fill, rule hour, invoice, scheduled statement, removal or on-demand disbursement checked in a run long enough for them β€” is inconclusive and fails like a violation (--no-coverage-gate reports it without failing). They print a summary and write a JSON report (P&L per strategy, fees by kind with the daily holding postings, returns and refunds, statements and disbursements, removals, pricing changes, fills and their delay after the payment, the HTTP status counts, errors):

python -m client.smoke.amazon_smoke --spawn --out /tmp/amazon-smoke      # starts and stops its own local server (45 marketplace days)
python -m client.smoke.amazon_smoke --spawn --days 45 --example 40 --out /tmp/amazon-smoke   # with the example below beside it
python -m client.smoke.amazon_smoke --base http://localhost:8000 --key-secret <its key secret> --out /tmp/amazon-smoke
python -m client.smoke.amazon_smoke --help                                # the run length and pacing options

--spawn starts xgames serve on a free localhost port with a fresh temporary database, the continuous marketplace at XGM_TIME_SCALE=3600 (a marketplace hour every real second: 45 marketplace days take about 18 real minutes), the genesis about three weeks of marketplace time before now, a small history, local payments, a random key secret, and the smoke configuration client/smoke/continuous_smoke_config.json (a small catalogue, the supplier's processing one day instead of seven: lots arrive 3–29 days after the fill).

client/examples/10_amazon_seller.py is the same seller flow as one readable script: the market's clock and rules, an open offer's fee breakdown and how long it stays open, the inbound quotes in days, an order with a starting pricing rule paid and filled at the close of its hour, the stock day by day (the arrival, the units sold, a live price change from the next hour, a removal of slow stock within the hour, an on-demand disbursement), then the statements, the monthly invoices and the lot's daily record:

python client/examples/10_amazon_seller.py http://localhost:8000 <an issued key> --days 30 --local-holder

Operator note. XGM_KERNEL=amazon_weekly runs the earlier seller engine instead, with four markets of weekly sessions; it is kept for its record and its tests, and its documentation is served on such a deployment in place of this page. The fee schedule's fields named after its sessions (settlement_period_sessions, funds_hold_sessions, low_inventory_new_sessions, utilization_new_seller_sessions, capacity_window, reserve_window, refund_window, returns_window) count weeks of seven marketplace days here; the weekly-only fields (max_age_sessions, competition_horizon, the session windows) are not read by the continuous marketplace β€” set their day equivalents above.