Put any CS2 skin on your own page, in 3D, with the stickers, charm, name tag, float and pattern seed you choose.
It is an <iframe> whose look is decided by its URL — no SDK, no build
step, nothing to install.
Turn every option on and off and watch the frame change. The tag under it is exactly what produces what you see — copy it onto your page and swap in your key. Each switch names the parameter it sets.
Drag to orbit. In first person, click fires, R reloads, G draws the weapon again and F inspects. The chequerboard is
the page behind the embed: with no bg the frame is genuinely
transparent, not black.
One tag. Replace the key with your own (see below) and the
item with any skin on the site — the two path segments are the same ones in our own URLs, so
cs2inspect.skin/ak-47/redline becomes
item=ak-47/redline.
<iframe
src="https://cs2inspect.skin/embed?key=pk_live_YOURKEY&item=ak-47/redline&wear=0.18&seed=661&spin=6"
width="600" height="400" frameborder="0" title="AK-47 | Redline"></iframe>
The frame is transparent by default, so it sits on your own background. Give it whatever size you like; the weapon is framed to fit whatever box it lands in.
Three ways, whichever your data already looks like.
item=ak-47/redline
The site's own two slugs: weapon, then skin. item=ak-47 on its own shows
the bare weapon.
name=AK-47 | Redline (Field-Tested)
The exact Steam market name, exactly as a marketplace holds it. Everything around the skin's own name
describes the copy rather than the skin, so it is unpicked for you: ★
and Souvenir are dropped, the
(Field-Tested) suffix is dropped because
wear says it exactly, and
StatTrak™ turns the counter on unless your
st says otherwise. So
★ StatTrak™ Karambit | Doppler (Factory New) just works.
weapon=ak47&paint=282
The model key and the paint index, as they appear in an inspect link. Best if you already parse inspect links;
paint left out means the bare weapon.
There is nothing to switch on: with no bg the frame is fully
transparent and your own page shows through it, whatever colour, gradient or image is back there. Set
bg only when you want the embed to paint its own —
bg=0b0d12, bg=white,
bg=rgb(20,22,30). bg=transparent
says the default out loud, which is worth doing if you are generating these URLs from a template.
It sits bottom left by default. logo=icon shrinks it to the mark alone,
logo=minimal drops the dark pill behind it for pages that are dark
anyway, and logopos=br, tl or
tr moves it to another corner. The embed is free and every load
serves a weapon model and several megabytes of texture off our bandwidth; the credit is what pays for that,
so on the Basic plan it cannot be removed —
logo=none is ignored and the default mark shows. Accounts on the
Premium plan can use logo=none to
remove it from every embed made with their keys.
The skin's name, its float and its seed, in whichever bottom corner the wordmark is not in. Useful on a page
that does not say those anywhere else, noise on a product page that already does.
card=0 and it is gone. The controls move the same way, to the top
corner the wordmark leaves free.
| Parameter | Default | What it does |
|---|---|---|
item |
— | weapon/skin slugs, e.g. awp/dragon-lore. |
name |
— | The full market name, instead of item. |
weapon, paint |
— | Model key and paint index, instead of item. |
wear |
0.06 |
The float, 0–1. Clamped to the skin's own legal range. |
seed |
1 |
Pattern index, 0–1000. Decides which part of the artwork lands where. |
st |
0 |
StatTrak™ module on the weapon. |
nametag |
none | Name tag text, up to 20 characters. |
stickers |
none | See stickers and charms. |
charm |
none | index or index:seed. |
bg |
transparent |
transparent (the default — your own page shows through), a hex colour
(0b0d12), an rgb() or a colour keyword.
|
spin |
0 |
Turntable speed in degrees per second. Pauses while someone is dragging. |
card |
1 |
card=0 removes the little name card in the bottom-left — the skin name, float and seed.
|
interactive |
1 |
interactive=0 stops dragging and zooming. |
view |
item |
view=hands shows the weapon held in first person, as in game. Click fires (hold for automatic weapons), right click is a knife's heavy attack, F inspects. |
gloves |
— | Gloves worn in first person: sport-gloves/vice (our page slugs) or the market name Sport Gloves | Vice. Absent or none: the agent's own. Change live with view.setGloves(). |
glovewear |
0 |
The gloves' float, 0–1, e.g. glovewear=0.15. Live: view.setGloves("sport-gloves/vice", 0.15). |
scene |
none |
A background from our maps, lit by that map's lights: vanity (warehouse), dust2, mirage, inferno, nuke, overpass, ancient_day, ancient_night, anubis, baggage, cache, italy, office, train, vertigo. |
controls |
0 |
controls=1 shows buttons for the view (rotate / first person), inspect and, with a scene, a background picker. |
ui |
1 |
ui=0 starts with the name card and controls hidden. H, the Hide UI button or view.setUi() toggles them. The wordmark always stays. |
accent |
D4FF4A |
Colour of the loading indicator and the active control. Hex (no # needed), rgb() or a colour name. |
loader |
bar |
Loading indicator: bar, spinner, dots or none. |
logo |
full |
How the wordmark looks: full, icon or minimal. none removes it, on the Premium plan only; on Basic it is ignored. See the corners. |
logopos |
bl |
The wordmark's corner: bl, br, tl or tr. The name card and controls take the corners it leaves free. In embed.js also accepted as logoPosition. |
key |
— | Your embed key. Required on every site but ours. |
A parameter this build has never heard of is ignored rather than refused, and so is a sticker that is not in the catalogue. An embed that drops one sticker is a small disappointment; one that renders an error box on your page because we shipped something new is not.
A sticker is slot:index, comma-separated. The slot is a position on the
weapon counted from 0; the index is the sticker's own number, the one in its inspect link.
stickers=0:5032,2:4501
Four optional numbers place it exactly, in the order you would say them — across, down, turn, wear:
slot:index:x:y:rotation:wear. x and
y are the game's own sticker offsets from the slot's centre (the values in an
inspect link; 0 is centred), rotation is in degrees, and wear is the
sticker's scrape, 0 (pristine) to 1.
Leave all four out and the sticker sits in the slot's default spot.
stickers=0:5032:0.02:-0.01:12:0.1charm=4123:661
The quickest way to get one of these right is to build it on the site — open a skin, place the stickers, then API → Copy iframe in your account menu. The snippet is the build on screen.
Optional, and only worth it if the embed has to react to something on your page — a skin picker, a float slider, a row of stickers being chosen. The loader is 3 KB and has no dependencies.
<div id="viewer" style="height:400px"></div>
<script src="https://cs2inspect.skin/embed.js"></script>
<script>
var view = CS2Inspect.embed("#viewer", {
key: "pk_live_YOURKEY",
item: "ak-47/redline",
wear: 0.18,
spin: 6,
});
view.on("ready", function (e) { console.log("showing", e.item); });
view.on("error", function (e) { console.warn(e.reason, e.message); });
// Later — only the fields you pass change.
view.update({ wear: 0.41, stattrak: true, stickers: [{ slot: 0, index: 5032 }] });
view.resetView();
</script>
CS2Inspect.url(spec) returns the embed URL for a spec without creating a
frame, if you would rather render the iframe yourself.
The loader is a wrapper over postMessage. Anything it does you can do
directly:
frame.contentWindow.postMessage(
{ type: "cs2embed:set", spec: { wear: 0.41, spin: 0 } },
"https://cs2inspect.skin",
);
window.addEventListener("message", function (e) {
if (e.data && e.data.source === "cs2inspect-embed") console.log(e.data.type, e.data);
});
Messages in: cs2embed:set (any parameter above, including
view and scene),
cs2embed:reset, cs2embed:inspect,
cs2embed:fire (alt: true for the secondary attack),
cs2embed:ping. With embed.js:
view.setView("hands"), view.setScene("dust2"),
view.inspect(), view.fire(),
view.setUi(false).
Messages out, all carrying source: "cs2inspect-embed":
ready (with the item it resolved),
updated, view (the view changed),
error and
pong.
example.com, or *.example.com for
a domain and everything under it. Ports are ignored, so localhost covers
your dev server on any port.
key=….It travels in the HTML of every page that frames the viewer, so anyone can read it. What limits it is the list of sites next to it, not secrecy — and nothing behind it is private: these are the same skins on our own public pages. Treat it as a name, not a password. If you would rather it stopped working, switch it off in the API panel.
Every embed loads a weapon model and its textures from us, which is megabytes per skin, so asset requests are
metered per visitor. Ordinary browsing never notices; a page that mounts fifty embeds at once will. Load them
lazily as they scroll into view — the JS loader already sets
loading="lazy".
The frame says what is wrong and what to do about it, and posts the same thing to your page as an
error message with a reason:
no_key |
No key in the URL, on a site that is not ours. |
bad_key |
No such key. Check it against the API panel. |
revoked |
The key was switched off by its owner. |
origin_not_allowed |
This site is not on the key's list. Add it in the API panel. |
no_origin |
The page was opened directly instead of being framed. |
unknown_item |
Nothing in the catalogue answers to that name, slug or paint index. |
no_model |
The skin is real but its model could not be loaded. Usually temporary. |
rate_limited |
Too many embeds from one visitor at once. Clears by itself. |