

```json
{
  "openapi": "3.0.0",
  "tags": [
    {
      "name": "Configuration",
      "description": "Associated with retrieving remote config"
    },
    {
      "name": "Currencies",
      "description": "Associated with player currency actions"
    },
    {
      "name": "Inventory",
      "description": "Associated with player inventory actions"
    },
    {
      "name": "Purchases",
      "description": "Associated with player purchasing (virtual/ real money) actions"
    }
  ],
  "info": {
    "title": "Economy API",
    "version": "2.0.0",
    "description": "# Introduction\n  This document outlines the API specification for the Economy API.\n  The Economy service allows the game client to retrieve and modify a player's economy resources in the cloud.\n# Concepts\n  ## Resources\n  Economy currently allows interaction with the following types of resources:\n  - Currencies: A resource that, when defined, contains two parameters: Initial and Max. The Initial parameter determines how much of the currency a game assigns to a player upon first interacting with the Economy system. The Max parameter determines how much of the currency the player is allowed to have.\n  - Inventory Items: A resource that doesn't have any set parameters; its intended use is to indicate the ownership or acquisition of an item in-game, for example, Sword and Shield.\n    A game client can add, remove or update the associated data of an instance of a configured inventory item from the player's inventory.\n  - Virtual Purchases: A transactional resource to implement a shop or trade feature. Allows the player to buy items/currencies using the previously defined currencies or inventory items.\n    A game client can redeem a virtual purchase and the player's account updates with the rewards if the costs criteria are met.\n  - Real Money Purchases: A transactional resource with the intended use to facilitate a shop or trade feature. Allows the player to buy any amount of items/currencies through an in-app purchase. Only uses the previously defined currencies or inventory items.\n    A game client can redeem a real money purchase and the player's account updates with the rewards.\n\n  The above resources also have an optional Custom Data parameter that can be populated with JSON data from the dashboard to allow clients to read bespoke data.\n  ## Writelock\n  The WriteLock is an integer that is automatically incremented serverside whenever a request that changes the stored value of a player's account or inventory.\n  The purpose of the WriteLock is to help prevent requests from the same or other game clients happening out-of-sync.\n  This parameter is optional, but when supplied with a request, the service does a comparison with the stored WriteLock on the server, and returns an error on mismatch.\n  ## Rate Limits\n  The API has rate limiting in place. Requests are limited on a per-player basis up to 150 requests per minute.\n  The API responds with a `429` HTTP status code if the requests exceed the rate limit.\n  Responses with a `429` status code include a `Retry-After` header to be used in conjunction with a client's retry logic, the value is the number of seconds until a request for the given player is accepted.\n"
  },
  "servers": [
    {
      "url": "https://economy.services.api.unity.com"
    }
  ],
  "paths": {
    "/v2/projects/{projectId}/players/{playerId}/currencies": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "get": {
        "summary": "Player currency balances",
        "tags": [
          "Currencies"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "title": "player-currency-balance-response",
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "description": "List of currency balances.",
                      "items": {
                        "$ref": "#/components/schemas/currency-balance-response"
                      }
                    },
                    "links": {
                      "type": "object",
                      "required": [
                        "next"
                      ],
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true,
                          "description": "Contains the URL path for requesting the next page of results. This value is `null` when there are no pages remaining."
                        }
                      }
                    }
                  },
                  "required": [
                    "results",
                    "links"
                  ]
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "operationId": "getPlayerCurrencies",
        "description": "Get a list of currency balances for a player.\nResults ordered in ascending currency ID.",
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$"
            },
            "in": "query",
            "name": "after",
            "allowEmptyValue": true,
            "description": "The currency ID after which to retrieve the next page of balances."
          },
          {
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1
            },
            "in": "query",
            "name": "limit",
            "description": "Number of currencies to be returned. Defaults to 20.",
            "allowEmptyValue": true
          }
        ],
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/currencies/{currencyId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "currencyId",
          "description": "Resource ID of the currency.",
          "in": "path",
          "required": true
        }
      ],
      "put": {
        "operationId": "setPlayerCurrencyBalance",
        "description": "Set a player's currency balance.",
        "tags": [
          "Currencies"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/currency-balance-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-currency-balance"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-currency-max-exceeded"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/currency-balance-request"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "summary": "Set currency balance",
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/currencies/{currencyId}/increment": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "currencyId",
          "description": "Resource ID of the currency.",
          "in": "path",
          "required": true
        }
      ],
      "post": {
        "summary": "Increment currency balance",
        "operationId": "incrementPlayerCurrencyBalance",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/currency-balance-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-currency-balance"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-currency-max-exceeded"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "description": "Increment a player's currency balance by a given value.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/currency-modify-balance-request"
              }
            }
          },
          "description": ""
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ],
        "tags": [
          "Currencies"
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/currencies/{currencyId}/decrement": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "currencyId",
          "description": "Resource ID of the currency.",
          "in": "path",
          "required": true
        }
      ],
      "post": {
        "summary": "Decrement currency balance",
        "operationId": "decrementPlayerCurrencyBalance",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/currency-balance-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-currency-balance"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-currency-insufficient-funds"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "description": "Decrements a player's currency balance by a given value.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/currency-modify-balance-request"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ],
        "tags": [
          "Currencies"
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/inventory": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "post": {
        "summary": "Add inventory item",
        "description": "Add an item to a player's inventory.",
        "operationId": "addInventoryItem",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/add-inventory-request"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/inventory-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-inventory"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-inventory-instance-limit"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ],
        "tags": [
          "Inventory"
        ]
      },
      "get": {
        "summary": "List player inventory",
        "tags": [
          "Inventory"
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "title": "player-inventory-response",
                  "type": "object",
                  "properties": {
                    "results": {
                      "type": "array",
                      "description": "List of player's inventory items.",
                      "items": {
                        "$ref": "#/components/schemas/inventory-response"
                      }
                    },
                    "links": {
                      "type": "object",
                      "required": [
                        "next"
                      ],
                      "properties": {
                        "next": {
                          "type": "string",
                          "nullable": true,
                          "description": "Contains the URL path for requesting the next page of results. This value is `null` when there are no pages remaining."
                        }
                      }
                    }
                  },
                  "required": [
                    "results",
                    "links"
                  ]
                }
              }
            }
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable"
          }
        },
        "operationId": "getPlayerInventory",
        "description": "Get a list of inventory for a player.\nResults ordered by ascending `playersInventoryItemId`.\n`playersIventoryItemIds` and `inventoryItemIds` filters are optional, if not given all items will be returned. If both are given an item must match both to be returned.",
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          },
          {
            "schema": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$",
              "maxLength": 50
            },
            "in": "query",
            "name": "after",
            "allowEmptyValue": true,
            "description": "The `playersInventoryItemId` after which to retrieve the next page of balances."
          },
          {
            "schema": {
              "type": "integer",
              "maximum": 100,
              "minimum": 1
            },
            "in": "query",
            "name": "limit",
            "description": "Number of items to be returned. Defaults to 20.",
            "allowEmptyValue": true
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "pattern": "^[A-Za-z0-9_-]+$",
                "maxLength": 50
              },
              "minItems": 1,
              "maxItems": 20
            },
            "in": "query",
            "name": "playersInventoryItemIds",
            "description": "List of `playersInventoryItemIds` in array notation, for example, `playersInventoryItemIds[]=ID1&playersInventoryItemIds[]=ID2`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "array",
              "items": {
                "type": "string",
                "maxLength": 50,
                "pattern": "^[A-Z0-9_-]+$"
              },
              "minItems": 1,
              "maxItems": 5
            },
            "in": "query",
            "name": "inventoryItemIds",
            "description": "List of inventory item IDs in array notation, for example, `inventoryItemIds[]=ID1&inventoryItemIds[]=ID2`.",
            "style": "form",
            "explode": true
          }
        ],
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/inventory/{playersInventoryItemId}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "playersInventoryItemId",
          "description": "The `playersInventoryItemId` of the item to be updated.",
          "in": "path",
          "required": true
        }
      ],
      "put": {
        "summary": "Update player's inventory item",
        "operationId": "updateInventoryItem",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/inventory-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-inventory-update"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        },
        "description": "Update a player's inventory item.",
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inventory-request-update"
              }
            }
          }
        },
        "security": [
          {
            "Client": []
          }
        ],
        "tags": [
          "Inventory"
        ]
      },
      "delete": {
        "summary": "Delete player's inventory item",
        "tags": [
          "Inventory"
        ],
        "operationId": "deleteInventoryItem",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "409": {
            "$ref": "#/components/responses/error-response-conflict-inventory-delete"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        },
        "description": "Delete a player's inventory item.",
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          },
          {
            "$ref": "#/components/parameters/writeLock"
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/inventory-delete-request"
              }
            }
          }
        },
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/purchases/virtual": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "post": {
        "summary": "Make virtual purchase",
        "operationId": "makeVirtualPurchase",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/player-purchase-virtual-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-virtual-purchase"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        },
        "description": "Make a virtual purchase for a player.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/player-purchase-virtual-request"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ],
        "tags": [
          "Purchases"
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/purchases/appleappstore": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "post": {
        "summary": "Redeem Apple App Store purchase",
        "operationId": "redeemAppleAppStorePurchase",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/player-purchase-appleappstore-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-apple-purchase"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        },
        "tags": [
          "Purchases"
        ],
        "description": "Redeem an Apple App Store purchase for a player.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/player-purchase-appleappstore-request"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/purchases/googleplaystore": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "post": {
        "summary": "Redeem Google Play purchase",
        "operationId": "redeemGooglePlayPurchase",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/player-purchase-googleplaystore-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "422": {
            "$ref": "#/components/responses/error-response-unprocessable-entity-google-purchase"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        },
        "tags": [
          "Purchases"
        ],
        "description": "Redeem a Google Play store purchase for a player.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/player-purchase-googleplaystore-request"
              }
            }
          }
        },
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ]
      }
    },
    "/v2/projects/{projectId}/players/{playerId}/config/resources": {
      "parameters": [
        {
          "$ref": "#/components/parameters/projectId"
        },
        {
          "$ref": "#/components/parameters/playerId"
        }
      ],
      "get": {
        "summary": "Get player's configuration",
        "tags": [
          "Configuration"
        ],
        "operationId": "getPlayerConfiguration",
        "description": "Returns the economy configuration for the player with any overrides applied.",
        "parameters": [
          {
            "$ref": "#/components/parameters/configAssignmentHash"
          },
          {
            "$ref": "#/components/parameters/installationId"
          },
          {
            "$ref": "#/components/parameters/analyticsUserId"
          }
        ],
        "security": [
          {
            "Client": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/player-configuration-response"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/error-response-bad-request"
          },
          "403": {
            "$ref": "#/components/responses/error-response-forbidden"
          },
          "404": {
            "$ref": "#/components/responses/error-response-not-found"
          },
          "429": {
            "$ref": "#/components/responses/error-response-too-many-requests"
          },
          "503": {
            "$ref": "#/components/responses/error-response-service-unavailable-datastore"
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "currency-balance-request": {
        "title": "currency-balance-request",
        "type": "object",
        "properties": {
          "currencyId": {
            "type": "string",
            "description": "Resource ID of the currency.",
            "deprecated": true
          },
          "balance": {
            "type": "integer",
            "format": "int64",
            "description": "The player's balance.",
            "minimum": 0,
            "maximum": 999999999999999
          },
          "writeLock": {
            "type": "string",
            "description": "The write lock for the currency balance."
          }
        },
        "required": [
          "balance"
        ]
      },
      "currency-balance-response": {
        "title": "currency-balance-response",
        "type": "object",
        "properties": {
          "currencyId": {
            "type": "string",
            "description": "Resource ID of the currency."
          },
          "balance": {
            "type": "integer",
            "format": "int64",
            "description": "The player's balance.",
            "minimum": 0,
            "maximum": 999999999999999
          },
          "writeLock": {
            "type": "string",
            "description": "The write lock for the currency balance."
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          }
        },
        "required": [
          "currencyId",
          "balance",
          "writeLock",
          "created",
          "modified"
        ]
      },
      "add-inventory-request": {
        "title": "add-inventory-request",
        "type": "object",
        "properties": {
          "inventoryItemId": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "Resource ID of the inventory item."
          },
          "playersInventoryItemId": {
            "type": "string",
            "description": "A `playersInventoryItemId` for the item being created. If not given, Economy automatically generates the ID. An ID must be unique for a player.",
            "pattern": "^[A-Za-z0-9_-]+$",
            "maxLength": 50
          },
          "instanceData": {
            "type": "object",
            "nullable": true,
            "description": "Instance data to be saved against the new inventory item. Max size when serialized 5 KB."
          }
        },
        "required": [
          "inventoryItemId"
        ]
      },
      "inventory-request-update": {
        "title": "player-inventory-request-update",
        "type": "object",
        "properties": {
          "instanceData": {
            "type": "object",
            "nullable": true,
            "description": "Instance data to be saved against the inventory item. Max size when serialized 5 KB."
          },
          "writeLock": {
            "type": "string",
            "description": "The write lock for the inventory item instance."
          }
        },
        "required": [
          "instanceData"
        ]
      },
      "inventory-delete-request": {
        "title": "player-inventory-delete-request",
        "type": "object",
        "deprecated": true,
        "description": "The request body has been deprecated in favor of using query parameters due to inconsistent HTTP client support\nfor sending request bodies for DELETE requests. Please use the corresponding query parameters instead, which\nwill take precedence over any request body properties if both are present.",
        "properties": {
          "writeLock": {
            "type": "string",
            "deprecated": true,
            "description": "The write lock for the inventory item instance.\nThis property has been deprecated. Please use the `writeLock` query parameter instead."
          }
        }
      },
      "inventory-response": {
        "title": "inventory-response",
        "type": "object",
        "properties": {
          "playersInventoryItemId": {
            "type": "string",
            "description": "ID of the player's inventory item.",
            "pattern": "^[A-Za-z0-9_-]+$",
            "maxLength": 50
          },
          "inventoryItemId": {
            "type": "string",
            "description": "Resource ID of the inventory item configuration associated with this instance.",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50
          },
          "instanceData": {
            "type": "object",
            "nullable": true,
            "description": "Instance data. Max size when serialized 5 KB."
          },
          "writeLock": {
            "type": "string",
            "description": "The write lock for the inventory item instance."
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          }
        },
        "required": [
          "playersInventoryItemId",
          "inventoryItemId",
          "writeLock",
          "created",
          "modified"
        ]
      },
      "modified-metadata": {
        "title": "modified-metadata",
        "type": "object",
        "properties": {
          "date": {
            "type": "string",
            "nullable": true,
            "format": "date-time",
            "description": "Date time in ISO 8601 format. `null` if there is no associated value.",
            "example": "2020-04-01T13:07:23Z"
          }
        },
        "required": [
          "date"
        ]
      },
      "currency-modify-balance-request": {
        "title": "currency-modify-balance-request",
        "type": "object",
        "properties": {
          "currencyId": {
            "type": "string",
            "description": "Resource ID of the currency.",
            "deprecated": true
          },
          "amount": {
            "type": "integer",
            "format": "int64",
            "minimum": 0,
            "maximum": 999999999999999,
            "description": "The value by which to increment or decrement. Zero is allowed but results in no change to the currency balance."
          },
          "writeLock": {
            "type": "string",
            "description": "The write lock for the currency balance."
          }
        },
        "required": [
          "amount"
        ]
      },
      "error-response-conflict-currency-balance": {
        "title": "error-response-conflict-currency-balance",
        "type": "object",
        "nullable": true,
        "description": "An error response sent back upon currency balance conflict.",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "For example 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "required": [
              "attempted",
              "existing"
            ],
            "properties": {
              "attempted": {
                "$ref": "#/components/schemas/currency-balance-request"
              },
              "existing": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/currency-balance-response"
                  }
                ]
              }
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "error-response-conflict-inventory-update": {
        "title": "error-response-conflict-inventory-update",
        "type": "object",
        "description": "An error response sent back upon player inventory item conflict.",
        "x-examples": {
          "Conflict Error Example": {
            "type": "problems/data/conflict",
            "title": "conflict error",
            "status": 409,
            "code": 10204,
            "detail": "WriteLock in update request does not match stored WriteLock.",
            "data": {
              "attempted": {
                "instanceData": {
                  "damage": "14"
                },
                "writeLock": "2509f6b5cbb187b8920a57913eb7fcb0"
              },
              "existing": {
                "playersInventoryItemId": "abc123",
                "inventoryItemId": "SWORD",
                "instanceData": {
                  "damage": "15"
                },
                "writeLock": "3309f6b5cbb187b8920a57913eb7fc66",
                "created": {
                  "date": "2020-01-01T01:01:01Z"
                },
                "modified": {
                  "date": "2020-02-02T02:02:02Z"
                }
              }
            }
          }
        },
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "e.g 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "required": [
              "attempted",
              "existing"
            ],
            "properties": {
              "attempted": {
                "$ref": "#/components/schemas/add-inventory-request"
              },
              "existing": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/inventory-response"
                  }
                ]
              }
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "error-response-conflict-inventory-delete": {
        "title": "error-response-conflict-inventory-delete",
        "type": "object",
        "description": "An error response sent back upon player inventory item conflict.",
        "x-examples": {
          "Conflict Error Example": {
            "type": "problems/data/conflict",
            "title": "conflict error",
            "status": 409,
            "code": 10204,
            "detail": "WriteLock in update request does not match stored WriteLock.",
            "data": {
              "attempted": {
                "playersInventoryItemId": "abc123",
                "writeLock": "2509f6b5cbb187b8920a57913eb7fcb0"
              },
              "existing": {
                "playersInventoryItemId": "abc123",
                "inventoryItemId": "SWORD",
                "instanceData": {
                  "damage": "15"
                },
                "writeLock": "3309f6b5cbb187b8920a57913eb7fc66",
                "created": {
                  "date": "2020-01-01T01:01:01Z"
                },
                "modified": {
                  "date": "2020-02-02T02:02:02Z"
                }
              }
            }
          }
        },
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "e.g 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "required": [
              "attempted",
              "existing"
            ],
            "properties": {
              "attempted": {
                "type": "object",
                "properties": {
                  "writeLock": {
                    "type": "string",
                    "description": "The write lock for the inventory item instance."
                  }
                }
              },
              "existing": {
                "$ref": "#/components/schemas/inventory-response"
              }
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "error-response-conflict-inventory": {
        "title": "error-response-conflict-inventory",
        "type": "object",
        "description": "An error response sent back upon player inventory item conflict.",
        "nullable": true,
        "x-examples": {
          "Conflict Error Example": {
            "type": "problems/data/conflict",
            "title": "conflict error",
            "status": 409,
            "code": 10204,
            "detail": "WriteLock in update request does not match stored WriteLock.",
            "data": {
              "attempted": {
                "playersInventoryItemId": "abc123",
                "inventoryItemId": "SWORD",
                "instanceData": {
                  "damage": "17"
                }
              },
              "existing": {
                "playersInventoryItemId": "abc123",
                "inventoryItemId": "SWORD",
                "instanceData": {
                  "damage": "15"
                },
                "writeLock": "2509f6b5cbb187b8920a57913eb7fcb0",
                "created": {
                  "date": "2020-01-01T01:01:01Z"
                },
                "modified": {
                  "date": "2020-02-02T02:02:02Z"
                }
              }
            }
          }
        },
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "e.g 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "type": "object",
            "required": [
              "attempted",
              "existing"
            ],
            "properties": {
              "attempted": {
                "$ref": "#/components/schemas/add-inventory-request"
              },
              "existing": {
                "nullable": true,
                "allOf": [
                  {
                    "$ref": "#/components/schemas/inventory-response"
                  }
                ]
              }
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "player-purchase-virtual-request": {
        "title": "player-purchase-virtual-request",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "ID of the purchase."
          },
          "playersInventoryItemIds": {
            "type": "array",
            "description": "IDs of the player's inventory items that should be used for any item costs associated with the purchase.",
            "maxItems": 20,
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$",
              "maxLength": 50
            }
          }
        },
        "required": [
          "id"
        ]
      },
      "player-purchase-virtual-response": {
        "title": "player-purchase-virtual-response",
        "type": "object",
        "properties": {
          "costs": {
            "type": "object",
            "description": "Costs of the purchase.",
            "required": [
              "Currency",
              "inventory"
            ],
            "properties": {
              "currency": {
                "type": "array",
                "minItems": 0,
                "description": "Currency that was deducted in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/currency-exchange-item"
                }
              },
              "inventory": {
                "type": "array",
                "minItems": 0,
                "description": "Inventory that was deducted in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/inventory-exchange-item"
                }
              }
            }
          },
          "rewards": {
            "type": "object",
            "description": "Rewards of the purchase.",
            "required": [
              "Currency",
              "inventory"
            ],
            "properties": {
              "currency": {
                "type": "array",
                "minItems": 0,
                "description": "Currency that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/currency-exchange-item"
                }
              },
              "inventory": {
                "type": "array",
                "minItems": 0,
                "description": "Inventory that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/inventory-exchange-item"
                }
              }
            }
          }
        },
        "required": [
          "costs",
          "rewards"
        ],
        "x-examples": {
          "Simple Purchase": {
            "costs": {
              "currency": [
                {
                  "id": "COIN",
                  "amount": 10
                }
              ],
              "inventory": []
            },
            "rewards": {
              "currency": [],
              "inventory": [
                {
                  "id": "SWORD",
                  "amount": 1,
                  "instanceIds": [
                    "12345678-1234-5678-1234-567812345678"
                  ]
                }
              ]
            }
          }
        }
      },
      "currency-exchange-item": {
        "title": "currency-exchange-item",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50,
            "description": "ID of the currency."
          },
          "amount": {
            "type": "integer",
            "format": "int64",
            "description": "Amount of currency added or deducted.",
            "minimum": 1,
            "maximum": 999999999999999
          }
        },
        "required": [
          "id",
          "amount"
        ]
      },
      "inventory-exchange-item": {
        "title": "inventory-exchange-item",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50,
            "description": "ID of the inventory item."
          },
          "amount": {
            "type": "integer",
            "description": "Number of player inventory items.",
            "minimum": 1
          },
          "playersInventoryItemIds": {
            "type": "array",
            "description": "The `playersInventoryItemIds` for the player's items to be added or removed.",
            "uniqueItems": true,
            "items": {
              "type": "string",
              "pattern": "^[A-Za-z0-9_-]+$",
              "maxLength": 50
            }
          }
        },
        "required": [
          "id",
          "amount",
          "playersInventoryItemIds"
        ]
      },
      "basic-error-response": {
        "title": "basic-error-response",
        "description": "Referenced from - https://tools.ietf.org/html/rfc7807#page-3 Consumers MUST use the 'type' string as the primary identifier for the problem type; the 'title' string is advisory and included only for users who are not aware of the semantics of the URI and do not have the ability to discover them (for example, offline log analysis). Consumers SHOULD NOT automatically dereference the type URI. The \"status\" member, if present, is only advisory; it conveys the HTTP status code used for the convenience of the consumer. Generators MUST use the same status code in the actual HTTP response, to assure that generic HTTP software that does not understand this format still behaves correctly.  See Section 5 for further caveats regarding its use. Consumers can use the status member to determine what the original status code used by the generator was, in cases where it has been changed (for example, by an intermediary or cache), and when message bodies persist without HTTP information.  Generic HTTP software still uses the HTTP status code. The \"detail\" member, if present, should focus on helping the client correct the problem, rather than giving debugging information.\n",
        "type": "object",
        "x-examples": {
          "example-1": {
            "type": "problems/basic",
            "title": "service unavailable",
            "status": 500,
            "code": 1000,
            "detail": "service unavailable",
            "details": [
              {
                "health": [
                  "service health ping failed"
                ]
              }
            ]
          }
        },
        "properties": {
          "type": {
            "type": "string",
            "description": "A URI reference [RFC3986] that identifies the problem type. This specification encourages that, when dereferenced, it provide human-readable documentation for the problem type (for example, using HTML [W3C.REC-html5-20141028]). When this member is not present, its value is assumed to be \"about:blank\"."
          },
          "title": {
            "type": "string",
            "description": "A short, human-readable summary of the problem type. It SHOULD NOT change from occurrence to occurrence of the problem, except for purposes of localization (for example, using proactive content negotiation; see [RFC7231], Section 3.4)."
          },
          "status": {
            "type": "integer",
            "description": "The HTTP status code ([RFC7231], Section 6) generated by the origin server for this occurrence of the problem."
          },
          "code": {
            "description": "Service specific error code.",
            "type": "integer"
          },
          "detail": {
            "type": "string",
            "description": "A human-readable explanation specific to this occurrence of the problem."
          },
          "instance": {
            "type": "string",
            "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced."
          },
          "details": {
            "type": "array",
            "description": "Machine readable service specific errors.",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "type"
        ]
      },
      "validation-error-body": {
        "title": "validation-error-body",
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "field",
          "messages"
        ],
        "description": "Single error in the Validation Error Response.",
        "x-examples": {}
      },
      "validation-error-response": {
        "title": "validation-error-response",
        "type": "object",
        "description": "Validation error response when a value provided from the client does not pass validation on server.\n",
        "x-examples": {
          "Validation Error Example": {
            "type": "problems/validation",
            "title": "validation error",
            "status": 400,
            "code": 1009,
            "detail": "See 'errors' for specific validation errors",
            "errors": [
              {
                "field": "name",
                "messages": [
                  "Only alphanumeric characters allowed"
                ]
              }
            ]
          }
        },
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "code": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/validation-error-body"
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "errors"
        ]
      },
      "player-purchase-appleappstore-request": {
        "title": "player-purchase-appleappstore-request",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "ID of the purchase."
          },
          "receipt": {
            "type": "string",
            "description": "Receipt data returned from the Apple App Store as a result of a successful purchase. This should be base64 encoded."
          },
          "localCost": {
            "type": "integer",
            "description": "The cost of the purchase as an integer in the minor currency format, for example, $1.99 USD would be 199."
          },
          "localCurrency": {
            "type": "string",
            "description": "The ISO-4217 currency code with which the player purchased the IAP.",
            "format": "ISO-4217",
            "example": "USD"
          }
        },
        "required": [
          "id",
          "receipt",
          "localCost",
          "localCurrency"
        ]
      },
      "player-purchase-appleappstore-response": {
        "title": "player-purchase-appleappstore-response",
        "type": "object",
        "x-examples": {},
        "properties": {
          "verification": {
            "type": "object",
            "required": [
              "status",
              "store"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "VALID",
                  "VALID_NOT_REDEEMED",
                  "INVALID_ALREADY_REDEEMED",
                  "INVALID_VERIFICATION_FAILED",
                  "INVALID_ANOTHER_PLAYER",
                  "INVALID_CONFIGURATION",
                  "INVALID_PRODUCT_ID_MISMATCH",
                  "CURRENCY_MAX_EXCEEDED"
                ],
                "example": "VALID",
                "description": "Status of the receipt verification. \n* `VALID`: The purchase was valid. \n* `VALID_NOT_REDEEMED`: The purchase was valid but seen before, and had not yet been redeemed. \n* `INVALID_ALREADY_REDEEMED`: The purchase has already been redeemed. \n* `INVALID_VERIFICATION_FAILED`: The receipt verification Service returned that the receipt data was not valid. \n* `INVALID_ANOTHER_PLAYER`: The receipt has previously been used by a different player and validated. \n* `INVALID_CONFIGURATION`: The service configuration is invalid, further information in the details section of the response. \n* `INVALID_PRODUCT_ID_MISMATCH`: The purchase configuration store product identifier does not match the one in the receipt.\n* `CURRENCY_MAX_EXCEEDED`: Could not add the rewards because one or more currencies would be taken over the specified maximum balance."
              },
              "store": {
                "type": "object",
                "description": "Details from the receipt validation service.",
                "required": [
                  "code",
                  "message",
                  "receipt"
                ],
                "properties": {
                  "code": {
                    "type": "string",
                    "description": "The status code sent back from the Apple App Store verification service.",
                    "nullable": false
                  },
                  "message": {
                    "type": "string",
                    "description": "A textual description of the returned status code.",
                    "nullable": false
                  },
                  "receipt": {
                    "type": "string",
                    "description": "The full response from the Apple App Store verification service as a JSON encoded string.",
                    "nullable": false
                  }
                }
              }
            }
          },
          "rewards": {
            "type": "object",
            "description": "Rewards of the purchase.",
            "required": [
              "Currency",
              "inventory"
            ],
            "properties": {
              "currency": {
                "type": "array",
                "minItems": 0,
                "description": "Currency that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/currency-exchange-item"
                }
              },
              "inventory": {
                "type": "array",
                "minItems": 0,
                "description": "Inventory that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/inventory-exchange-item"
                }
              }
            }
          }
        },
        "required": [
          "verification",
          "rewards"
        ]
      },
      "error-response-purchase-appleappstore-failed": {
        "title": "error-response-purchase-appleappstore-failed",
        "type": "object",
        "description": "An error response sent back upon a redeem Apple App Store purchase.",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "e.g 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/player-purchase-appleappstore-response"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "player-purchase-googleplaystore-request": {
        "title": "player-purchase-googleplaystore-request",
        "type": "object",
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "ID of the purchase."
          },
          "purchaseData": {
            "type": "string",
            "description": "A JSON encoded string returned from a successful in-app billing purchase."
          },
          "purchaseDataSignature": {
            "type": "string",
            "description": "A signature of the `purchaseData` returned from a successful in-app billing purchase."
          },
          "localCost": {
            "type": "integer",
            "description": "The cost of the purchase as an integer in the minor currency format, for example, $1.99 USD would be 199."
          },
          "localCurrency": {
            "type": "string",
            "description": "The ISO-4217 currency code with which the player purchased the IAP.",
            "format": "ISO-4217",
            "example": "USD"
          }
        },
        "required": [
          "id",
          "purchaseData",
          "purchaseDataSignature",
          "localCost",
          "localCurrency"
        ]
      },
      "player-purchase-googleplaystore-response": {
        "title": "player-purchase-googleplaystore-response",
        "type": "object",
        "properties": {
          "verification": {
            "type": "object",
            "required": [
              "status",
              "store"
            ],
            "properties": {
              "status": {
                "type": "string",
                "enum": [
                  "VALID",
                  "VALID_NOT_REDEEMED",
                  "INVALID_ALREADY_REDEEMED",
                  "INVALID_VERIFICATION_FAILED",
                  "INVALID_ANOTHER_PLAYER",
                  "INVALID_CONFIGURATION",
                  "INVALID_PRODUCT_ID_MISMATCH",
                  "CURRENCY_MAX_EXCEEDED"
                ],
                "example": "VALID",
                "description": "Status of the receipt verification. \n* `VALID`: The purchase was valid. \n* `VALID_NOT_REDEEMED`: The purchase was valid but seen before, and had not yet been redeemed. \n* `INVALID_ALREADY_REDEEMED`: The purchase has already been redeemed. \n* `INVALID_VERIFICATION_FAILED`: The receipt verification Service returned that the receipt data was not valid. \n* `INVALID_ANOTHER_PLAYER`: The receipt has previously been used by a different player and validated. \n* `INVALID_CONFIGURATION`: The service configuration is invalid, further information in the details section of the response. \n* `INVALID_PRODUCT_ID_MISMATCH`: The purchase configuration store product identifier does not match the one in the receipt.\n* `CURRENCY_MAX_EXCEEDED`: Could not add the rewards because one or more currencies would be taken over the specified maximum balance."
              },
              "store": {
                "type": "object",
                "description": "Details from the receipt validation service.",
                "properties": {
                  "receipt": {
                    "type": "string",
                    "description": "Receipt that was sent in the request"
                  }
                }
              }
            }
          },
          "rewards": {
            "type": "object",
            "description": "Rewards of the purchase.",
            "required": [
              "currency",
              "inventory"
            ],
            "properties": {
              "currency": {
                "type": "array",
                "minItems": 0,
                "description": "Currency that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/currency-exchange-item"
                }
              },
              "inventory": {
                "type": "array",
                "minItems": 0,
                "description": "Inventory that was credited in the purchase.",
                "items": {
                  "$ref": "#/components/schemas/inventory-exchange-item"
                }
              }
            }
          }
        },
        "required": [
          "verification",
          "rewards"
        ]
      },
      "error-response-purchase-googleplaystore-failed": {
        "title": "error-response-purchase-googleplaystore-failed",
        "type": "object",
        "description": "An error response sent back upon a redeem Google Play purchase.",
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer",
            "description": "e.g 409"
          },
          "code": {
            "type": "integer",
            "description": "For example 10204"
          },
          "detail": {
            "type": "string"
          },
          "instance": {
            "type": "string"
          },
          "data": {
            "$ref": "#/components/schemas/player-purchase-googleplaystore-response"
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "player-configuration-response": {
        "title": "player-configuration-response",
        "type": "object",
        "properties": {
          "metadata": {
            "type": "object",
            "description": "Contains information about the results.",
            "properties": {
              "configAssignmentHash": {
                "type": "string",
                "description": "Hash representing the exact version of the configuration in the response."
              }
            }
          },
          "results": {
            "type": "array",
            "description": "Array of resource definitions.",
            "items": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/currency-resource"
                },
                {
                  "$ref": "#/components/schemas/inventory-item-resource"
                },
                {
                  "$ref": "#/components/schemas/virtual-purchase-resource"
                },
                {
                  "$ref": "#/components/schemas/real-money-purchase-resource"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "CURRENCY": "#/components/schemas/currency-resource",
                  "INVENTORY_ITEM": "#/components/schemas/inventory-item-resource",
                  "VIRTUAL_PURCHASE": "#/components/schemas/virtual-purchase-resource",
                  "MONEY_PURCHASE": "#/components/schemas/real-money-purchase-resource"
                }
              }
            }
          }
        },
        "required": [
          "configAssignmentHash",
          "results"
        ]
      },
      "currency-resource": {
        "title": "Currency resource",
        "type": "object",
        "description": "The definition for a economy resource that represents a currency.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50,
            "description": "Identifier for the resource."
          },
          "name": {
            "type": "string",
            "description": "Name of the resource."
          },
          "type": {
            "type": "string",
            "description": "Type of the resource, for example `CURRENCY`, `INVENTORY_ITEM`, `VIRTUAL_PURCHASE`, `MONEY_PURCHASE`.",
            "enum": [
              "CURRENCY"
            ]
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "initial": {
            "type": "integer"
          },
          "max": {
            "type": "integer"
          },
          "customData": {
            "nullable": true,
            "type": "object"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "created",
          "modified"
        ]
      },
      "inventory-item-resource": {
        "title": "Inventory item resource",
        "type": "object",
        "description": "The definition for a economy resource that represents a inventory item.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50,
            "description": "Identifier for the resource."
          },
          "name": {
            "type": "string",
            "description": "Name of the resource."
          },
          "type": {
            "type": "string",
            "description": "Type of the resource, for example `CURRENCY`, `INVENTORY_ITEM`, `VIRTUAL_PURCHASE`, `MONEY_PURCHASE`.",
            "enum": [
              "INVENTORY_ITEM"
            ]
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "customData": {
            "type": "object",
            "nullable": true
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "created",
          "modified"
        ]
      },
      "virtual-purchase-resource": {
        "title": "Virtual purchase resource",
        "type": "object",
        "description": "The definition for a economy resource that represents a virtual purchase.",
        "properties": {
          "id": {
            "type": "string",
            "pattern": "^[A-Z0-9_-]+$",
            "maxLength": 50,
            "description": "Identifier for the resource."
          },
          "name": {
            "type": "string",
            "description": "Name of the resource."
          },
          "type": {
            "type": "string",
            "enum": [
              "VIRTUAL_PURCHASE"
            ],
            "description": "Type of the item, for example `CURRENCY`, `INVENTORY_ITEM`, `VIRTUAL_PURCHASE`, `MONEY_PURCHASE`."
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "costs": {
            "type": "array",
            "description": "The costs deducted from the player when making the purchase. A cost is an ID of a currency or inventory item, plus an amount.",
            "items": {
              "$ref": "#/components/schemas/cost"
            }
          },
          "rewards": {
            "type": "array",
            "description": "The rewards credited to the player when making the purchase. A reward is composed of the ID of a currency or inventory item, the amount of that currency or item, and the default instance data (for inventory items).",
            "items": {
              "$ref": "#/components/schemas/reward"
            }
          },
          "customData": {
            "nullable": true,
            "type": "object"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "created",
          "modified"
        ]
      },
      "real-money-purchase-resource": {
        "title": "Real money purchase resource",
        "type": "object",
        "description": "The definition for a economy resource that represents a real money purchase.",
        "properties": {
          "id": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9_-]+$",
            "description": "ID of the resource."
          },
          "name": {
            "type": "string",
            "maxLength": 50,
            "description": "A descriptive name for the resource."
          },
          "type": {
            "type": "string",
            "enum": [
              "MONEY_PURCHASE"
            ],
            "description": "Type of the item, for example `CURRENCY`, `INVENTORY_ITEM`, `VIRTUAL_PURCHASE`, `MONEY_PURCHASE`."
          },
          "storeIdentifiers": {
            "type": "object",
            "minProperties": 1,
            "description": "Store identifiers.",
            "properties": {
              "appleAppStore": {
                "type": "string",
                "description": "Apple App Store identifier."
              },
              "googlePlayStore": {
                "type": "string",
                "description": "Google Play Store identifier."
              }
            }
          },
          "rewards": {
            "type": "array",
            "description": "The rewards credited to the player when making the purchase. A reward is composed of the ID of a currency or inventory item, the amount of that currency or item, and the default instance data (for inventory items).",
            "minItems": 0,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/reward"
            }
          },
          "customData": {
            "type": "object",
            "nullable": true,
            "description": "Max size when serialised 5 KB."
          },
          "created": {
            "$ref": "#/components/schemas/modified-metadata"
          },
          "modified": {
            "$ref": "#/components/schemas/modified-metadata"
          }
        },
        "required": [
          "id",
          "name",
          "type",
          "storeIdentifiers",
          "rewards",
          "customData",
          "created",
          "modified"
        ]
      },
      "cost": {
        "type": "object",
        "properties": {
          "resourceId": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9-_]+$",
            "description": "The ID of the currency or inventory item that is deducted as part of the purchase."
          },
          "amount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 999999999999999,
            "description": "The amount of the item deducted as part of the purchase."
          }
        },
        "required": [
          "resourceId",
          "amount"
        ]
      },
      "reward": {
        "type": "object",
        "properties": {
          "resourceId": {
            "type": "string",
            "maxLength": 50,
            "pattern": "^[A-Z0-9-_]+$",
            "description": "The ID of a currency or inventory item resource that is credited as part of the purchase."
          },
          "amount": {
            "type": "integer",
            "minimum": 1,
            "maximum": 999999999999999,
            "description": "The amount of the resource credited as part of the purchase."
          },
          "defaultInstanceData": {
            "type": "object",
            "nullable": true,
            "deprecated": true,
            "description": "When the reward is an inventory item resource, this specifies instance data automatically saved against the new inventory item. Max size when serialised 5 KB. This property has been deprecated and will only return \"null\"."
          }
        },
        "required": [
          "resourceId",
          "amount"
        ]
      }
    },
    "responses": {
      "error-response-bad-request": {
        "description": "Bad Request. Returned code indicates one of:\n   - Request parameter validation failure\n   - Other\n See the response schema for more details",
        "content": {
          "application/problem+json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/basic-error-response"
                },
                {
                  "$ref": "#/components/schemas/validation-error-response"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "problems/basic": "#/components/schemas/basic-error-response",
                  "problems/validation": "#/components/schemas/validation-error-response"
                }
              }
            }
          }
        }
      },
      "error-response-unprocessable-entity-currency-max-exceeded": {
        "description": "Unprocessable entity\n- Currency maximum would be exceeded",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-unprocessable-entity-currency-insufficient-funds": {
        "description": "Unprocessable entity\n- Insufficient funds",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-unprocessable-entity-inventory-instance-limit": {
        "description": "Instance limit",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-unprocessable-entity-virtual-purchase": {
        "description": "Unprocessable entity\n- Costs not met\n- Currency maximum would be exceeded\n- Instance limit",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-unprocessable-entity-apple-purchase": {
        "description": "Unprocessable entity\n- Currency maximum would be exceeded\n- Receipt Product ID does not match configuration\n- Configuration does not include a product ID for this IAP provider\n- Instance limit",
        "content": {
          "application/problem+json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/error-response-purchase-appleappstore-failed"
                },
                {
                  "$ref": "#/components/schemas/basic-error-response"
                }
              ],
              "discriminator": {
                "propertyName": "code",
                "mapping": {
                  "1007": "#/components/schemas/basic-error-response",
                  "1008": "#/components/schemas/basic-error-response",
                  "10201": "#/components/schemas/error-response-purchase-appleappstore-failed",
                  "10502": "#/components/schemas/error-response-purchase-appleappstore-failed",
                  "10503": "#/components/schemas/error-response-purchase-appleappstore-failed",
                  "10506": "#/components/schemas/error-response-purchase-appleappstore-failed",
                  "10507": "#/components/schemas/error-response-purchase-appleappstore-failed"
                }
              }
            }
          }
        }
      },
      "error-response-unprocessable-entity-google-purchase": {
        "description": "Unprocessable entity\n- Currency maximum would be exceeded\n- Receipt Product ID does not match configuration\n- Configuration does not include a product ID for this IAP provider\n- Instance limit",
        "content": {
          "application/problem+json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/error-response-purchase-googleplaystore-failed"
                },
                {
                  "$ref": "#/components/schemas/basic-error-response"
                }
              ],
              "discriminator": {
                "propertyName": "code",
                "mapping": {
                  "1007": "#/components/schemas/basic-error-response",
                  "1008": "#/components/schemas/basic-error-response",
                  "8004": "#/components/schemas/basic-error-response",
                  "10201": "#/components/schemas/error-response-purchase-googleplaystore-failed",
                  "10502": "#/components/schemas/error-response-purchase-googleplaystore-failed",
                  "10503": "#/components/schemas/error-response-purchase-googleplaystore-failed",
                  "10506": "#/components/schemas/error-response-purchase-googleplaystore-failed",
                  "10507": "#/components/schemas/error-response-purchase-googleplaystore-failed"
                }
              }
            }
          }
        }
      },
      "error-response-conflict-currency-balance": {
        "description": "Conflict \n- Write lock does not match",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/error-response-conflict-currency-balance"
            }
          }
        }
      },
      "error-response-conflict-inventory": {
        "description": "Conflict\n- Write lock does not match\n- Instance with `playersInventoryItemId` already exists",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/error-response-conflict-inventory"
            }
          }
        }
      },
      "error-response-conflict-inventory-update": {
        "description": "Conflict\n- Write lock does not match",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/error-response-conflict-inventory-update"
            }
          }
        }
      },
      "error-response-conflict-inventory-delete": {
        "description": "Conflict\n- Write lock does not match",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/error-response-conflict-inventory-delete"
            }
          }
        }
      },
      "error-response-forbidden": {
        "description": "Forbidden",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-not-found": {
        "description": "Not Found",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-service-unavailable-datastore": {
        "description": "Service Unavailable\n- Unable to acquire lock on resources\n- Datastore unavailable",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-service-unavailable": {
        "description": "Service Unavailable",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      },
      "error-response-too-many-requests": {
        "description": "Too Many Requests",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "number"
            },
            "description": "The number of seconds until a request is accepted."
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/basic-error-response"
            }
          }
        }
      }
    },
    "parameters": {
      "projectId": {
        "name": "projectId",
        "in": "path",
        "description": "ID of the project.",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "playerId": {
        "name": "playerId",
        "in": "path",
        "description": "ID of the player.",
        "required": true,
        "schema": {
          "type": "string"
        }
      },
      "configAssignmentHash": {
        "name": "configAssignmentHash",
        "in": "query",
        "description": "Configuration assignment hash that should be used when processing this request.",
        "schema": {
          "type": "string"
        }
      },
      "installationId": {
        "name": "unity-installation-id",
        "in": "header",
        "description": "Unique identifier that identifies an installation on the client’s device. The same player can have different installationIds if they have the game installed on different devices. It is available to all Unity packages that integrate with the Services SDK Core package.",
        "schema": {
          "type": "string"
        }
      },
      "writeLock": {
        "name": "writeLock",
        "in": "query",
        "description": "The writelock for a database entry.",
        "schema": {
          "type": "string"
        }
      },
      "analyticsUserId": {
        "name": "analytics-user-id",
        "in": "header",
        "description": "A unique string that identifies the player and is consistent across their subsequent play sessions for analytics purposes. It is the primary user identifier and it comes from the Core package.",
        "schema": {
          "type": "string"
        }
      }
    },
    "securitySchemes": {
      "Client": {
        "type": "http",
        "scheme": "bearer",
        "description": "To get started with Authentication, please visit the [Client Authentication section](https://services.docs.unity.com/docs/client-auth)."
      }
    }
  },
  "x-tagGroups": [
    {
      "name": "Endpoints",
      "tags": [
        "Configuration",
        "Currencies",
        "Inventory",
        "Purchases"
      ]
    }
  ]
}
```