Skip to content

Skinslink API — LLM Reference

Single-page API reference optimized for LLMs, AI agents, and code generation tools. For full interactive docs, see the API Reference.

Overview

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


Endpoints

POST /merchant/create-intent

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):

FieldTypeRequiredDescription
merchant_tx_idstringyesYour unique order ID
gamestringnocsgo, rust, dota2, tf2
partnerintegernoSteam trade partner ID
tokenstringnoSteam trade token
result_urlstringnoWebhook URL override for this deposit
success_urlstringnoRedirect URL on success
fail_urlstringnoRedirect URL on failure
custom_currencystringnoCurrency code (1–4 chars). Requires all 3 currency fields
custom_currency_multipliernumbernoMultiplier (0.5–2.0)
custom_currency_ratenumbernoExchange rate (≥ 0.1)

Response data: { "id": int, "merchant_tx_id": string, "url": string }

Example:

bash
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"}'

POST /merchant/inventory

Fetches a user's Steam inventory with real-time pricing.

Request body (JSON):

FieldTypeRequiredDescription
gamestringyescsgo, rust, dota2, tf2
partnerintegeryesSteam trade partner ID
tokenstringyesSteam trade token (exactly 8 characters)

Response data:

json
{
  "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:

  • Cached responses: ~100–200ms. Fresh fetch: ~1–4s.
  • Prices are point-in-time; items are re-priced at deposit creation.
  • Use items[].id as asset_ids in create-deposit.

Example:

bash
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"}'

POST /merchant/create-deposit

Creates a deposit with selected Steam items. Returns trade offer details.

Request body (JSON):

FieldTypeRequiredDescription
merchant_tx_idstringyesYour unique order ID
gamestringyescsgo, rust, dota2, tf2
partnerintegeryesSteam trade partner ID
tokenstringyesSteam trade token
asset_idsstring[]yesItem IDs from inventory response
result_urlstringnoWebhook URL override for this deposit
success_urlstringnoRedirect URL on success
fail_urlstringnoRedirect URL on failure
custom_currencystringnoCurrency code (1–4 chars). Requires all 3 currency fields
custom_currency_multipliernumbernoMultiplier (0.5–2.0)
custom_currency_ratenumbernoExchange rate (≥ 0.1)

Response data:

json
{
  "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:

  • Status is active on success, failed on error.
  • bot_name, bot_steam_id, trade_offer_id may be null if the bot hasn't assigned yet.
  • Custom currency fields are not included in the create-deposit response. Use GET /merchant/deposit/status to retrieve them once the trade reaches hold or completed.

Example:

bash
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"]}'

GET /merchant/deposit/status

Retrieves current status of a deposit.

Query parameters:

FieldTypeRequiredDescription
idintegerone requiredInternal trade ID
merchant_tx_idstringone requiredYour order ID

At least one of id or merchant_tx_id must be provided.

Response data:

json
{
  "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",
  "custom_currency": "EUR",
  "custom_currency_multiplier": 1.0,
  "custom_currency_rate": 0.92,
  "custom_currency_sum": 33.35
}

Notes:

  • Custom currency fields only included when status is hold or completed.
  • For real-time updates, use webhooks instead of polling.

Example:

bash
curl "https://api.skinslink.com/api/v1/merchant/deposit/status?merchant_tx_id=order-123" \
  -H "X-Api-Key: your-api-key"

Purchase Endpoints

POST /merchant/purchase

Creates a skin purchase. Skinslink sends a trade offer with the requested item to the specified Steam account.

Request body (JSON):

FieldTypeRequiredDescription
partnerintegeryesSteam trade partner ID (minimum: 8)
tokenstringyesSteam trade token (exactly 8 characters)
gamestringyescsgo, rust, dota2, tf2
namestringconditionalItem market name. Provide either name or asset_id
asset_idstringconditionalSpecific asset ID. Provide either name or asset_id
merchant_tx_idstringnoYour unique order ID
max_pricenumbernoMaximum price you're willing to pay (USD)

Response data:

json
{
  "id": 178,
  "merchant_tx_id": "order-123",
  "status": "pending",
  "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/..."
  }
}

Fail reasons: insufficient_balance, price_changed, item_not_available, item_specified_price_not_found, provider_unavailable

Example:

bash
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"}'

GET /merchant/purchase/status

Retrieves current status of a purchase.

Query parameters:

FieldTypeRequiredDescription
idintegerone requiredPurchase ID
merchant_tx_idstringone requiredYour order ID

At least one of id or merchant_tx_id must be provided.

Response data: Same as POST /merchant/purchase response.

Example:

bash
curl "https://api.skinslink.com/api/v1/merchant/purchase/status?merchant_tx_id=order-123" \
  -H "X-Api-Key: your-api-key"

GET /merchant/purchase

Retrieves purchase history with pagination and filtering.

Query parameters:

FieldTypeRequiredDescription
limitintegernoItems per page
offsetintegernoPagination offset
statusstringnoFilter: new, pending, active, hold, completed, failed, canceled, reverted
date_rangeintegernoDays to look back: 1, 7, 30, 90, 365
searchstringnoSearch query (1-100 chars)
sortstringnoSort: id, -id, merchant_tx_id, -merchant_tx_id, status, -status, amount, -amount, created_at, -created_at

Response data: { "data": [PurchaseResponse, ...], "total": int }

Example:

bash
curl "https://api.skinslink.com/api/v1/merchant/purchase?limit=100&status=completed" \
  -H "X-Api-Key: your-api-key"

GET /merchant/purchase/available

Returns available items with purchase prices for a given game.

Query parameters:

FieldTypeRequiredDescription
gamestringyescsgo, rust, dota2, tf2
fullbooleannoWhen true, returns individual items with full details. Default returns items grouped by name

Response data (grouped, default):

json
{
  "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):

json
{
  "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/..."
    }
  ]
}

