Sandbox Config Documentation
What is a Config?
A config is a custom script written in JavaScript that analyzes a list of past skin sales (listings[]
) and returns a single number — your suggested price or value estimation.
You also receive the current item
object to compare against each listing.
Inputs
listings[]
: array of past sales. Each entry has fields likesale_price
,float_value
,fade_percent
,playside_blue
,sale_date
, etc.item
: the current item being estimated. Contains fields likefloat_value
,fade_percent
,playside_blue
, andstickers
.
Return Value
Your script must return a single number — this will be shown as the estimated price on the CSFloat listing card. If your config can’t estimate (e.g. not enough data), return null
.
Writing Your First Config
Here’s the simplest possible config — it returns the average price of all listings:
function run(listings, item) {
let total = 0;
for (let l of listings) {
total += l.sale_price;
}
return total / listings.length;
}
But some configs will:
- Group listings by float range (e.g., 0.07–0.09)
- Filter by fade percent, blue %, and stickers
- Trim outliers (lowest/highest prices)
- Use time-decay weighting to prioritize recent sales
- Add a small bonus for stickers
The following default config shows how to do all of the above.
Default Config Example
function run(listings, item) {
function getFloatBucket(f) {
const r = [[0.75,1],[0.5,0.75],[0.45,0.5],[0.4,0.45],[0.38,0.4],[0.3,0.38],[0.24,0.3],[0.21,0.24],[0.18,0.21],[0.165,0.18],[0.15,0.165],[0.12,0.15],[0.09,0.12],[0.07,0.09],[0.06,0.07],[0.01,0.06],[0.001,0.01],[0,0.001]];
for (const [min, max] of r) if (f <= max && f > min) return [min, max];
return null;
}
function within(a, b, t) {
return typeof a === 'number' && typeof b === 'number' && Math.abs(a - b) <= t;
}
const b = getFloatBucket(item.float_value);
if (!b) return null;
const TOL_FADE = 3, TOL_BLUE = 3, now = Date.now(), decayDays = 1, trimPercent = 0.15;
const baseOnly = listings.filter(s =>
s.float_value > b[0] && s.float_value <= b[1] &&
(item.fade_percent == null || within(s.fade_percent, item.fade_percent, TOL_FADE)) &&
(item.playside_blue == null || within(s.playside_blue, item.playside_blue, TOL_BLUE)) &&
s.stickers === '[]'
);
if (baseOnly.length < 3) return null;
const sorted = baseOnly.slice().sort((a, b) => a.sale_price - b.sale_price);
const cut = Math.floor(sorted.length * trimPercent);
const trimmed = sorted.slice(cut, sorted.length - cut);
const weighted = trimmed.map(s => {
const age = (now - new Date(s.sale_date).getTime()) / (1000 * 60 * 60 * 24);
const w = Math.exp(-age / decayDays);
return { p: s.sale_price, w };
});
const sumW = weighted.reduce((a, x) => a + x.w, 0);
const base = sumW ? weighted.reduce((a, x) => a + x.p * x.w, 0) / sumW : null;
if (!base) return null;
let stickerPrice = 0, boost = 0;
try {
const stickers = JSON.parse(item.stickers || '[]');
stickerPrice = stickers.reduce((sum, s) => sum + (s.reference?.price || 0), 0);
if (stickerPrice < 100) boost = 0.1;
else if (stickerPrice < 1000) boost = 0.05;
else boost = 0.02;
} catch {}
return Math.round(base + (stickerPrice * boost));
}
This config buckets float, filters by fade & blue %, removes outliers, weights recent sales, and boosts for stickers.
Security and Restrictions
- No access to network, window, document, or fetch
- No DOM or browser APIs
- Only pure JavaScript logic is allowed
Tips
- Wrap logic in try/catch to avoid runtime crashes
- Return
null
when you can't make a good estimate - Test your config with real listing arrays
- Keep your code short and optimized
This documentation is for FloatPilot config creators only.