Skip to content

Sell API

Sell your Steam items to VIP buyers through the matching engine. The sell flow is a two-step process: first match your items against active buy orders, then create a trade with the matched buyer. Use the tracking endpoints to monitor trade progress.

Base path: /api/sell

Match Items

POST /api/sell/match

Match your inventory items against active buy orders. Returns matched prices and the buyer ID. Use this before creating a trade to verify which items have demand and at what price.

Request Body

FieldTypeRequiredDescription
game_idnumberYesGame ID (730, 570, 252490, 440)
itemsarrayYesArray of items to match (min 1)
items[].market_hash_namestringYesSteam market hash name
items[].amountnumberNoQuantity to match. Default: 1
bash
curl -X POST "https://market.vpsbot.io/api/sell/match" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "game_id": 730,
    "items": [
      { "market_hash_name": "AK-47 | Redline (Field-Tested)", "amount": 2 },
      { "market_hash_name": "AWP | Asiimov (Field-Tested)", "amount": 1 }
    ]
  }'
js
const { data } = await client.post('/sell/match', {
  game_id: 730,
  items: [
    { market_hash_name: 'AK-47 | Redline (Field-Tested)', amount: 2 },
    { market_hash_name: 'AWP | Asiimov (Field-Tested)', amount: 1 }
  ]
});

Example Response

json
{
  "success": true,
  "data": {
    "buyer_id": "76561198012345678",
    "items": [
      {
        "market_hash_name": "AK-47 | Redline (Field-Tested)",
        "price": 14500,
        "amount": 2
      },
      {
        "market_hash_name": "AWP | Asiimov (Field-Tested)",
        "price": 32000,
        "amount": 1
      }
    ]
  }
}

TIP

Items with price: 0 have no matching buy order. Only items with a non-zero price can be sold.

Response Fields

FieldTypeDescription
successbooleanWhether the request succeeded
data.buyer_idstringMatched VIP buyer's identifier. Pass this to /sell/trades/create
data.itemsarrayItems with matched prices
data.items[].market_hash_namestringSteam market hash name
data.items[].pricenumberMatched buy order price (1$ = 1000) (0 = no match)
data.items[].amountnumberMatched quantity
data.items[].errorstringError message if item could not be resolved

Create Trade

POST /api/sell/trades/create

Create a sell trade with a matched buyer. This freezes the buyer's balance, assigns a bot, and sends a Steam trade offer to collect your items.

WARNING

You must call /api/sell/match first to obtain the buyer_id and verify item prices. The buyer_id and item prices must match current buy orders, otherwise the request will be rejected.

Request Body

FieldTypeRequiredDescription
custom_idstringYesYour unique trade identifier (used for idempotency)
buyer_idstringYesBuyer ID returned from /api/sell/match
tradelinkstringYesYour Steam trade offer URL
game_idnumberYesGame ID (730, 570, 252490, 440)
itemsarrayYesArray of items to sell (min 1)
items[].assetidstringYesSteam asset ID of the item
items[].market_hash_namestringYesSteam market hash name
items[].pricenumberYesSale price (1$ = 1000) (must not exceed buy order price)
items[].contextidstringNoSteam context ID. Default: "2"
messagestringNoOptional message to include in the trade offer
bash
curl -X POST "https://market.vpsbot.io/api/sell/trades/create" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "custom_id": "sell-001",
    "buyer_id": "76561198012345678",
    "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
    "game_id": 730,
    "items": [
      {
        "assetid": "38291847562",
        "market_hash_name": "AK-47 | Redline (Field-Tested)",
        "price": 14500
      },
      {
        "assetid": "49382716453",
        "market_hash_name": "AK-47 | Redline (Field-Tested)",
        "price": 14500
      },
      {
        "assetid": "27461938274",
        "market_hash_name": "AWP | Asiimov (Field-Tested)",
        "price": 32000
      }
    ]
  }'
