Virtual items

Overview

Virtual items are in-game items that users can purchase with real or virtual currency or receive as a bonus. These items have no physical form and are used exclusively within the game. Examples of virtual items: skins, potions, weapons, keys, and other elements that affect gameplay or character appearance.

Key features:

Note

Virtual items, like other items (virtual currency, bundles, etc.), can be created in Publisher Account, via API, or imported as a part of a catalog.

This guide covers manual item creation and API usage.

For detailed information on importing a catalog, refer to the following sections:

Setting up in Publisher Account

Create group

Note
A group can include various item types (virtual items, virtual currency packages, etc.). For detailed information about grouping and sorting, refer to the How to group and sort items in catalog instruction.

Groups enable you to build a multi-level catalog. Items not assigned to a group will be placed in the Ungrouped group. The Ungrouped group can’t be edited or deleted.

To create a group:

  1. Open your project in Publisher Account and go to the Items catalog > Virtual items section.
  2. Click + and select Create group from the drop-down list.
  1. Specify the following parameters:
    • External ID — unique group ID.
    • Group name.
  2. To make the group available in the store, set the Show group in Store toggle to On. In this case, the group will be created with the Enabled status. You can change the group status later.
  3. Click Create group.
Note

If a group has the Disabled status, such a group:

  • is not returned in the response when calling the Get item group list API method
  • is not displayed in the properties of items included in this group when calling client API methods for getting a list of items
  • is not available for use in Site Builder.

To change the group’s status after creation, find the desired group in the Items catalog > Virtual items section and select the necessary status in the Status column.

You can create a multi-level catalog by adding new groups inside existing ones. The exception is the Ungrouped group, for which creating nested groups is not available.

To nest an existing group within another group:

  1. Open your project in Publisher Account and go to the Items catalog > Virtual items section.
  2. Select the group you want to nest under another existing group.
  3. Click ••• and select Edit group from the drop-down list.
  4. From the Directory location drop-down list, select the parent group where you want to place the current group.
  1. Click Save changes.

Create virtual item

To create a virtual item:

  1. Open your project in Publisher Account and go to the Items catalog > Virtual items section.
  2. Click + and select Create item from the drop-down list.
  1. Define the availability status of the virtual item in the catalog. Select one of the following options:
    • Unavailable (default) — the item is not available for purchase in the catalog, can’t be included in a bundle, or used as a bonus for another item purchase.
    • Available — the item is available for purchase in the catalog and can be included in a bundle or used as a bonus for another item purchase.
    • Partially available — the item is not available for purchase from the catalog but can still be added to a bundle or used as a bonus for another item purchase.
    You can change the item’s availability status later.
  1. Configure the basic settings. Specify the following:
    • image (optional)
    • SKU
    • one or several groups the item should belong to
    • item name
    • item description (optional)
Note
An item description is limited to 255 characters. If you need to add a description longer than 255 characters, contact your Customer Success Manager or email to csm@xsolla.com.
  1. Leave the item type set to the default one — Consumable (recommended).
Note
The item type — consumable, nonconsumable, or time-limited — defines how the item behaves in the Xsolla inventory system. Xsolla inventory is available only when integrated via SDK.
  1. Set up virtual item pricing:
    • To create a free virtual item, in the Paid or free field, select Free item.
    • To create a paid virtual item, in the Paid or free field, select Paid item, and specify the price in one or more currencies.
    • Set up regional prices (optional).
Note
A virtual item can have prices in multiple real and virtual currencies. In this case, you must define a default currency for each type: one for real currencies and one for virtual currencies.
  1. Limit the number of items available for purchase (optional). To do that:
    1. Set Limit number of times one user can buy this item toggle to On, and specify the number of items a user can purchase.
    2. Configure the limit refresh frequency:
      1. If you don’t want to reset the limit, select No regular refresh from the drop-down list.
      2. If you want to regularly reset the limit, select a refresh frequency from the drop-down list and specify when the reset should occur.
  2. Limiting the display time for items in the store (optional). To do that, in the Show item in store field, select Time period, specify the time zone, the beginning, and the end of the period. If you don’t want to indicate the end of the item display period, check the No end date box.
  3. Add additional attributes (optional).
  4. Click Create item.

Working with virtual items via API

Use API calls from the Admin subsection of the Virtual Items & Currency group to set up virtual items.

Notice
Endpoints from the Admin subsection aren’t intended for building a catalog in the store on the frontend side. You shouldn’t use them for landing pages, web stores, and in-game logics.

