Skip to main content
POST
/
api
/
vm
/
buy
/
crypto
Buy with crypto
curl --request POST \
  --url https://api.example.com/api/vm/buy/crypto \
  --header 'Content-Type: application/json' \
  --data '
{
  "claw_id": "<string>",
  "amount": 123,
  "currency": "<string>",
  "chain": "<string>",
  "txs": [
    {}
  ],
  "voucher_id": "<string>",
  "permit_data": {},
  "buyer_wallet": "<string>",
  "extraData": {}
}
'
{
  "result": {
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": "did:privy:abc123",
    "public_id": "_a1b2c3d4",
    "total": 25.00,
    "tx_hash": "5Kn8...bundle_signature",
    "nfts": [
      {
        "id": "9XnY...mint_address",
        "type": "enft",
        "buyback_price": 21.25,
        "content": {
          "metadata": {
            "name": "2024 Juan Soto RC Auto /25",
            "image": "https://cdn.phygitals.com/cards/example.png"
          }
        }
      }
    ]
  }
}
Submits a crypto payment for one or more claw pulls. You build and sign the on-chain payment transaction client-side, then send it to Phygitals for co-signing, bundling, and fulfillment.
Scope required: vm.buy.crypto. See authentication for how to send your key.
This endpoint is rate-limited to 1 request per 60 seconds per API key.

Prerequisites

  1. A user API key with the vm.buy.crypto scope
  2. A linked external Solana wallet with sufficient USDC or USDT
  3. Pack details from GET /api/vm/available — note the pack id and mint_price
  4. Signer public keys from POST /api/orpc/config/signers/pubkeys (no authentication required) to construct valid transactions

Request body

claw_id
string
required
Pack ID (mint address) from /api/vm/available.
amount
integer
required
Number of pulls. Must be a positive integer.
currency
string
required
Payment token. Supported values depend on chain — for Solana: usdc, usdt.
chain
string
required
Payment chain. For example solana or an EVM chain slug supported by the pack.
txs
array
required
Array of serialized, signed payment transactions. Each entry is a byte array (JSON) or base64 string. On Solana, the buyer wallet must be a signer on the payment transaction.
voucher_id
string
Optional voucher ID or code. When provided, the payment transfer may be skipped if the voucher covers the purchase.
permit_data
object
Required for paid EVM purchases. ERC-20 permit signature authorizing the payment token transfer.
buyer_wallet
string
API key requests only. Solana or EVM address that pays for and receives the items. When omitted, your account’s primary linked wallet is used. The wallet must sign the payment transaction. Vouchers attached to your account remain yours to spend regardless of which buyer_wallet you specify.
extraData
object
Optional metadata attached to the purchase session.

Example request

POST /api/vm/buy/crypto
X-API-Key: phy_your_secret_key
Content-Type: application/json

{
  "claw_id": "BSG6DyEihFFtfvxtL9mKYsvTwiZXB1rq5gARMTJC2xAM",
  "amount": 1,
  "currency": "usdc",
  "chain": "solana",
  "txs": [[/* signed VersionedTransaction bytes */]]
}

Response

On success the API returns the fulfilled purchase. If fulfillment is still in progress, the response includes a session_id — poll POST /api/vm/buy/status until items are ready.
{
  "result": {
    "session_id": "550e8400-e29b-41d4-a716-446655440000",
    "user_id": "did:privy:abc123",
    "public_id": "_a1b2c3d4",
    "total": 25.00,
    "tx_hash": "5Kn8...bundle_signature",
    "nfts": [
      {
        "id": "9XnY...mint_address",
        "type": "enft",
        "buyback_price": 21.25,
        "content": {
          "metadata": {
            "name": "2024 Juan Soto RC Auto /25",
            "image": "https://cdn.phygitals.com/cards/example.png"
          }
        }
      }
    ]
  }
}
result.session_id
string
Purchase session ID. Pass to /api/vm/buy/status if nfts is empty or fulfillment is pending.
result.nfts
array
Pulled items. Each entry includes an id (mint address), metadata, and buyback_price when applicable.
result.tx_hash
string
On-chain transaction or bundle signature for the purchase.

Error responses

StatusExampleCause
400{ "error": "amount must be a positive integer" }Invalid amount
400{ "error": "Unsupported currency: …" }Unknown currency / chain pair
400{ "error": "…" }Pack out of stock, invalid transaction, or business-rule rejection
401{ "message": "Invalid or missing credentials" }Missing or invalid API key
429{ "message": "Rate limit exceeded" }More than one request per 60 seconds
500{ "error": "Error during transaction" }Unexpected server error

Integration flow

Transaction construction is chain-specific. Refer to the Phygitals web client or contact hello@phygitals.com for integration support on your target chain.