js
const { data } = await client.post('/sell/trades/create', {
  custom_id: 'sell-001',
  buyer_id: '76561198012345678',
  tradelink: 'https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY',
  game_id: 730,
  items: [
    { assetid: '38291847562', market_hash_name: 'AK-47 | Redline (Field-Tested)', price: 14500 },
    { assetid: '49382716453', market_hash_name: 'AK-47 | Redline (Field-Tested)', price: 14500 },
    { assetid: '27461938274', market_hash_name: 'AWP | Asiimov (Field-Tested)', price: 32000 }
  ]
});

Success Response (201)

json
{
  "success": true,
  "data": {
    "trade_id": "a1b2c3d4-...",
    "custom_id": "sell-001",
    "summary": {
      "items_count": 3,
      "total_value": 61000
    },
    "processed_trade": {
      "id": "a1b2c3d4-...",
      "status": "PENDING"
    },
    "selected_bot": {
      "steamid64": "76561198999999999",
      "avatar": "https://avatars.steamstatic.com/...",
      "profile_name": "VPSBot #12"
    },
    "status": "PENDING"
  }
}

Response Fields

FieldTypeDescription
successbooleanWhether the trade was created
data.trade_idstringMarket trade UUID
data.custom_idstringYour custom ID echoed back
data.summaryobjectTrade summary
data.summary.items_countnumberNumber of items in the trade
data.summary.total_valuenumberTotal trade value (1$ = 1000)
data.processed_tradeobjectProcessed trade details
data.processed_trade.idstringInternal trade UUID
data.processed_trade.statusstringInitial trade status (PENDING)
data.selected_botobjectThe bot that will send the trade offer
data.selected_bot.steamid64stringBot's Steam ID
data.selected_bot.avatarstringBot's avatar URL
data.selected_bot.profile_namestringBot's display name
data.statusstringTrade status (PENDING)

List Trades

GET /api/sell/trades

Retrieve a paginated list of your sell trades with optional filtering and sorting.

Query Parameters

ParameterTypeRequiredDescription
game_idnumberNoFilter by game ID (730, 570, 252490, 440)
statusstringNoFilter by trade status
date_fromstringNoFilter trades created after this date (ISO 8601)
date_tostringNoFilter trades created before this date (ISO 8601)
price_minnumberNoMinimum trade value (1$ = 1000)
price_maxnumberNoMaximum trade value (1$ = 1000)
custom_idstringNoFilter by your custom trade ID
sort_bystringNoSort field (e.g. created_at, purchase_price)
sort_directionstringNoSort direction: asc or desc
limitnumberNoNumber of results per page. Default: 20
offsetnumberNoNumber of results to skip. Default: 0
bash
curl "https://market.vpsbot.io/api/sell/trades?game_id=730&status=Accepted&limit=10&offset=0" \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades', {
  params: { game_id: 730, status: 'Accepted', limit: 10, offset: 0 }
});

Example Response

json
{
  "success": true,
  "data": {
    "trades": [
      {
        "id": "a1b2c3d4-...",
        "bot_login": "vpsbot12",
        "custom_id": "sell-001",
        "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
        "status": "Accepted",
        "error": null,
        "created_at": "2026-03-13T10:00:00Z",
        "updated_at": "2026-03-13T10:05:00Z",
        "bot_profile_name": "VPSBot #12",
        "bot_avatar": "https://avatars.steamstatic.com/...",
        "purchase_room_title": "Room A",
        "purchase_room_id": "room-uuid",
        "game_id": 730,
        "purchase_price": 61000,
        "items_count": 3,
        "trade_status": "Completed",
        "rollback_side": null
      }
    ],
    "total": 1,
    "limit": 10,
    "offset": 0
  }
}

Response Fields