Basic authorization is used for API calls. Pass the Authorization:Basic <your_authorization_basic_key>, where <your_authorization_basic_key> is the merchant ID:API key pair encoded according to the Base64 standard. Go to Publisher Account to find these parameters:

  • Merchant ID is shown:
    • In the Company settings > Company section.
    • In the URL in the browser address bar on any Publisher Account page. The URL has the following format: https://publisher.xsolla.com/<merchant_id>/.

Notice

For more information about working with API keys, see the API reference.

Key recommendations:

  • Save the generated API key on your side. You can view the API key in Publisher Account only once when it is created.
  • Keep your API key a secret. It provides access to your personal account and your projects in Publisher Account.
  • The API key must be stored on your server and never in binaries or on the frontend.

If an API call you need does not contain the project_id path parameter, use the API key that is valid in all the company’s projects to set up authorization.

Use API calls from the Catalog subsection of the Virtual Items & Currency group to get the catalog of virtual items on the client side. These calls don’t require basic authorization.

Use the Get virtual items list API call to get the full list of items not divided into groups. To get the list of items from the definite group, pass the external_id parameter to the Get items list by specified group call.

Advanced settings for virtual items

Limit number of items available for purchase

You can limit how many times a specific virtual item can be purchased by a single user. This helps control item availability and supports the creation of exclusive offers.

Use cases include:

  • Daily, weekly, or monthly purchase limits for a virtual item.
  • A welcome item available for purchase only once per user.

There are two ways to configure purchase limits:

  • In Publisher Account: When creating or editing an item, set the Limit number of times one user can buy this item toggle to On, specify the item quantity available for purchase, and configure the refresh schedule.
  • Via API: When creating or updating an item, pass the purchase limit settings in the limits object in the request body.

Limit enforcement is handled entirely on the Xsolla’s side. The system tracks how many times each user has purchased an item and prevents purchases that exceed the configured limit.

If a user access token is included in a catalog request (when calling API methods from the Catalog subsection of the Virtual Items & Currency group), Xsolla calculates how many units of each item the specific user can still purchase. The response will include the limits object that contains the total allowed quantity (the total parameter) and the remaining quantity available to that user (the available parameter). These values can be used to display availability in the interface.

If the user access token is not provided in the request, the available parameter value will always match the total limit in the response.

Example of a response containing items with purchase limits:

Copy
Full screen
Small screen
 1{
 2  "items": [
 3    {
 4      "sku": "big_rocket",
 5      "name": "Big Rocket",
 6      "groups": [
 7        {
 8          "external_id": "accessory",
 9          "name": "Accessory"
10        }
11      ],
12      "attributes": [
13        {
14          "external_id": "stack_size",
15          "name": "Stack size",
16          "values": [
17            {
18              "external_id": "size_e3364991f92e751689a68b96598a5a5a84010b85",
19              "value": "5"
20            }
21          ]
22        }
23      ],
24      "type": "virtual_good",
25      "description": "Big Rocket - description",
26      "image_url": "https://popmedia.blob.core.windows.net/popyourself/male/outfit/male_armor_white_a-01.png",
27      "is_free": false,
28      "price": {
29        "amount": "100.99",
30        "amount_without_discount": "100.99",
31        "currency": "USD"
32      },
33      "virtual_prices": [
34        {
35          "amount": 100,
36          "sku": "vc_test",
37          "is_default": true,
38          "amount_without_discount": 100,
39          "image_url": "http://image.png",
40          "name": "SHOTGUN FOR TRUE RAIDERS",
41          "type": "virtual_currency",
42          "description": "description"
43        }
44      ],
45      "can_be_bought": true,
46      "inventory_options": {
47        "consumable": {
48          "usages_count": 1
49        },
50        "expiration_period": {
51          "type": "day",
52          "value": 1
53        }
54      },
55      "virtual_item_type": "non_renewing_subscription",
56      "limits": {
57        "per_user": {
58          "total": 5,
59          "available": 5
60        },
61        "per_item": null
62      }
63    }
64  ]
65}

Additionally, Xsolla enforces the purchase limit during both checkout initialization and order completion. If a user opens multiple tabs or attempts to create several orders simultaneously, the system will prevent the limit from being exceeded: any unpaid orders containing already-purchased items will be canceled.

Note
To learn more about this and other types of purchase quantity limits, refer to the Number limited offers instruction.

Limit display time for items in store

You can specify a display period for items in the store in order to:

  • maintain the relevance of the catalog at a given time, for example, during holiday sales
  • create an item in advance without displaying it in the catalog
  • motivate users to buy items by displaying a timer next to the item