Notes:

  • Prices and availability are point-in-time; items are re-priced at purchase time.
  • Use items[].id or items[].name + game in POST /merchant/purchase.

Example:

bash
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:

FieldTypeRequiredDescription
gamestringyescsgo, rust, dota2, tf2
namesstring[]yesItem names (names=Item1&names=Item2)

Response data: Same format as GET /merchant/purchase/available standard response.

Example:

bash
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"

Transaction Status Machine

new → pending → active → completed
 |       |        |
 |       |        ├→ hold → completed
 |       |        |           |
 |       |        |           └→ reverted
 |       |        ├→ failed
 |       |        └→ canceled
 |       ├→ failed
 |       └→ canceled
 └→ canceled
StatusDescriptionTerminal
newCreated, not yet processedno
pendingAwaiting trade offer creationno
activeTrade offer sent, waiting for user to acceptno
holdItems on Steam 7-day trade holdno
completedSuccessful, items transferredyes
failedTransaction failedyes
canceledTransaction canceledyes
revertedHeld transaction reversedyes

Webhooks

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:

json
{
  "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"
}

Signature verification:

sign = base64( sha256( trade_id + merchant_secret ) )
  • Custom currency fields are not yet included in webhook payloads. Use GET /merchant/deposit/status to retrieve custom currency data for hold/completed trades.
  • Respond 200 OK quickly; process asynchronously.
  • Retries with exponential backoff on non-2xx responses.
  • Deduplicate using merchant_tx_id + status.

Purchase Webhooks

Payload:

json
{
  "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"
}

Signature verification:

sign = base64( sha256( purchase_id + merchant_secret ) )
  • purchase_id is an integer — convert to string before hashing.
  • Purchase webhooks always use your merchant-level webhook URL (no per-purchase override).
  • Same retry behavior and deduplication as deposit webhooks.

Error Handling

Error response: { "success": false, "message": "error description" }

Validation errors include field details:

json
{
  "success": false,
  "message": "validation error",
  "data": [
    { "field": "InventoryRequest.game", "code": "required", "message": "game is a required field" }
  ]
}
HTTP CodeMeaning
400Bad request / validation error
401Missing or invalid API key
403Merchant disabled or IP not whitelisted
404Resource not found
408Timeout (retry)
409Duplicate merchant_tx_id
500Internal error (retry)
502Upstream service error (retry)

Domain-Specific Validation Error Codes

When message is validation error, the data array may contain these domain-specific codes in addition to standard validation codes (required, len, oneof):

FieldCodeMeaning
merchant_tx_idexistDuplicate merchant_tx_id
inventoryinventory_reloadInventory data is stale — refetch before retrying
tokentrade_link_revokedUser reset their Steam trade URL
partnertrade_link_invalidSteam trade link is incorrect or expired
partnertrade_bannedUser's Steam account has a trade ban
partnerprofile_privateUser's Steam profile is private
partnerlimited_accountLimited Steam account (hasn't spent $5 on Steam)
partnerholdTemporary Steam trade hold is active
gamepermissionsUser's Steam inventory for this game is private
partnerhold_and_permissionsTrade 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.


Integration Flows

Flow 1: Redirect (with UI)

  1. POST /merchant/create-intent → get url
  2. Redirect user to url
  3. User selects items and confirms on Skinslink's page
  4. Receive webhook with final status

Flow 2: API-only (without UI)

  1. POST /merchant/inventory → get items with prices
  2. User selects items on your UI
  3. POST /merchant/create-deposit with selected asset_ids → get trade offer info
  4. User accepts Steam trade offer
  5. Receive webhook with final status
  6. Optionally poll GET /merchant/deposit/status for real-time tracking

Flow 3: Iframe

  1. POST /merchant/create-intent → get url
  2. Load url as iframe src inside your page
  3. User selects items and confirms trade inside the iframe
  4. Iframe sends window.postMessage events to parent with { type: "skinslink:deposit-status", txId: string, status: string }
  5. Statuses: new, active, hold, completed, canceled, failed
  6. Use PostMessage for real-time UI updates; rely on server-side webhooks for balance crediting

Flow 4: Purchase

  1. GET /merchant/purchase/available?game=csgo → browse available items
  2. User selects an item on your UI (or use GET /merchant/purchase/search for specific items)
  3. POST /merchant/purchase with item details and Steam credentials → get purchase info
  4. User accepts the Steam trade offer
  5. Receive webhook with final status
  6. Optionally poll GET /merchant/purchase/status for real-time tracking

Quick Reference

ActionMethodEndpoint
Create intent (redirect flow)POST/merchant/create-intent
Get inventoryPOST/merchant/inventory
Create deposit (API flow)POST/merchant/create-deposit
Check statusGET/merchant/deposit/status
Browse available itemsGET/merchant/purchase/available
Search items by nameGET/merchant/purchase/search
Create purchasePOST/merchant/purchase
Check purchase statusGET/merchant/purchase/status
Purchase historyGET/merchant/purchase

Auth header: X-Api-Key: your-api-key

Games: csgo, rust, dota2, tf2