FieldTypeDescription
data.tradesarrayList of trades
data.trades[].idstringMarket trade UUID
data.trades[].bot_loginstringBot login name
data.trades[].custom_idstringYour custom trade ID
data.trades[].tradelinkstringSteam trade offer URL
data.trades[].statusstringTrade status
data.trades[].errorstring | nullError message if trade failed
data.trades[].created_atstringTrade creation timestamp (ISO 8601)
data.trades[].updated_atstringLast update timestamp (ISO 8601)
data.trades[].bot_profile_namestringBot's display name
data.trades[].bot_avatarstringBot's avatar URL
data.trades[].purchase_room_titlestringPurchase room name
data.trades[].purchase_room_idstringPurchase room UUID
data.trades[].game_idnumberGame ID
data.trades[].purchase_pricenumberTotal trade value (1$ = 1000)
data.trades[].items_countnumberNumber of items in the trade
data.trades[].trade_statusstringSteam trade status
data.trades[].rollback_sidestring | nullRollback side if applicable
data.totalnumberTotal number of matching trades
data.limitnumberPage size
data.offsetnumberCurrent offset

Trade Dashboard

GET /api/sell/trades/dashboard

Get aggregated statistics for your sell trades.

Query Parameters

ParameterTypeRequiredDescription
game_idnumberNoFilter stats by game ID
bash
curl "https://market.vpsbot.io/api/sell/trades/dashboard?game_id=730" \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades/dashboard', {
  params: { game_id: 730 }
});

Example Response

json
{
  "success": true,
  "data": {
    "trades_count": 150,
    "accepted_count": 120,
    "processing_count": 5,
    "failed_count": 10,
    "rolledback_count": 15,
    "items_count": 450,
    "total_value": 6750000,
    "success_rate": 80.0
  }
}

Response Fields

FieldTypeDescription
data.trades_countnumberTotal number of trades
data.accepted_countnumberSuccessfully completed trades
data.processing_countnumberCurrently processing trades
data.failed_countnumberFailed trades
data.rolledback_countnumberRolled back trades
data.items_countnumberTotal items across all trades
data.total_valuenumberTotal value of all trades (1$ = 1000)
data.success_ratenumberPercentage of successful trades

Get Trade by Custom ID

GET /api/sell/trades/by-custom-id/{custom_id}

Look up a trade using your custom identifier.

Path Parameters

ParameterTypeDescription
custom_idstringYour custom trade ID
bash
curl "https://market.vpsbot.io/api/sell/trades/by-custom-id/sell-001" \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades/by-custom-id/sell-001');

Example Response

json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-...",
    "bot_login": "vpsbot12",
    "custom_id": "sell-001",
    "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
    "status": "Accepted",
    "error": null,
    "created_at": "2026-03-13T10:00:00Z",
    "updated_at": "2026-03-13T10:05:00Z",
    "bot_profile_name": "VPSBot #12",
    "bot_avatar": "https://avatars.steamstatic.com/...",
    "purchase_room_title": "Room A",
    "purchase_room_id": "room-uuid",
    "game_id": 730,
    "purchase_price": 61000,
    "items_count": 3,
    "trade_status": "Completed",
    "rollback_side": null
  }
}

Response Fields

Same as individual trade object in List Trades.


Get Trade by Steam Tradeoffer ID

GET /api/sell/trades/by-steam-tradeoffer-id/{tradeoffer_id}

Look up a trade using the Steam trade offer ID.

Path Parameters

ParameterTypeDescription
tradeoffer_idstringSteam trade offer ID
bash
curl "https://market.vpsbot.io/api/sell/trades/by-steam-tradeoffer-id/5234567890" \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades/by-steam-tradeoffer-id/5234567890');

Example Response

json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-...",
    "bot_login": "vpsbot12",
    "custom_id": "sell-001",
    "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
    "status": "Accepted",
    "error": null,
    "created_at": "2026-03-13T10:00:00Z",
    "updated_at": "2026-03-13T10:05:00Z",
    "bot_profile_name": "VPSBot #12",
    "bot_avatar": "https://avatars.steamstatic.com/...",
    "purchase_room_title": "Room A",
    "purchase_room_id": "room-uuid",
    "game_id": 730,
    "purchase_price": 61000,
    "items_count": 3,
    "trade_status": "Completed",
    "rollback_side": null
  }
}

Response Fields

Same as individual trade object in List Trades.


Get Trade by Steam Trade ID

GET /api/sell/trades/by-steam-trade-id/{trade_id}

Look up a trade using the Steam trade ID. Only available for trades with status Accepted or RolledBack.

