Skip to main content
POST
/
api
/
v1
/
vm
/
buy
/
init
Start a purchase
curl --request POST \
  --url https://api.example.com/api/v1/vm/buy/init \
  --header 'Content-Type: application/json' \
  --data '
{
  "id": "<string>",
  "amount": 123,
  "user_id": "<string>"
}
'
{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "nfts": [
    {
      "id": "9XnY...mint_address",
      "content": {
        "metadata": {
          "name": "Juan Soto RC Auto /25",
          "image": "https://cdn.phygitals.com/cards/soto-rc-auto.png",
          "back_image": "https://cdn.phygitals.com/cards/soto-rc-auto-back.png",
          "attributes": [
            { "trait_type": "Year", "value": "2024" },
            { "trait_type": "Category", "value": "Baseball" }
          ]
        }
      },
      "buyback_price": 8.50
    }
  ]
}
Initiates a purchase from a pack. Returns a session_id that you pass to /api/v1/vm/buy/status to poll for the pulled items.
Prerequisites: The pack must have in_stock: true and enable: true. amount must be between 1 and the pack’s max_per_mint.

Request body

id
string
required
Pack ID from /api/v1/vm/available.
amount
number
required
Number of pulls. Must be ≥ 1 and ≤ max_per_mint.
user_id
string
required
Partner-defined identifier for the end user making the purchase. Pulled items are associated with this user_id for inventory lookup, sellback, and shipping.

Example request

POST /api/v1/vm/buy/init
X-API-Key: <your_api_key>
Content-Type: application/json

{
  "id": "BSG6Dy...",
  "amount": 2,
  "user_id": "user_abc123"
}

Response

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000",
  "nfts": [
    {
      "id": "9XnY...mint_address",
      "content": {
        "metadata": {
          "name": "Juan Soto RC Auto /25",
          "image": "https://cdn.phygitals.com/cards/soto-rc-auto.png",
          "back_image": "https://cdn.phygitals.com/cards/soto-rc-auto-back.png",
          "attributes": [
            { "trait_type": "Year", "value": "2024" },
            { "trait_type": "Category", "value": "Baseball" }
          ]
        }
      },
      "buyback_price": 8.50
    }
  ]
}
session_id
string
Unique session identifier. Pass to /api/v1/vm/buy/status to poll for fulfillment.
nfts
array
Array of pulled items.
nfts[].id
string
Item identifier. Used as item_id in /api/v1/vm/buyback.
nfts[].content.metadata
object
Item metadata: name, image, back_image, and attributes.
nfts[].content.metadata.back_image
string | null
CDN URL for the card back image, or null when not available.
nfts[].buyback_price
number
The sellback value in USD.
nfts[].type
string
Item source. One of: enft, ebay, fanatics, alt, external.
nfts[].mint_address
string | null
On-chain mint address. null for items that haven’t been minted (in sandbox, always null for ebay-sourced items).
nfts[].collection_address
string | null
On-chain collection address.
nfts[].token_standard
string | null
Token standard for on-chain items.
See the item shape reference for the full canonical schema.

Errors

StatusBodyCause
400{ "error": "Claw machine is out of stock" }Pack is not currently purchasable. See note below.
400{ "error": "Amount must be greater than 0" }Invalid amount
400{ "error": "Amount must be less than or equal to N" }Exceeds max_per_mint
400{ "error": "VM not found" }Unknown pack ID
400{ "error": "user_id is required" }Missing user_id
500{ "error": "Error during transaction" }Internal server error
Claw machine is out of stock is returned when the pack is not currently purchasable. In sandbox, this single error covers three distinct underlying conditions: enable: false, in_stock: false, or no candidate listings available in any rarity tier at request time. Production may differentiate these with distinct messages in the future. Partners should treat any “out of stock” 400 as terminal for this pack and re-fetch /api/v1/vm/available before retrying.

Sandbox notes

In sandbox, item selection is Math.random()-weighted across the pack’s rarity_distribution.weight field, then a uniform random pick within the chosen tier’s FMV range. Items are not reserved or removed from inventory. The same listing can be returned to other user_ids on subsequent calls. Sandbox buy/init also fulfills synchronously, so the items are already pulled by the time the response arrives. Calling buy/init twice with the same body produces two distinct session_ids and stacks the items.