Note
When building the catalog UI using Site Builder, the timer will be displayed automatically. If you create a catalog in your own UI, you need to implement the timer yourself.

You can configure the display time limit for an item in the store in the following ways:

  • In Publisher Account: When creating or editing an item, in the Show item in store field, select Time period and specify the time zone, start date, and end date. To leave the end date open, check the No end date box.
  • Via the API: When creating or updating an item, include the following parameters in the periods object:
    • periods[0].date_from — the start date and time of the display period (format: YYYY-MM-DDThh:mm:ss±hh:mm).
    • periods[0].date_until — the end date and time of the display period. To omit the end date, pass null.

You can define multiple display periods using the API by passing an array of objects, each with a start and end date.

Example of a periods array:

Copy
Full screen
Small screen
 1"periods": [
 2      {
 3        "date_from": "2022-06-10T14:00:00+03:00",
 4        "date_until": "2022-06-30T14:00:00+03:00"
 5      },
 6       {
 7        "date_from": "2022-07-10T14:00:00+03:00",
 8        "date_until": "2022-07-30T14:00:00+03:00"
 9      },
10       {
11        "date_from": "2022-08-10T14:00:00+03:00",
12        "date_until": "2022-08-30T14:00:00+03:00"
13      }
14]

Set up regional restrictions

You can configure in which regions a virtual item will be available for purchase. This allows you to control who sees the item and where, e.g., you can hide the item from users in certain countries, or make it available only in specific regions as part of a regional promotional campaign.

To set up regional restrictions for virtual items, include an array of regions objects with the corresponding region IDs in the request body when calling the Create virtual item or Update virtual item API methods.

Example of a regions array:

Copy
Full screen
Small screen
1"regions": [
2  {
3     "id": 123
4  },
5  {
6     "id": 456
7  }
8]
Note
To learn more on configuring regional restrictions, refer to the Regional sales restrictions instruction.

Set up regional prices

You can configure regional pricing to adjust the cost of virtual items based on the economic conditions of different countries. This helps make offers more accessible to users in regions with varying purchasing power, increasing both conversion rates and overall sales.

You can set up regional pricing in the following ways:

  • In Publisher Account (manual configuration): When creating or editing an item, go to the Price settings section, set the Prices in real currency toggle to On, and click Set up prices. You can either enter prices manually or calculate them automatically based on currencies and taxes.
  • Via CSV import in Publisher Account: In the CSV file, you can add multiple rows with item prices for specific regions. For more information about the file structure and examples, refer to the Local prices instruction.
Example of a CSV file for import:
Copy
Full screen
Small screen
 1SKU,Currency,Amount,Country,IsDefault,Platform
 2game-key-1,EUR,9.09,,1,steam
 3game-key-1,EUR,9.2,DE,0,steam
 4game-key-1,EUR,8.09,IT,0,steam
 5game-key-1,USD,10.1,US,0,steam
 6game-key-1,MYR,47,MY,0,steam
 7game-key-2,EUR,2.09,,1,steam
 8game-key-2,EUR,2.2,DE,0,steam
 9game-key-2,EUR,1.79,IT,0,steam
10game-key-2,USD,2.3,US,0,steam
11game-key-2,MYR,24,MY,0,steam
  • Via the API: When creating or updating an item, include the prices array in the request body with the regional pricing settings.
Example of a prices array:
Copy
Full screen
Small screen
 1"prices": [
 2      {
 3        "amount": 100,
 4        "currency": "USD",
 5        "is_enabled": true,
 6        "is_default": true
 7      },
 8      {
 9        "amount": 200,
10        "currency": "CZK",
11        "country_iso": "CZ",
12        "is_enabled": false,
13        "is_default": false
14      }
15    ]
Note
To learn more about configuring regional prices, the country detection mechanism, and pricing display rules in the catalog, refer to the Local prices instruction.
Was this article helpful?
Thank you!
Is there anything we can improve? Message
We’re sorry to hear that
Please explain why this article wasn’t helpful to you. Message
Thank you for your feedback!
We’ll review your message and use it to help us improve your experience.

Useful links

Last updated: October 8, 2025

Found a typo or other text error? Select the text and press Ctrl+Enter.

Report a problem
We always review our content. Your feedback helps us improve it.
Provide an email so we can follow up
Thank you for your feedback!
We couldn't send your feedback
Try again later or contact us at doc_feedback@xsolla.com.