Path Parameters

ParameterTypeDescription
trade_idstringSteam trade ID
bash
curl "https://market.vpsbot.io/api/sell/trades/by-steam-trade-id/4012345678" \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades/by-steam-trade-id/4012345678');

Example Response

json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-...",
    "bot_login": "vpsbot12",
    "custom_id": "sell-001",
    "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
    "status": "Accepted",
    "error": null,
    "created_at": "2026-03-13T10:00:00Z",
    "updated_at": "2026-03-13T10:05:00Z",
    "bot_profile_name": "VPSBot #12",
    "bot_avatar": "https://avatars.steamstatic.com/...",
    "purchase_room_title": "Room A",
    "purchase_room_id": "room-uuid",
    "game_id": 730,
    "purchase_price": 61000,
    "items_count": 3,
    "trade_status": "Completed",
    "rollback_side": null
  }
}

Response Fields

Same as individual trade object in List Trades.


Get Trade by ID

GET /api/sell/trades/by-id/{id}

Look up a trade using its market trade UUID.

Path Parameters

ParameterTypeDescription
idstringMarket trade UUID
bash
curl "https://market.vpsbot.io/api/sell/trades/by-id/a1b2c3d4-..." \
  -H "x-api-key: YOUR_API_KEY"
js
const { data } = await client.get('/sell/trades/by-id/a1b2c3d4-...');

Example Response

json
{
  "success": true,
  "data": {
    "id": "a1b2c3d4-...",
    "bot_login": "vpsbot12",
    "custom_id": "sell-001",
    "tradelink": "https://steamcommunity.com/tradeoffer/new/?partner=XXXXX&token=YYYYY",
    "status": "Accepted",
    "error": null,
    "created_at": "2026-03-13T10:00:00Z",
    "updated_at": "2026-03-13T10:05:00Z",
    "bot_profile_name": "VPSBot #12",
    "bot_avatar": "https://avatars.steamstatic.com/...",
    "purchase_room_title": "Room A",
    "purchase_room_id": "room-uuid",
    "game_id": 730,
    "purchase_price": 61000,
    "items_count": 3,
    "trade_status": "Completed",
    "rollback_side": null
  }
}

Response Fields

Same as individual trade object in List Trades.


Error Responses

All endpoints return errors in a consistent format:

json
{
  "success": false,
  "error": "Error description"
}

Match Errors

HTTP StatusErrorDescription
400Invalid request bodyMalformed JSON or missing required fields

Create Trade Errors

HTTP StatusErrorDescription
400Invalid request bodyMalformed JSON or missing required fields
400Buyer mismatchThe buyer_id doesn't match the current best buyer for these items
400No buy order found for item: ...An item has no matching buy order
400Item ... price exceeds buy order priceRequested price is higher than the active buy order
400Trade value must be positiveTotal trade value is zero or negative
400Insufficient balanceBuyer doesn't have enough balance
400No suitable purchase room foundNo purchase room matches the trade value
400No suitable bot foundNo available bot for this trade
400Game not supportedThe game_id is not supported
409A trade with this custom_id already existsDuplicate custom_id (idempotency check)
500Internal errorServer-side failure

Trade Lookup Errors

HTTP StatusErrorDescription
404Trade not foundNo trade found with the given identifier

Sell Flow Overview

  1. Match - Call POST /api/sell/match with your items to get prices and a buyer_id
  2. Review - Check which items have price > 0 (matched with a buy order)
  3. Create Trade - Call POST /api/sell/trades/create with the buyer_id, your items' asset IDs, and prices
  4. Accept Trade - A bot will send you a Steam trade offer. Accept it to complete the sale
  5. Track Trade - Use the trade lookup endpoints to monitor trade status (e.g. GET /api/sell/trades/by-custom-id/{custom_id})
  6. Settlement - Once the trade is confirmed on Steam, the buyer's balance is deducted

Idempotency

The custom_id field acts as an idempotency key. If you retry with the same custom_id, you'll get a 409 Conflict instead of a duplicate trade.

Need help? Contact our support team