Appearance
Single-page API reference optimized for LLMs, AI agents, and code generation tools. For full interactive docs, see the API Reference.
Skinslink is a Steam skin trading platform. Merchants integrate with Skinslink to accept Steam item deposits from users and purchase skins for delivery to users. The API handles inventory pricing, deposit creation, skin purchases, trade offer management, and status tracking via webhooks.
Base URL: https://api.skinslink.com/api/v1
Auth: All requests require X-Api-Key: <your-api-key> header.
Response envelope: Every response follows { "success": bool, "message": string, "data": ... }.
Supported games: csgo (CS2), rust, dota2, tf2
Creates a deposit intent for the redirect flow. Returns a URL where the user completes the deposit on Skinslink's hosted page.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
merchant_tx_id | string | yes | Your unique order ID |
game | string | no | csgo, rust, dota2, tf2 |
partner | integer | no | Steam trade partner ID |
token | string | no | Steam trade token |
result_url | string | no | Webhook URL override for this deposit |
success_url | string | no | Redirect URL on success |
fail_url | string | no | Redirect URL on failure |
custom_currency | string | no | Currency code (1–4 chars). Requires all 3 currency fields |
custom_currency_multiplier | number | no | Multiplier (0.5–2.0) |
custom_currency_rate | number | no | Exchange rate (≥ 0.1) |
Response data: { "id": int, "merchant_tx_id": string, "url": string }
Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/create-intent \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"merchant_tx_id":"order-123","game":"csgo","partner":123456789,"token":"AbCdEfGh"}'Fetches a user's Steam inventory with real-time pricing.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
game | string | yes | csgo, rust, dota2, tf2 |
partner | integer | yes | Steam trade partner ID |
token | string | yes | Steam trade token (exactly 8 characters) |
Response data:
{
"items": [
{
"id": "38029384123",
"name": "AK-47 | Redline (Field-Tested)",
"price": 12.45,
"image_url": "https://community.cloudflare.steamstatic.com/economy/image/...",
"exterior": "Field-Tested",
"rarity": "Classified",
"rarity_color": "#d32ce6"
}
],
"total": 47,
"sum": 284.90,
"game": "csgo"
}Notes:
items[].id as asset_ids in create-deposit.Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/inventory \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"game":"csgo","partner":123456789,"token":"AbCdEfGh"}'Creates a deposit with selected Steam items. Returns trade offer details.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
merchant_tx_id | string | yes | Your unique order ID |
game | string | yes | csgo, rust, dota2, tf2 |
partner | integer | yes | Steam trade partner ID |
token | string | yes | Steam trade token |
asset_ids | string[] | yes | Item IDs from inventory response |
result_url | string | no | Webhook URL override for this deposit |
success_url | string | no | Redirect URL on success |
fail_url | string | no | Redirect URL on failure |
custom_currency | string | no | Currency code (1–4 chars). Requires all 3 currency fields |
custom_currency_multiplier | number | no | Multiplier (0.5–2.0) |
custom_currency_rate | number | no | Exchange rate (≥ 0.1) |
Response data:
{
"id": 42,
"merchant_tx_id": "order-123",
"status": "active",
"amount": 36.25,
"bot_name": "Skinslink Bot #3",
"bot_steam_id": 76561199012345678,
"trade_offer_id": "6912345678",
"trade_offer_expiry_at": "2026-02-16T12:30:00Z"
}Notes:
active on success, failed on error.bot_name, bot_steam_id, trade_offer_id may be null if the bot hasn't assigned yet.GET /merchant/deposit/status to retrieve them once the trade reaches hold or completed.Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/create-deposit \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"merchant_tx_id":"order-123","game":"csgo","partner":123456789,"token":"AbCdEfGh","asset_ids":["38029384123","38029384124"]}'Quotes provider prices by market hash name. By default also creates a draft trade record (status new) that locks the quote for 5 minutes; commit it with create-deposit-by-hash-name using the returned id.
Request headers:
X-Api-Key (required)X-Provider (optional) — comma-separated provider whitelistRequest body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
game | string | yes | csgo, rust, dota2, tf2 |
marketHashNames | string[] | yes | Item market hash names. Min 1, max 2000 |
no_deposit_intent | boolean | no | When true, skip trade creation (price-only quote). Default false |
Response data:
{
"id": 742,
"total": 2,
"sum": 45.50,
"items": [
{ "name": "AK-47 | Redline (Field-Tested)", "price": 22.75, "originalPrice": 23.10 }
]
}Notes:
id is the trade ID — pass to create-deposit-by-hash-name. Omitted when no_deposit_intent=true.price is the final price after multipliers; originalPrice is the provider's raw price.total: 0, sum: 0, items: [] with no id.X-Provider header.Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/get-prices \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"game":"csgo","marketHashNames":["AK-47 | Redline (Field-Tested)"]}'Commits a deposit using a quote id from get-prices. Identifies items by market hash name + Steam asset_id. Supports per-item min_price price-drop protection.
Request headers:
X-Api-Key (required)X-Provider (optional) — comma-separated provider whitelistRequest body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | yes | Trade ID from get-prices (min 1) |
merchant_tx_id | string | yes | Your unique order ID (overwrites the temporary ID from get-prices) |
game | string | yes | csgo, rust, dota2, tf2 |
partner | integer | yes | Steam trade partner ID |
token | string | yes | Steam trade token (exactly 8 chars) |
items | object[] | yes | Items to deposit (min 1) |
items[].asset_id | string | yes | Steam asset ID (numeric string) |
items[].name | string | yes | Market hash name (must match a name in get-prices) |
items[].min_price | number | no | Minimum acceptable price (USD); deposit fails if current price drops below |
result_url | string | no | Webhook URL override |
success_url | string | no | Success redirect URL |
fail_url | string | no | Failure redirect URL |
custom_currency | string | no | Currency code (1–4 chars). Requires all 3 currency fields |
custom_currency_multiplier | number | no | Multiplier (0.5–2.0) |
custom_currency_rate | number | no | Exchange rate (≥ 0.1) |
Response data: Same shape as POST /merchant/create-deposit (id, merchant_tx_id, status, amount, bot_name, bot_steam_id, trade_offer_id, trade_offer_expiry_at).
Processing:
id, verifies merchant ownership and status new.merchant_tx_id + game/partner/token/URLs in a DB transaction → status pending.inventory_reload.item_specified_price_not_found if any item's current price < its min_price.failed + fail_reason: provider_unavailable. On success → active.Fail reasons: item_specified_price_not_found, provider_unavailable
Errors: 400 (validation, expired prices, min_price not met), 401 (invalid key), 404 (trade not found / not yours), 409 (duplicate merchant_tx_id), 500.
Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/create-deposit-by-hash-name \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"id":742,"merchant_tx_id":"order-9999","game":"csgo","partner":123456789,"token":"AbCdEfGh","items":[{"asset_id":"38029384123","name":"AK-47 | Redline (Field-Tested)","min_price":20.00}]}'Retrieves current status of a deposit.
Query parameters:
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | one required | Internal trade ID |
merchant_tx_id | string | one required | Your order ID |
At least one of id or merchant_tx_id must be provided.
Response data:
{
"id": 42,
"merchant_tx_id": "order-123",
"status": "completed",
"bot_steam_id": 76561199012345678,
"bot_name": "Skinslink Bot #3",
"trade_offer_id": "6912345678",
"trade_offer_expiry_at": "2026-02-16T12:30:00Z",
"success_url": "https://yoursite.com/deposit/success",
"fail_url": "https://yoursite.com/deposit/failed",
"hold_end_date": null,
"fail_reason": null,
"custom_currency": "EUR",
"custom_currency_multiplier": 1.0,
"custom_currency_rate": 0.92,
"custom_currency_sum": 33.35
}Notes:
hold or completed.success_url and fail_url are only present if set on the deposit. hold_end_date is only present when status is hold. fail_reason is only present when status is failed or canceled.Example:
curl "https://api.skinslink.com/api/v1/merchant/deposit/status?merchant_tx_id=order-123" \
-H "X-Api-Key: your-api-key"Creates a skin purchase. Skinslink sends a trade offer with the requested item to the specified Steam account.
Request body (JSON):
| Field | Type | Required | Description |
|---|---|---|---|
partner | integer | yes | Steam trade partner ID (minimum: 8) |
token | string | yes | Steam trade token (exactly 8 characters) |
game | string | yes | csgo, rust, dota2, tf2 |
name | string | conditional | Item market name. Provide either name or asset_id |
asset_id | string | conditional | Specific asset ID. Provide either name or asset_id |
merchant_tx_id | string | no | Your unique order ID |
max_price | number | no | Maximum price you're willing to pay (USD) |
Response data:
{
"id": 178,
"merchant_tx_id": "order-123",
"status": "pending",
"steam_name": "John Doe",
"steam_avatar_url": "https://avatars.steamstatic.com/...",
"trade_offer_id": null,
"fail_reason": null,
"steam_id": "76561198338314767",
"amount": 45.99,
"date": "2026-03-24T10:30:00Z",
"item": {
"id": "38029384123",
"name": "AK-47 | Redline (Field-Tested)",
"price": 45.99,
"image_url": "https://community.cloudflare.steamstatic.com/economy/image/..."
}
}Note: Optional fields (merchant_tx_id, fail_reason, steam_name, steam_avatar_url, trade_offer_id, item) are omitted from the response when not available — they will not appear as null.
Fail reasons: insufficient_balance, price_changed, item_not_available, item_specified_price_not_found, provider_unavailable
Example:
curl -X POST https://api.skinslink.com/api/v1/merchant/purchase \
-H "X-Api-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{"partner":123456789,"token":"AbCdEfGh","game":"csgo","name":"AK-47 | Redline (Field-Tested)","merchant_tx_id":"order-123"}'Retrieves current status of a purchase.
Query parameters:
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | one required | Purchase ID |
merchant_tx_id | string | one required | Your order ID |
At least one of id or merchant_tx_id must be provided.
Response data: Same as POST /merchant/purchase response.
Example:
curl "https://api.skinslink.com/api/v1/merchant/purchase/status?merchant_tx_id=order-123" \
-H "X-Api-Key: your-api-key"Retrieves purchase history with pagination and filtering.
Query parameters:
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer | no | Items per page |
offset | integer | no | Pagination offset |
status | string | no | Filter: new, pending, active, hold, completed, failed, canceled, reverted |
date_range | integer | no | Days to look back: 1, 7, 30, 90, 365 |
search | string | no | Search query (1-100 chars) |
sort | string | no | Sort: id, -id, merchant_tx_id, -merchant_tx_id, status, -status, amount, -amount, created_at, -created_at |
Response data: { "data": [PurchaseResponse, ...], "total": int }
Example:
curl "https://api.skinslink.com/api/v1/merchant/purchase?limit=100&status=completed" \
-H "X-Api-Key: your-api-key"Returns available items with purchase prices for a given game.
Query parameters:
| Field | Type | Required | Description |
|---|---|---|---|
game | string | yes | csgo, rust, dota2, tf2 |
full | boolean | no | When true, returns individual items with full details. Default returns items grouped by name |
extended | boolean | no | When true, includes class_id, instance_id, float, inspect_url, phase in each item (full format only) |
Response data (grouped, default):
{
"game": "csgo",
"total": 542,
"items": [
{
"name": "AK-47 | Redline",
"count": 3,
"price": 11.20,
"game": "csgo",
"image_url": "https://community.cloudflare.steamstatic.com/economy/image/..."
}
]
}Response data (full, full=true):
{
"game": "csgo",
"total": 1847,
"items": [
{
"id": "38029384123",
"name": "AK-47 | Redline (Field-Tested)",
"price": 12.45,
"image_url": "https://community.cloudflare.steamstatic.com/economy/image/...",
"exterior": "Field-Tested",
"rarity": "Classified",
"rarity_color": "#8650AC"
}
]
}Notes:
items[].id or items[].name + game in POST /merchant/purchase.exterior, rarity, rarity_color are included when available. class_id, instance_id, float, inspect_url, phase are only included when extended=true (full format only).Example:
curl "https://api.skinslink.com/api/v1/merchant/purchase/available?game=csgo" \
-H "X-Api-Key: your-api-key"Returns purchase prices for specific item names.
Query parameters:
| Field | Type | Required | Description |
|---|---|---|---|
game | string | yes | csgo, rust, dota2, tf2 |
names | string[] | yes | Item names (names=Item1&names=Item2) |
extended | boolean | no | When true, includes class_id, instance_id, float, inspect_url, phase in each item |
Response data: Same format as GET /merchant/purchase/available full format (full=true). Supports extended=true for the same extended fields.
Example:
curl "https://api.skinslink.com/api/v1/merchant/purchase/search?game=csgo&names=AK-47+%7C+Redline+(Field-Tested)" \
-H "X-Api-Key: your-api-key"new → pending → active → completed
| | |
| | ├→ hold → completed
| | | |
| | | └→ reverted
| | ├→ failed
| | └→ canceled
| ├→ failed
| └→ canceled
└→ canceled| Status | Description | Terminal |
|---|---|---|
new | Created, not yet processed | no |
pending | Awaiting trade offer creation | no |
active | Trade offer sent, waiting for user to accept | no |
hold | Items on Steam 7-day trade hold | no |
completed | Successful, items transferred | yes |
failed | Transaction failed | yes |
canceled | Transaction canceled | yes |
reverted | Held transaction reversed | yes |
Skinslink sends POST requests to your webhook URL when trade statuses change.
Webhook-triggering statuses: hold, completed, failed, canceled, reverted
Statuses that do NOT trigger webhooks: new, pending, active
Payload:
{
"sign": "b64EncodedSHA256Signature==",
"status": "completed",
"trade_id": 178,
"trade_date": "2026-02-16T12:00:00Z",
"merchant_tx_id": "order-123",
"steam_id": "76561198338314767",
"offer_id": "6912345678",
"amount": 36.25,
"amount_currency": "usd",
"hold_end_date": null,
"fail_reason": null
}Signature verification:
sign = base64( sha256( trade_id + merchant_secret ) )GET /merchant/deposit/status to retrieve custom currency data for hold/completed trades.hold_end_date is included when status is hold. fail_reason is included when status is failed or canceled.200 OK quickly; process asynchronously.merchant_tx_id + status.Payload:
{
"sign": "b64EncodedSHA256Signature==",
"status": "completed",
"purchase_id": 178,
"trade_date": "2026-03-24T10:30:00Z",
"merchant_tx_id": "order-123",
"asset_id": "38029384123",
"offer_id": "6912345678",
"amount": 45.99,
"amount_currency": "usd",
"fail_reason": null
}Signature verification:
sign = base64( sha256( purchase_id + merchant_secret ) )purchase_id is an integer — convert to string before hashing.active status (trade offer sent to user). Statuses new and pending do not trigger notifications.fail_reason — string | null. Only present when status is failed.Error response: { "success": false, "message": "error description" }
Validation errors include field details:
{
"success": false,
"message": "validation error",
"data": [
{ "field": "InventoryRequest.game", "code": "required", "message": "game is a required field" }
]
}| HTTP Code | Meaning |
|---|---|
| 400 | Bad request / validation error |
| 401 | Missing or invalid API key |
| 403 | Merchant disabled or IP not whitelisted |
| 404 | Resource not found |
| 408 | Timeout (retry) |
| 409 | Duplicate merchant_tx_id |
| 500 | Internal error (retry) |
| 502 | Upstream service error (retry) |
When message is validation error, the data array may contain these domain-specific codes in addition to standard validation codes (required, len, oneof):
| Field | Code | Meaning |
|---|---|---|
merchant_tx_id | exist | Duplicate merchant_tx_id |
inventory | inventory_reload | Inventory data is stale — refetch before retrying |
token | trade_link_revoked | User reset their Steam trade URL |
partner | trade_link_invalid | Steam trade link is incorrect or expired |
partner | trade_banned | User's Steam account has a trade ban |
partner | profile_private | User's Steam profile is private |
partner | limited_account | Limited Steam account (hasn't spent $5 on Steam) |
partner | hold | Temporary Steam trade hold is active |
game | permissions | User's Steam inventory for this game is private |
partner | hold_and_permissions | Trade hold + game permission issues combined |
These codes apply to POST /merchant/create-intent, POST /merchant/create-deposit, POST /merchant/inventory, and POST /merchant/purchase. The code field is stable and safe for programmatic error handling.
POST /merchant/create-intent → get urlurlPOST /merchant/inventory → get items with pricesPOST /merchant/create-deposit with selected asset_ids → get trade offer infoGET /merchant/deposit/status for real-time trackingPOST /merchant/create-intent → get urlurl as iframe src inside your pagewindow.postMessage events to parent with { type: "skinslink:deposit-status", txId: string, status: string }new, active, hold, completed, canceled, failedGET /merchant/purchase/available?game=csgo → browse available itemsGET /merchant/purchase/search for specific items)POST /merchant/purchase with item details and Steam credentials → get purchase infoGET /merchant/purchase/status for real-time trackingPOST /merchant/get-prices with game + marketHashNames → get id, prices (5-minute quote window)POST /merchant/create-deposit-by-hash-name with id, merchant_tx_id, Steam credentials, and per-item {asset_id, name, min_price?} → get trade offer infoGET /merchant/deposit/status for real-time trackingUse this flow when you already know the item names and want a confirmed price quote (with optional per-item min_price floor) before committing.
| Action | Method | Endpoint |
|---|---|---|
| Create intent (redirect flow) | POST | /merchant/create-intent |
| Get inventory | POST | /merchant/inventory |
| Create deposit (API flow) | POST | /merchant/create-deposit |
| Get prices by hash name | POST | /merchant/get-prices |
| Create deposit by hash name | POST | /merchant/create-deposit-by-hash-name |
| Check status | GET | /merchant/deposit/status |
| Browse available items | GET | /merchant/purchase/available |
| Search items by name | GET | /merchant/purchase/search |
| Create purchase | POST | /merchant/purchase |
| Check purchase status | GET | /merchant/purchase/status |
| Purchase history | GET | /merchant/purchase |
Auth header: X-Api-Key: your-api-key
Games: csgo, rust, dota2, tf2