Free Pricing API tutorial
How to Look Up CS2 Skin Prices
Build a small webpage that shows the price reported by each marketplace and when each price was checked.
Last updated 2026-09-04 · Reviewed by OpenSkin · 20 minutes · Beginner
What you will build
Build a small webpage where someone enters the full item name shown on Steam and sees the current price from each available marketplace.

Before you start
- Python 3 to serve the files locally
- A modern web browser
- The full item name shown on the Steam Community Market
Project files
current-price-card/
index.html
styles.css
app.jsBuild it
- Create the form and results table
The form asks for the full Steam market name. The results table stays hidden until the API returns a price.
- Request the item
URLSearchParams correctly handles spaces, the pipe character, and the exterior in names such as AK-47 | Redline (Field-Tested).
- Create one row per marketplace
Keep the marketplace name beside its price and checked time. Skip marketplaces that did not return a price.
- Show API errors
Check the HTTP status before displaying results. An invalid or unknown item should show a message instead of a blank table.
- Serve and open the page
Start the local server with the command below, then open http://localhost:8090 in a browser.
index.html
Form and result table
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>CS2 price lookup</title>
<link rel="stylesheet" href="styles.css">
</head>
<body>
<main>
<p class="eyebrow">Marketplace prices</p>
<h1>CS2 price lookup</h1>
<form id="lookup">
<label for="item">Exact Steam market name</label>
<div class="controls">
<input id="item" value="AK-47 | Redline (Field-Tested)" required>
<button>Get prices</button>
</div>
</form>
<p id="status" role="status"></p>
<section id="result" hidden>
<h2 id="result-title"></h2>
<table>
<thead><tr><th>Marketplace</th><th>Listed price</th><th>Checked</th></tr></thead>
<tbody id="prices"></tbody>
</table>
</section>
</main>
<script type="module" src="app.js"></script>
</body>
</html>app.js
API request, error handling, and rendering
const API = 'https://api.openskin.dev/v1/prices'
const form = document.querySelector('#lookup')
const itemInput = document.querySelector('#item')
const status = document.querySelector('#status')
const result = document.querySelector('#result')
const title = document.querySelector('#result-title')
const tbody = document.querySelector('#prices')
const marketplaceNames = {steam:'Steam', skinport:'Skinport', buff:'Buff163', youpin:'YouPin', csfloat:'CSFloat'}
function marketplaceRows(payload) {
return Object.entries(payload.prices ?? {})
.flatMap(([marketplace, quote]) => {
const ask = quote?.ask ?? null
if (typeof ask !== 'number') return []
return [{marketplace: marketplaceNames[marketplace] ?? marketplace, ask, observedAt: quote.updated_at ?? 'Not provided'}]
})
.sort((a, b) => a.ask - b.ask)
}
function addCell(row, value) {
const cell = document.createElement('td')
cell.textContent = value
row.append(cell)
}
form.addEventListener('submit', async event => {
event.preventDefault()
result.hidden = true
status.textContent = 'Looking up prices…'
const query = new URLSearchParams({item: itemInput.value.trim()})
try {
const response = await fetch(`${API}?${query}`)
const payload = await response.json()
if (!response.ok) throw new Error(payload.error?.message ?? payload.message ?? `Request failed (${response.status})`)
const rows = marketplaceRows(payload)
if (!rows.length) throw new Error('No current prices are available for this item.')
tbody.replaceChildren()
for (const price of rows) {
const row = document.createElement('tr')
addCell(row, price.marketplace)
addCell(row, new Intl.NumberFormat('en-US', {style:'currency', currency:'USD'}).format(price.ask))
addCell(row, price.observedAt === 'Not provided' ? price.observedAt : new Date(price.observedAt).toLocaleString())
tbody.append(row)
}
title.textContent = payload.item ?? itemInput.value.trim()
status.textContent = `${rows.length} marketplaces returned`
result.hidden = false
} catch (error) {
status.textContent = error instanceof Error ? error.message : 'The request failed.'
}
})styles.css
Readable responsive layout
:root { color-scheme: dark; font-family: system-ui, sans-serif; background:#141614; color:#f3f4f3; }
body { margin:0; padding:48px 20px; }
main { width:min(760px,100%); margin:auto; }
.eyebrow { color:#8eb69a; font:600 12px ui-monospace,monospace; text-transform:uppercase; }
h1 { margin:8px 0 32px; font-size:clamp(36px,8vw,64px); letter-spacing:-.04em; }
label { display:block; margin-bottom:8px; color:#b7bbb8; }
.controls { display:flex; gap:10px; }
input,button { min-height:44px; border:1px solid #3b403c; border-radius:6px; font:inherit; }
input { flex:1; min-width:0; padding:0 12px; background:#1d201e; color:inherit; }
button { padding:0 18px; background:#376f49; color:white; cursor:pointer; }
#status { min-height:24px; color:#aeb2af; }
section { margin-top:28px; border-top:1px solid #343735; }
table { width:100%; border-collapse:collapse; }
th,td { padding:13px 8px; border-bottom:1px solid #303331; text-align:left; }
th { color:#9ea29f; font-size:12px; }
td:nth-child(2) { font-variant-numeric:tabular-nums; }
@media (max-width:560px) { .controls { display:grid; } th:nth-child(3),td:nth-child(3) { font-size:11px; } }Run it
cd current-price-card
python3 -m http.server 8090
Open http://localhost:8090 in your browser.Expected output
AK-47 | Redline (Field-Tested)
Marketplace Listed price Checked
CSFloat $21.91 Sep 4, 2026, 5:13 AM
Steam $24.38 Sep 4, 2026, 5:12 AMHow it works
- The full item name shown on Steam includes the exterior. AK-47 | Redline and AK-47 | Redline (Field-Tested) are different items.
- The page sorts prices from lowest to highest but keeps each marketplace separate.
- If a marketplace has no price, the page leaves it out. It does not turn missing data into a $0 price.
Verify the result
Enter the full item name shown on Steam and confirm that the table shows at least one marketplace, price, and checked time. An unknown item should show an error instead of an empty or zero price.
Troubleshooting
| What you see | Likely cause | What to do |
|---|---|---|
| 400 Invalid item | The item parameter is empty or malformed. | Copy the full item name shown on Steam, including the exterior. |
| 404 Unknown item | The catalog does not contain that exact market name. | Check spelling and punctuation against Steam or the OpenSkin catalog. |
| Table is empty | Known item, but no marketplace currently has an ask. | Show “No current asks” and keep the value missing rather than using zero. |