# Create Steam offer

`POST /v2/merchant/create-steam-offer`

Create a Steam offer for user using **ONE OF** `deposit_id` **OR** `transaction_id`. 

You can create a deposit without items and call this method later to create a Steam offer.

You have 15 minutes after creation a deposit to create a Steam offer. You can't create multiple Steam offers for one deposit.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `api` | query | string | required | Your [WAXPEER API](https://waxpeer.com/profile/user) |

## Request body

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `merchant` | string | required | Your merchant name |
| `deposit_id` | string | optional | Your unique custom deposit ID (string, max 50 characters) |
| `transaction_id` | integer | optional | Transaction ID |
| `steam_id` | string | required | Steam ID (17 digits) |
| `trade_url_token` | string | required | Trade URL token (8 characters) |
| `game` | enum | required | Game type |
| `items` | array<string> | required | List of item IDs |

```json
{
  "merchant": "mymerchant",
  "deposit_id": "123456asd",
  "transaction_id": 123456,
  "steam_id": "76561198000000000",
  "trade_url_token": "abcdefgh",
  "game": "csgo",
  "items": [
    "123",
    "456",
    "789"
  ]
}
```

## Example (curl)

```bash
curl -X POST 'https://api.waxpeer.com/v2/merchant/create-steam-offer?api=%7B%7BAPI_KEY%7D%7D' \
  -H 'Content-Type: application/json' \
  -d '{
  "merchant": "mymerchant",
  "deposit_id": "123456asd",
  "transaction_id": 123456,
  "steam_id": "76561198000000000",
  "trade_url_token": "abcdefgh",
  "game": "csgo",
  "items": [
    "123",
    "456",
    "789"
  ]
}'
```

## Example response

```json
{
  "status": "success",
  "url": "https://pay.waxpeer.com/merchant/mymerchant?hash=7USFcwzEvgxs6l2u3ow4IQxlgJBYEZZt",
  "transaction_id": 123456,
  "hash": "7USFcwzEvgxs6l2u3ow4IQxlgJBYEZZt",
  "listed": [
    {
      "name": "AWP | Asiimov (Field-tested)",
      "item_id": "141414144",
      "price": 1000
    }
  ],
  "failed": [
    {
      "item_id": "141414145",
      "price": 1000,
      "name": "AWP | Asiimov (Field-tested)",
      "error_message": "item_not_acceptable"
    }
  ]
}
```

## Responses

- `200` **Please open the schema to see the response structure, fields and their descriptions**

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `status` | string | required |  |
| `url` | string | required | Redirect URL for the deposit. Redirect the user to this URL to complete the deposit if you are using a redirect for the deposit process. |
| `transaction_id` | integer | required | Transaction ID of the deposit |
| `hash` | string | required | Hash identifier (Used for tracking the deposit on redirect or widget) |
| `listed` | array<object> | required | List of successfully listed items (One trade will be created with these items) |
| `listed.name` | string | optional | Steam item name |
| `listed.item_id` | string | optional | Steam item_id (asset id) from user inventory |
| `listed.price` | number | optional | Price of an item (1000 = 1$) |
| `failed` | array<object> | required | List of items that failed to list (Trade will be without these items. Count them as canceled) |
| `failed.item_id` | string | optional | Steam item_id (asset id) from user inventory |
| `failed.price` | number | optional | Price of an item (1000 = 1$) |
| `failed.name` | string | optional | Steam item name |
| `failed.error_message` | string | optional | Error message |


## Notes for agents

- Auth is the query parameter `api`, not an Authorization header.
- See [/statuses.md](/statuses.md) for numeric trade status plus `escrow_status` / `release_date`.
- Prefer GET /v2/search-items-by-name over v1.
- Prefer GET /v2/get-items-list over v1 (cursor keyset pagination without the 5000 row cap). Pass next_cursor only while has_more is true.
- Prefer POST /v2/my-history over v1 (faster on long histories, ordered by trade id). On buy rows, price is the amount you paid.
- Trade-locked listings are omitted unless you pass include_hold=1. They then include unlock_at and send_until (RFC 3339 UTC).
- Buy a trade-locked listing only by exact item_id with allow_trade_locked (query 1 on GET /v1/buy-one-p2p, body true on POST /v1/buy). GET /v1/buy-one-p2p-name never sells hold items.
- CSV snapshot: GET /v1/prices/snapshot?format=csv (gzip). include_hold appends unlock_at,send_until. compact and whitemarket are JSON-only.
- Do not use GET /v1/ready-to-transfer-p2p; use the [trade websocket](/websocket.md).
