> ## Documentation Index
> Fetch the complete documentation index at: https://dev.phygitals.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Poll purchase status

> Check whether a crypto pack purchase has fulfilled and retrieve pulled items.

Polls the status of a purchase session created by [`POST /api/vm/buy/crypto`](/public-api/purchase/crypto). The server holds the connection open and checks fulfillment internally before responding.

<Note>
  **Scope required:** `vm.buy.crypto`
</Note>

## Request body

<ParamField body="session_id" type="string" required>
  Session ID from the `buy/crypto` response (`result.session_id`).
</ParamField>

## Example request

```http theme={"dark"}
POST /api/vm/buy/status
X-API-Key: phy_your_secret_key
Content-Type: application/json

{
  "session_id": "550e8400-e29b-41d4-a716-446655440000"
}
```

## Response

<ResponseExample>
  ```json 200 — fulfilled theme={"dark"}
  {
    "result": {
      "session_id": "550e8400-e29b-41d4-a716-446655440000",
      "user_id": "did:privy:abc123",
      "public_id": "_a1b2c3d4",
      "tx_hash": "5Kn8...bundle_signature",
      "nfts": [
        {
          "id": "9XnY...mint_address",
          "type": "enft",
          "buyback_price": 21.25,
          "mint_address": "9XnY...mint_address",
          "content": {
            "metadata": {
              "name": "2024 Juan Soto RC Auto /25",
              "image": "https://cdn.phygitals.com/cards/example.png"
            },
            "links": {
              "image": "https://cdn.phygitals.com/cards/example.png"
            }
          }
        }
      ]
    }
  }
  ```

  ```json 200 — still processing theme={"dark"}
  {
    "status": "pending"
  }
  ```
</ResponseExample>

<ResponseField name="result.nfts" type="array">
  Pulled items once fulfillment completes. Empty or absent while the purchase is still processing.
</ResponseField>

<ResponseField name="result.public_id" type="string">
  Public reveal identifier for the pull (shareable link prefix).
</ResponseField>

<ResponseField name="status" type="string">
  Present when fulfillment has not completed within the server poll window. Retry after a short delay.
</ResponseField>

## Error responses

| Status | Example                                           | Cause                      |
| ------ | ------------------------------------------------- | -------------------------- |
| `400`  | `{ "error": "Transaction failed" }`               | On-chain purchase failed   |
| `401`  | `{ "message": "Invalid or missing credentials" }` | Missing or invalid API key |

## Polling guidance

* Call this endpoint after `buy/crypto` when the initial response has a `session_id` but no `nfts`
* The server polls for up to \~6 seconds before returning a pending `status`
* On the client side, retry with 500–1000 ms between attempts until `result.nfts` is populated or an error is returned
* Stop polling on `400` with `"Transaction failed"`
