Appearance
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
| Field | Type | Required | Description |
|---|---|---|---|
game_id | number | Yes | Game ID (730, 570, 252490, 440) |
items | array | Yes | Array of items to match (min 1) |
items[].market_hash_name | string | Yes | Steam market hash name |
items[].amount | number | No | Quantity 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
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the request succeeded |
data.buyer_id | string | Matched VIP buyer's identifier. Pass this to /sell/trades/create |
data.items | array | Items with matched prices |
data.items[].market_hash_name | string | Steam market hash name |
data.items[].price | number | Matched buy order price (1$ = 1000) (0 = no match) |
data.items[].amount | number | Matched quantity |
data.items[].error | string | Error 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
| Field | Type | Required | Description |
|---|---|---|---|
custom_id | string | Yes | Your unique trade identifier (used for idempotency) |
buyer_id | string | Yes | Buyer ID returned from /api/sell/match |
tradelink | string | Yes | Your Steam trade offer URL |
game_id | number | Yes | Game ID (730, 570, 252490, 440) |
items | array | Yes | Array of items to sell (min 1) |
items[].assetid | string | Yes | Steam asset ID of the item |
items[].market_hash_name | string | Yes | Steam market hash name |
items[].price | number | Yes | Sale price (1$ = 1000) (must not exceed buy order price) |
items[].contextid | string | No | Steam context ID. Default: "2" |
message | string | No | Optional 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
| Field | Type | Description |
|---|---|---|
success | boolean | Whether the trade was created |
data.trade_id | string | Market trade UUID |
data.custom_id | string | Your custom ID echoed back |
data.summary | object | Trade summary |
data.summary.items_count | number | Number of items in the trade |
data.summary.total_value | number | Total trade value (1$ = 1000) |
data.processed_trade | object | Processed trade details |
data.processed_trade.id | string | Internal trade UUID |
data.processed_trade.status | string | Initial trade status (PENDING) |
data.selected_bot | object | The bot that will send the trade offer |
data.selected_bot.steamid64 | string | Bot's Steam ID |
data.selected_bot.avatar | string | Bot's avatar URL |
data.selected_bot.profile_name | string | Bot's display name |
data.status | string | Trade status (PENDING) |
List Trades
GET /api/sell/trades
Retrieve a paginated list of your sell trades with optional filtering and sorting.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
game_id | number | No | Filter by game ID (730, 570, 252490, 440) |
status | string | No | Filter by trade status |
date_from | string | No | Filter trades created after this date (ISO 8601) |
date_to | string | No | Filter trades created before this date (ISO 8601) |
price_min | number | No | Minimum trade value (1$ = 1000) |
price_max | number | No | Maximum trade value (1$ = 1000) |
custom_id | string | No | Filter by your custom trade ID |
sort_by | string | No | Sort field (e.g. created_at, purchase_price) |
sort_direction | string | No | Sort direction: asc or desc |
limit | number | No | Number of results per page. Default: 20 |
offset | number | No | Number 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
| Field | Type | Description |
|---|---|---|
data.trades | array | List of trades |
data.trades[].id | string | Market trade UUID |
data.trades[].bot_login | string | Bot login name |
data.trades[].custom_id | string | Your custom trade ID |
data.trades[].tradelink | string | Steam trade offer URL |
data.trades[].status | string | Trade status |
data.trades[].error | string | null | Error message if trade failed |
data.trades[].created_at | string | Trade creation timestamp (ISO 8601) |
data.trades[].updated_at | string | Last update timestamp (ISO 8601) |
data.trades[].bot_profile_name | string | Bot's display name |
data.trades[].bot_avatar | string | Bot's avatar URL |
data.trades[].purchase_room_title | string | Purchase room name |
data.trades[].purchase_room_id | string | Purchase room UUID |
data.trades[].game_id | number | Game ID |
data.trades[].purchase_price | number | Total trade value (1$ = 1000) |
data.trades[].items_count | number | Number of items in the trade |
data.trades[].trade_status | string | Steam trade status |
data.trades[].rollback_side | string | null | Rollback side if applicable |
data.total | number | Total number of matching trades |
data.limit | number | Page size |
data.offset | number | Current offset |
Trade Dashboard
GET /api/sell/trades/dashboard
Get aggregated statistics for your sell trades.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
game_id | number | No | Filter 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
| Field | Type | Description |
|---|---|---|
data.trades_count | number | Total number of trades |
data.accepted_count | number | Successfully completed trades |
data.processing_count | number | Currently processing trades |
data.failed_count | number | Failed trades |
data.rolledback_count | number | Rolled back trades |
data.items_count | number | Total items across all trades |
data.total_value | number | Total value of all trades (1$ = 1000) |
data.success_rate | number | Percentage 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
| Parameter | Type | Description |
|---|---|---|
custom_id | string | Your 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
| Parameter | Type | Description |
|---|---|---|
tradeoffer_id | string | Steam 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
| Parameter | Type | Description |
|---|---|---|
trade_id | string | Steam 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
| Parameter | Type | Description |
|---|---|---|
id | string | Market 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 Status | Error | Description |
|---|---|---|
| 400 | Invalid request body | Malformed JSON or missing required fields |
Create Trade Errors
| HTTP Status | Error | Description |
|---|---|---|
| 400 | Invalid request body | Malformed JSON or missing required fields |
| 400 | Buyer mismatch | The buyer_id doesn't match the current best buyer for these items |
| 400 | No buy order found for item: ... | An item has no matching buy order |
| 400 | Item ... price exceeds buy order price | Requested price is higher than the active buy order |
| 400 | Trade value must be positive | Total trade value is zero or negative |
| 400 | Insufficient balance | Buyer doesn't have enough balance |
| 400 | No suitable purchase room found | No purchase room matches the trade value |
| 400 | No suitable bot found | No available bot for this trade |
| 400 | Game not supported | The game_id is not supported |
| 409 | A trade with this custom_id already exists | Duplicate custom_id (idempotency check) |
| 500 | Internal error | Server-side failure |
Trade Lookup Errors
| HTTP Status | Error | Description |
|---|---|---|
| 404 | Trade not found | No trade found with the given identifier |
Sell Flow Overview
- Match - Call
POST /api/sell/matchwith your items to get prices and abuyer_id - Review - Check which items have
price > 0(matched with a buy order) - Create Trade - Call
POST /api/sell/trades/createwith thebuyer_id, your items' asset IDs, and prices - Accept Trade - A bot will send you a Steam trade offer. Accept it to complete the sale
- Track Trade - Use the trade lookup endpoints to monitor trade status (e.g.
GET /api/sell/trades/by-custom-id/{custom_id}) - 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.