

```json
{
  "openapi": "3.0.0",
  "info": {
    "title": "Cloud Save Data",
    "version": "1.0",
    "description": "# Introduction\nThis is the API specification for the Unity Cloud Save service that allows player or custom non-player state to be accessed and persisted from a game client.\nThe Player State API allows data to be stored against a specific player ID. Access using client authentication is limited to the specified player for both data reads and writes.\nThe Game State API allows data to be stored against a custom ID provided by the user. All players are able to read the data from the custom ID using client authentication, but write operations are limited to Service Account authentication.\nTo use this API, you must first enable it through the Unity Gaming Services dashboard.\n\n# General Information\n**Cloud Save Data** is for storing small blobs of JSON serializable data, stored as key/value pairs.\nIt can store data against a player ID (referred to as Player State) or a custom ID (referred to as Game State). The custom ID is a string that can be used to store data against a non-player entity, but the client API is restricted to read-only access.\nIn addition to the default access levels for player and game state, data can be stored in public player state, protected player state, or private game state. The access details are as follows:\n- Default Player State: Player-writable and player-readable, by the player the data corresponds to\n- Public Player State: Player-writable by the player the data corresponds to, and readable by any player (e.g. public player profile data)\n- Protected Player State: Server-writable only, and player-readable by the player the data corresponds to\n- Default Game State: Server-writable only, player-readable by any player\n- Private Game State: Server-writable and server-readable only\n\nThe maximum size for player or custom data is 5 MB across all key/value pairs for that player and access class. A player can have data in a single slot that is up to 5 MB in size, or use many slots that equal to less than 5 MB in total size.\nLimits:\n- Maximum 255 characters per slot name\n- Maximum 2000 data slots per player or custom ID per access class\n- Maximum 5 MB in size per player or custom ID per access class across all slots\n\n## Rate Limits\nThe API has rate limiting in place. The endpoints are limited to 600 requests per minute on a per-player basis.\nThe query endpoints (paths ending in `/query`) are additionally subject to a per-project limit of 6000 requests per minute, shared across all callers of a project. As a result, a query request may receive a `429` due to the per-project limit even when the individual player is within the 600/minute per-player limit.\nThe API responds with a `429` HTTP status code if a rate limit is exceeded.\nIt will also respond with a `Retry-After` header to be used in conjunction with a client's retry logic. The value is the number of seconds until the request will be accepted.\n",
    "contact": {
      "name": "Cloud Save Team",
      "url": "https://discussions.unity.com/tag/cloud-save"
    }
  },
  "tags": [
    {
      "name": "Data",
      "description": "Associated with the Cloud Save Data service."
    }
  ],
  "servers": [
    {
      "url": "https://cloud-save.services.api.unity.com/v1/data"
    }
  ],
  "security": [
    {
      "Client": []
    },
    {
      "ServiceAccount": []
    }
  ],
  "x-anchors": {
    "playerAuthRules": [
      {
        "authorizationType": "token",
        "resourceId": "projectId",
        "resourceType": "project"
      },
      {
        "authorizationType": "entitlement",
        "productCodes": [
          "CLD-SAV-BUNDL"
        ],
        "source": "token",
        "resourceType": "project",
        "isGatedFreeTierAccessAllowed": true,
        "isFreeTierGracePeriodEnabled": true
      },
      {
        "authorizationType": "audience",
        "audience": "cloud-save",
        "applyTo": {
          "authenticationType": [
            "jwt"
          ],
          "issuers": [
            "player-auth"
          ]
        }
      }
    ],
    "readBillingEvents": {
      "events": [
        {
          "service": "cloud-save-data",
          "sku": "UGS",
          "uom": "Cloud Save - Reads",
          "qtySource": "number",
          "qty": 1,
          "parameters": [
            {
              "source": "path",
              "resourceType": "project",
              "resourceId": "projectId"
            }
          ]
        }
      ]
    },
    "writeBillingEvents": {
      "events": [
        {
          "service": "cloud-save-data",
          "sku": "UGS",
          "uom": "Cloud Save - Writes",
          "qtySource": "number",
          "qty": 1,
          "parameters": [
            {
              "source": "path",
              "resourceType": "project",
              "resourceId": "projectId"
            }
          ]
        }
      ]
    }
  },
  "paths": {
    "/projects/{projectId}/players/{playerId}/all/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Set Player Item Batch Across Access Classes",
        "operationId": "setCrossAccessClassItemBatch",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Set up to 100 data items with key, value and optional writeLock for the given player, across multiple access classes.\nThe values are limited to a maximum size of 5 MB per access level slots for the player.\nSaved state for each access level for a player is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic per access class, but may succeed on one access class and fail on another.\nError responses should identify the affected key operations that failed.\n",
        "requestBody": {
          "description": "Add data items in multiple access classes to store for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetCrossAccessClassItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetCrossAccessClassItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/all/item-request": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Get Player Items Across Access Classes",
        "operationId": "getCrossAccessClassItems",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Retrieves saved data values for all keys specified, across access classes.\nLimited to a maximum of 100 keys across all access classes.\n",
        "requestBody": {
          "description": "Request data items from multiple access classes for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetCrossAccessClassItemsBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetCrossAccessClassItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Player Items",
        "operationId": "getItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves saved data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Player Item",
        "operationId": "setItem",
        "tags": [
          "Data"
        ],
        "description": "Set a data item with a given key and value for the specified player.\nThe value is limited to a maximum size of 5 MB across all default access level slots.\nThe entire default access level saved state for a player is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\n",
        "requestBody": {
          "description": "Add a data item to store for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Player Items",
        "operationId": "deleteItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all default access level data associated with a given player.\n",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Player Keys",
        "operationId": "getKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of keys for the given player, ordered alphabetically in pages of 100.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Player Item",
        "operationId": "deleteItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a data item by the specified key for the given player.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Set Player Item Batch",
        "operationId": "setItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 data items with key, value and optional writeLock for the given player. The values are limited to a maximum size of 5 MB across all default access level slots for the player.\nThe entire default access level saved state for a player is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.",
        "requestBody": {
          "description": "Set batch data items for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/public/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Public Player Items",
        "operationId": "getPublicItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves saved data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\nAccessible by any player for any other player's data.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Public Player Item",
        "operationId": "setPublicItem",
        "tags": [
          "Data"
        ],
        "description": "Set a public data item with a given key and value for the specified player.\nThe value is limited to a maximum size of 5 MB across all public access level slots.\nThe entire public saved state for a player is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\nThe value set will be publicly readable by any player.\n",
        "requestBody": {
          "description": "Add a data item to store for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Public Player Items",
        "operationId": "deletePublicItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all public data associated with a given player.\n",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/public/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Public Player Keys",
        "operationId": "getPublicKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of public keys for the given player, ordered alphabetically in pages of 100. Accessible by any player for any other player's data.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/public/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Public Player Item",
        "operationId": "deletePublicItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a public data item by the specified key for the given player.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/public/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Set Public Player Item Batch",
        "operationId": "setPublicItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 public data items with key, value and optional writeLock for the given player. The values are limited to a maximum size of 5 MB across all slots for the player.\nThe entire public saved state for a player is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.",
        "requestBody": {
          "description": "Set batch data items for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/protected/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Protected Player Items",
        "operationId": "getProtectedItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves protected save data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Protected Player Item",
        "operationId": "setProtectedItem",
        "tags": [
          "Data"
        ],
        "description": "Set a protected data item with a given key and value for the specified player.\nThe value is limited to a maximum size of 5 MB across all protected access level slots.\nThe entire protected saved state for a player is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Add a data item to store for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Protected Player Items",
        "operationId": "deleteProtectedItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all protected data associated with a given player. Only accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/protected/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Protected Player Keys",
        "operationId": "getProtectedKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of protected keys for the given player, ordered alphabetically in pages of 100.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/protected/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Protected Player Item",
        "operationId": "deleteProtectedItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a protected data item by the specified key for the given player. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/protected/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Set Protected Player Item Batch",
        "operationId": "setProtectedItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 protected data items with key, value and optional writeLock for the given player. The values are limited to a maximum size of 5 MB across all slots for the player.\nThe entire protected saved state for a player is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.\nOnly accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Set batch data items for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/private/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Private Player Items",
        "operationId": "getPrivateItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves private save data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Private Player Item",
        "operationId": "setPrivateItem",
        "tags": [
          "Data"
        ],
        "description": "Set a private data item with a given key and value for the specified player.\nThe value is limited to a maximum size of 5 MB across all private access level slots.\nThe entire private saved state for a player is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Add a data item to store for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Private Player Items",
        "operationId": "deletePrivateItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all private data associated with a given player. Only accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/private/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "get": {
        "summary": "Get Private Player Keys",
        "operationId": "getPrivateKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of private keys for the given player, ordered alphabetically in pages of 100. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/private/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Private Player Item",
        "operationId": "deletePrivateItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a private data item by the specified key for the given player. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock.\nOnly accessible via an authenticated server authority."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/{playerId}/private/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/PlayerId"
        }
      ],
      "post": {
        "summary": "Set Private Player Item Batch",
        "operationId": "setPrivateItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 private data items with key, value and optional writeLock for the given player. The values are limited to a maximum size of 5 MB across all slots for the player.\nThe entire private saved state for a player is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.\nOnly accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Set batch data items for a player.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/all/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "post": {
        "summary": "Set Custom Item Batch Across Access Classes",
        "operationId": "setCrossAccessClassCustomItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 100 data items with key, value and optional writeLock for the given custom ID, across multiple access classes.\nThe values are limited to a maximum size of 5 MB per access level slots for the custom ID.\nSaved state for each access level for a custom ID is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic per access class, but may succeed on one access class and fail on another.\nError responses should identify the affected key operations that failed.\n",
        "requestBody": {
          "description": "Add data items in multiple access classes to store for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetCrossAccessClassCustomItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetCrossAccessClassCustomItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/all/item-request": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "post": {
        "summary": "Get Custom Items Across Access Classes",
        "operationId": "getCrossAccessClassCustomItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves saved data values for all keys specified, across access classes.\nLimited to a maximum of 100 keys across all access classes.\n",
        "requestBody": {
          "description": "Request data items from multiple access classes for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/GetCrossAccessClassCustomItemsBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetCrossAccessClassCustomItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "get": {
        "summary": "Get Custom Items",
        "operationId": "getCustomItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves saved data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Custom Item",
        "operationId": "setCustomItem",
        "tags": [
          "Data"
        ],
        "description": "Set a data item with a given key and value for the specified custom ID.\nThe value is limited to a maximum size of 5 MB across all default access level slots.\nThe entire default access level saved state for a custom ID is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Add a data item to store for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Custom Items",
        "operationId": "deleteCustomItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all default access level data associated with a given custom ID. Only accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "get": {
        "summary": "Get Custom Keys",
        "operationId": "getCustomKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of keys for the given custom ID, ordered alphabetically in pages of 100.",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Custom Item",
        "operationId": "deleteCustomItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a data item by the specified key for the specified custom ID. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "post": {
        "summary": "Set Custom Item Batch",
        "operationId": "setCustomItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 data items with key, value and optional writeLock against the custom ID. The values are limited to a maximum size of 5 MB across all default access level slots for the custom ID.\nThe entire default access level saved state for a custom ID is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.\nOnly accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Set batch data items for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/private/items": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "get": {
        "summary": "Get Private Custom Items",
        "operationId": "getPrivateCustomItems",
        "tags": [
          "Data"
        ],
        "description": "Retrieves private save data values for all keys specified, ordered alphabetically in pages of 20.\nIf no keys are supplied then returns all keys, ordered alphabetically in pages of 20.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/KeyList"
            },
            "in": "query",
            "name": "keys",
            "description": "The keys to retrieve, in exploded form style, e.g. `keys=KEY1&keys=KEY2&keys=KEY3`.",
            "style": "form",
            "explode": true
          },
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "after",
            "description": "The key after which to retrieve the next page of keys."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetItemsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "post": {
        "summary": "Set Private Custom Item",
        "operationId": "setPrivateCustomItem",
        "tags": [
          "Data"
        ],
        "description": "Set a private data item with a given key and value for the specified custom ID.\nThe value is limited to a maximum size of 5 MB across all private access level slots.\nThe entire private saved state for a custom ID is limited to 2000 keys.\nAttempting to set a new key beyond this limit will result in an error.\nOnly accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Add a data item to store for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/Conflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      },
      "delete": {
        "summary": "Delete Private Custom Items",
        "operationId": "deletePrivateCustomItems",
        "tags": [
          "Data"
        ],
        "description": "Deletes all private data associated with a given custom ID. Only accessible via an authenticated server authority.\n",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/private/keys": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "get": {
        "summary": "Get Private Custom Keys",
        "operationId": "getPrivateCustomKeys",
        "tags": [
          "Data"
        ],
        "description": "Gets a paged list of private keys for the given custom ID, ordered alphabetically in pages of 100. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/Key"
            },
            "in": "query",
            "name": "after",
            "description": "Returns the page of results after the key specified."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetKeysResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "404": {
            "$ref": "#/components/responses/NotFound"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/private/items/{key}": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        },
        {
          "$ref": "#/components/parameters/Key"
        }
      ],
      "delete": {
        "summary": "Delete Private Custom Item",
        "operationId": "deletePrivateCustomItem",
        "tags": [
          "Data"
        ],
        "description": "Deletes a private data item by the specified key for the specified custom ID. Only accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/schemas/WriteLock"
            },
            "in": "query",
            "name": "writeLock",
            "description": "Enforces conflict checking when deleting an existing data item.\nOmitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock."
          }
        ],
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/DeleteConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/{customId}/private/item-batch": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        },
        {
          "$ref": "#/components/parameters/CustomId"
        }
      ],
      "post": {
        "summary": "Set Private Custom Item Batch",
        "operationId": "setPrivateCustomItemBatch",
        "tags": [
          "Data"
        ],
        "description": "Set up to 20 private data items with key, value and optional writeLock against the custom ID. The values are limited to a maximum size of 5 MB across all private access level slots for the custom ID.\nThe entire private saved state for a custom ID is limited to 2000 keys. Attempting to set a new key beyond this limit will result in an error.\nThe batch set operation is considered atomic and if any of the set key operation fails, the entire operation is failed. Error responses should identify the affected key operations that failed.\nOnly accessible via an authenticated server authority.",
        "security": [
          {
            "ServiceAccount": []
          }
        ],
        "requestBody": {
          "description": "Set batch data items for a custom ID.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/SetItemBatchBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/SetItemBatchResponse"
                }
              }
            }
          },
          "400": {
            "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/BasicErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/ValidationErrorResponse"
                    },
                    {
                      "$ref": "#/components/schemas/BatchBasicErrorResponse"
                    }
                  ],
                  "discriminator": {
                    "propertyName": "type",
                    "mapping": {
                      "problems/basic": "#/components/schemas/BasicErrorResponse",
                      "problems/validation": "#/components/schemas/ValidationErrorResponse",
                      "problems/batch-basic": "#/components/schemas/BatchBasicErrorResponse",
                      "problems/batch-validation": "#/components/schemas/BatchValidationErrorResponse"
                    }
                  }
                }
              }
            }
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "409": {
            "$ref": "#/components/responses/BatchConflict"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Default Player Data",
        "operationId": "queryDefaultPlayerData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query player data with the default access class. If no index is available to fulfil the query then the query will fail.\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/protected/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Protected Player Data",
        "operationId": "queryProtectedPlayerData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query player data with the protected access class. If no index is available to fulfil the query then the query will fail.\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/private/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Private Player Data",
        "operationId": "queryPrivatePlayerData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query player data with the private access class. If no index is available to fulfil the query then the query will fail. Only accessible via an authenticated server authority.\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players/public/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Public Player Data",
        "operationId": "queryPublicPlayerData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          },
          {
            "Client": []
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query player data with the public access class. If no index is available to fulfil the query then the query will fail.\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Default Custom Data",
        "operationId": "queryDefaultCustomData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          },
          {
            "Client": []
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query custom data with the default access class. If no index is available to fulfil the query then the query will fail\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom/private/query": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "post": {
        "summary": "Query Private Custom Data",
        "operationId": "queryPrivateCustomData",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.indexes.get"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Query custom data with the private access class. If no index is available to fulfil the query then the query will fail.\n",
        "requestBody": {
          "description": "Query object with an array of conditions to query the data with.",
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/QueryIndexBody"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/QueryIndexResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/players": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "get": {
        "summary": "Get Players",
        "operationId": "getPlayers",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.entities.list"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Retrieves a paginated list of all players which have data set, ordered alphabetically by player ID, with metadata about their stored data.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/parameters/PlayerId"
            },
            "in": "query",
            "name": "start",
            "description": "The player ID to start the page from. If not specified, the first page will be returned."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "in": "query",
            "name": "limit",
            "description": "The maximum number of player data IDs to return. If not specified, the default limit of 20 will be used."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetPlayersResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    },
    "/projects/{projectId}/custom": {
      "parameters": [
        {
          "$ref": "#/components/parameters/ProjectId"
        }
      ],
      "get": {
        "summary": "Get Custom IDs",
        "operationId": "getCustomIDs",
        "security": [
          {
            "ServiceAccount": [
              "cloud_save.entities.list"
            ]
          }
        ],
        "tags": [
          "Data"
        ],
        "description": "Get a paginated list of all Game State custom data IDs for a given project and environment.\n",
        "parameters": [
          {
            "schema": {
              "$ref": "#/components/parameters/CustomId"
            },
            "in": "query",
            "name": "start",
            "description": "The custom data ID to start the page from. If not specified, the first page will be returned."
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 1,
              "maximum": 100
            },
            "in": "query",
            "name": "limit",
            "description": "The maximum number of custom data IDs to return. If not specified, the default limit of 20 will be used."
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/GetCustomIdsResponse"
                }
              }
            }
          },
          "400": {
            "$ref": "#/components/responses/BadRequest"
          },
          "401": {
            "$ref": "#/components/responses/Unauthorized"
          },
          "403": {
            "$ref": "#/components/responses/Forbidden"
          },
          "429": {
            "$ref": "#/components/responses/TooManyRequests"
          },
          "500": {
            "$ref": "#/components/responses/InternalServerError"
          },
          "503": {
            "$ref": "#/components/responses/ServiceUnavailable"
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "Client": {
        "type": "http",
        "scheme": "bearer",
        "description": "To get started with Authentication, please visit the\n[Client Authentication section](https://services.docs.unity.com/docs/client-auth)."
      },
      "ServiceAccount": {
        "type": "http",
        "scheme": "bearer",
        "description": "To get started with Authentication, please visit the\n[Service Account Authentication section](https://services.docs.unity.com/docs/service-account-auth).\nWhen using a Service Account, these APIs require exchanging Service Account credentials for\nan access token, please see the section about the\n[Token Exchange API](https://services.docs.unity.com/docs/service-account-auth/index.html#extra-step-use-the-token-exchange-api)."
      }
    },
    "parameters": {
      "ProjectId": {
        "name": "projectId",
        "in": "path",
        "description": "ID of the project.",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "8bdacc33-6eef-4577-beb0-633c86259f5b"
      },
      "PlayerId": {
        "name": "playerId",
        "in": "path",
        "description": "The player ID supplied by the Authorization service.",
        "required": true,
        "schema": {
          "type": "string"
        },
        "example": "s1QFdyYFXCC2YBocplKoLstxvQ2r"
      },
      "CustomId": {
        "name": "customId",
        "in": "path",
        "description": "The custom data ID specified by the user. Must be between 1 and 64 characters long and contain only alphanumeric characters, underscores, and hyphens.",
        "required": true,
        "schema": {
          "type": "string",
          "pattern": "^[A-Za-z0-9_-]{1,64}$"
        },
        "example": "my-custom-data-id"
      },
      "Key": {
        "name": "key",
        "in": "path",
        "description": "Item key.",
        "required": true,
        "schema": {
          "$ref": "#/components/schemas/Key"
        }
      }
    },
    "schemas": {
      "Key": {
        "title": "Key",
        "type": "string",
        "pattern": "^[A-Za-z0-9_-]{1,255}$",
        "description": "Item key",
        "minLength": 1,
        "maxLength": 255,
        "example": "EXAMPLE_KEY"
      },
      "KeyList": {
        "title": "KeyList",
        "type": "array",
        "description": "List of keys",
        "items": {
          "$ref": "#/components/schemas/Key"
        }
      },
      "Value": {
        "title": "Value",
        "type": "object",
        "description": "Any JSON serializable structure with a maximum size of 5 MB."
      },
      "WriteLock": {
        "title": "WriteLock",
        "type": "string",
        "description": "Enforces conflict checking when updating an existing data item. This field should be omitted when creating a new data item.\nWhen updating an existing item, omitting this field ignores write conflicts. When present, an error response will be returned if the writeLock in the request does not match the stored writeLock.\nThe writeLock is an opaque value: send back the value returned by this API without changing or interpreting it.",
        "example": "efac747f6fb244569efef962ca9dc30e"
      },
      "ModifiedMetadata": {
        "title": "ModifiedMetadata",
        "type": "object",
        "description": "Timestamp for when the object was modified.",
        "properties": {
          "date": {
            "$ref": "#/components/schemas/IsoDate"
          }
        },
        "required": [
          "date"
        ]
      },
      "IsoDate": {
        "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"
      },
      "PlayerId": {
        "title": "Player ID",
        "description": "The player ID supplied by the Authorization service.",
        "type": "string",
        "example": "s1QFdyYFXCC2YBocplKoLstxvQ2r"
      },
      "CustomId": {
        "title": "Custom Data ID",
        "description": "The custom data ID defined by the user.",
        "type": "string",
        "example": "my-custom-data-id"
      },
      "SetCrossAccessClassItemBatchBody": {
        "title": "SetCrossAccessClassItemBatchBody",
        "type": "object",
        "properties": {
          "default": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          },
          "public": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          },
          "protected": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          },
          "private": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          }
        }
      },
      "SetCrossAccessClassCustomItemBatchBody": {
        "title": "SetCrossAccessClassCustomItemBatchBody",
        "type": "object",
        "properties": {
          "default": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          },
          "private": {
            "$ref": "#/components/schemas/SetItemBatchBody"
          }
        }
      },
      "SetCrossAccessClassItemBatchResponse": {
        "title": "SetCrossAccessClassItemBatchResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "object",
            "properties": {
              "default": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              },
              "public": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              },
              "protected": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              },
              "private": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              }
            }
          }
        }
      },
      "SetCrossAccessClassCustomItemBatchResponse": {
        "title": "SetCrossAccessClassCustomItemBatchResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "object",
            "properties": {
              "default": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              },
              "private": {
                "$ref": "#/components/schemas/SetItemBatchResponse"
              }
            }
          }
        }
      },
      "GetCrossAccessClassItemsBody": {
        "title": "GetCrossAccessClassItemsBody",
        "type": "object",
        "properties": {
          "default": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          },
          "public": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          },
          "protected": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          },
          "private": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          }
        }
      },
      "GetCrossAccessClassCustomItemsBody": {
        "title": "GetCrossAccessClassCustomItemsBody",
        "type": "object",
        "properties": {
          "default": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          },
          "private": {
            "$ref": "#/components/schemas/AccessClassKeyList"
          }
        }
      },
      "AccessClassKeyList": {
        "title": "AccessClassKeyList",
        "type": "object",
        "properties": {
          "keys": {
            "$ref": "#/components/schemas/KeyList"
          }
        }
      },
      "GetCrossAccessClassItemsResponse": {
        "title": "GetCrossAccessClassItemsResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "object",
            "properties": {
              "default": {
                "$ref": "#/components/schemas/AccessClassData"
              },
              "public": {
                "$ref": "#/components/schemas/AccessClassData"
              },
              "protected": {
                "$ref": "#/components/schemas/AccessClassData"
              },
              "private": {
                "$ref": "#/components/schemas/AccessClassData"
              }
            }
          }
        }
      },
      "GetCrossAccessClassCustomItemsResponse": {
        "title": "GetCrossAccessClassCustomItemsResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "object",
            "properties": {
              "default": {
                "$ref": "#/components/schemas/AccessClassData"
              },
              "private": {
                "$ref": "#/components/schemas/AccessClassData"
              }
            }
          }
        }
      },
      "AccessClassData": {
        "title": "AccessClassData",
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "minItems": 0,
            "maxItems": 100,
            "description": "Data values for given keys, ordered alphabetically.",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          }
        }
      },
      "QueryIndexResponse": {
        "title": "QueryIndexResponse",
        "description": "The response to an index query request containing a list of the resulting entity IDs and their associated data.",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "description": "The entity ID",
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/PlayerId"
                    },
                    {
                      "$ref": "#/components/schemas/CustomId"
                    }
                  ]
                },
                "data": {
                  "type": "array",
                  "description": "The list of data key-value pairs for the entity",
                  "items": {
                    "$ref": "#/components/schemas/Item"
                  }
                }
              }
            }
          }
        }
      },
      "Item": {
        "title": "Item",
        "type": "object",
        "description": "Response type for a Data Item stored in the Cloud Save service.",
        "properties": {
          "key": {
            "$ref": "#/components/schemas/Key"
          },
          "value": {
            "$ref": "#/components/schemas/Value"
          },
          "writeLock": {
            "$ref": "#/components/schemas/WriteLock"
          },
          "modified": {
            "$ref": "#/components/schemas/ModifiedMetadata"
          },
          "created": {
            "$ref": "#/components/schemas/ModifiedMetadata"
          }
        },
        "required": [
          "key",
          "value",
          "writeLock",
          "modified",
          "created"
        ]
      },
      "GetItemsResponse": {
        "title": "GetItemsResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "minItems": 0,
            "maxItems": 20,
            "description": "Data values for all keys, ordered alphabetically in pages of 20.",
            "items": {
              "$ref": "#/components/schemas/Item"
            }
          },
          "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"
        ]
      },
      "BaseErrorResponse": {
        "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 (e.g., 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 (e.g., 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",
            "nullable": true,
            "description": "A URI reference that identifies the specific occurrence of the problem. It may or may not yield further information if dereferenced."
          }
        },
        "required": [
          "type"
        ]
      },
      "BasicErrorResponse": {
        "title": "BasicErrorResponse",
        "description": "Referenced from - https://tools.ietf.org/html/rfc7807#page-3\nConsumers 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 (e.g., offline log analysis). Consumers SHOULD NOT automatically dereference the type URI.\nThe \"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.\nConsumers can use the status member to determine what the original status code used by the generator was, in cases where it has been changed (e.g., by an intermediary or cache), and when message bodies persist without HTTP information.  Generic HTTP software will still use the HTTP status code.\nThe \"detail\" member, if present, ought to focus on helping the client correct the problem, rather than giving debugging information.\n",
        "type": "object",
        "example": {
          "type": "problems/basic",
          "title": "service unavailable",
          "status": 500,
          "code": 1000,
          "detail": "service unavailable",
          "details": [
            {
              "health": [
                "service health ping failed"
              ]
            }
          ]
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseErrorResponse"
          },
          {
            "properties": {
              "details": {
                "type": "array",
                "description": "Machine readable service specific errors.",
                "items": {
                  "type": "object"
                }
              }
            }
          }
        ]
      },
      "ValidationErrorResponse": {
        "title": "ValidationErrorResponse",
        "type": "object",
        "description": "Validation error response when a value provided from the client does not pass validation on server.",
        "example": {
          "type": "problems/validation",
          "title": "validation error",
          "status": 400,
          "detail": "See 'errors' for specific validation errors",
          "code": 1009,
          "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/ValidationErrorBody"
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "errors"
        ]
      },
      "ValidationErrorBody": {
        "title": "ValidationErrorBody",
        "type": "object",
        "properties": {
          "field": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "field",
          "messages"
        ],
        "description": "Single error in the Validation Error Response."
      },
      "SetItemBody": {
        "title": "SetItemBody",
        "type": "object",
        "description": "Request type for a Data Item to store in the Cloud Save service.",
        "properties": {
          "key": {
            "description": "The key will be created if it does not exist, provided the item limit of 2000 keys has not been reached for this entity.",
            "allOf": [
              {
                "$ref": "#/components/schemas/Key"
              }
            ]
          },
          "value": {
            "$ref": "#/components/schemas/Value"
          },
          "writeLock": {
            "$ref": "#/components/schemas/WriteLock"
          }
        },
        "example": {
          "key": "ItemKey",
          "value": {
            "Health": 87,
            "Array": [
              23,
              12,
              123
            ],
            "Object": {
              "weapon": "Sword",
              "damage": 3,
              "durability": 46
            },
            "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0"
          }
        },
        "required": [
          "key",
          "value"
        ]
      },
      "SetItemResponse": {
        "title": "SetItemResponse",
        "type": "object",
        "description": "Newly generated writeLock for the item.",
        "properties": {
          "writeLock": {
            "$ref": "#/components/schemas/WriteLock"
          }
        },
        "required": [
          "writeLock"
        ]
      },
      "AttemptedItem": {
        "title": "AttemptedItem",
        "type": "object",
        "description": "Response type for an attempted Data Item sent to the Cloud Save service.",
        "properties": {
          "key": {
            "$ref": "#/components/schemas/Key"
          },
          "value": {
            "$ref": "#/components/schemas/Value"
          },
          "writeLock": {
            "$ref": "#/components/schemas/WriteLock"
          }
        },
        "example": {
          "key": "KEY1",
          "value": {
            "value": "data"
          },
          "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0"
        },
        "required": [
          "key",
          "value",
          "writeLock"
        ]
      },
      "ConflictErrorResponseData": {
        "title": "ConflictErrorResponseData",
        "description": "A human-readable explanation specific to this occurrence of the problem.",
        "type": "object",
        "properties": {
          "attempted": {
            "$ref": "#/components/schemas/AttemptedItem"
          },
          "existing": {
            "$ref": "#/components/schemas/Item"
          }
        }
      },
      "ConflictErrorResponse": {
        "title": "ConflictErrorResponse",
        "type": "object",
        "description": "An error sent back upon resource conflict.",
        "example": {
          "type": "problems/data/conflict",
          "title": "conflict error",
          "status": 409,
          "code": 1004,
          "detail": "WriteLock in data item update request does not match stored WriteLock",
          "data": {
            "attempted": {
              "key": "ItemKey",
              "value": {
                "value": "new data"
              },
              "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0"
            },
            "existing": {
              "key": "ItemKey",
              "value": {
                "value": "old data"
              },
              "writeLock": "2509f6b5cbb187b8920a57913eb7fcb0",
              "modified": {
                "date": "2020-02-22T20:20:20Z"
              },
              "created": {
                "date": "2020-01-20T20:20:20Z"
              }
            }
          }
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseErrorResponse"
          },
          {
            "properties": {
              "data": {
                "$ref": "#/components/schemas/ConflictErrorResponseData"
              }
            }
          }
        ],
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "DeleteConflictErrorResponse": {
        "title": "ConflictErrorResponse",
        "type": "object",
        "description": "An error sent back upon resource conflict.",
        "example": {
          "type": "problems/data/conflict",
          "title": "conflict error",
          "status": 409,
          "code": 1004,
          "detail": "WriteLock in data item update request does not match stored WriteLock",
          "data": {
            "key": "KEY1",
            "attemptedWriteLock": "2509f6b5cbb187b8920a57913eb7fcb0",
            "existingWriteLock": "7b8920a57912509f6b5cbb183eb7fcb0"
          }
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseErrorResponse"
          },
          {
            "properties": {
              "data": {
                "type": "object",
                "description": "A human-readable explanation specific to this occurrence of the problem.",
                "properties": {
                  "key": {
                    "type": "string"
                  },
                  "attemptedWriteLock": {
                    "type": "string"
                  },
                  "existingWriteLock": {
                    "type": "string"
                  }
                }
              }
            }
          }
        ],
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "KeyMetadata": {
        "title": "KeyMetadata",
        "type": "object",
        "description": "Response type Key with metadata for an individual data item stored in the Cloud Save service.",
        "example": {
          "key": "KEY1",
          "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0",
          "modified": {
            "date": "2020-02-20T20:20:20Z"
          }
        },
        "properties": {
          "key": {
            "$ref": "#/components/schemas/Key"
          },
          "writeLock": {
            "$ref": "#/components/schemas/WriteLock"
          },
          "modified": {
            "$ref": "#/components/schemas/ModifiedMetadata"
          }
        },
        "required": [
          "key",
          "writeLock",
          "modified"
        ]
      },
      "GetKeysResponse": {
        "title": "GetKeysResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "description": "A paged list of keys for the given player, ordered alphabetically in pages of 100.",
            "items": {
              "$ref": "#/components/schemas/KeyMetadata"
            }
          },
          "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"
        ]
      },
      "SetItemBatchBody": {
        "title": "SetItemBatchBody",
        "type": "object",
        "properties": {
          "data": {
            "type": "array",
            "minItems": 1,
            "maxItems": 20,
            "items": {
              "$ref": "#/components/schemas/SetItemBody"
            }
          }
        }
      },
      "SetItemBatchResponse": {
        "title": "SetItemBatchResponse",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "$ref": "#/components/schemas/Key"
                },
                "writeLock": {
                  "$ref": "#/components/schemas/WriteLock"
                }
              },
              "required": [
                "key",
                "writeLock"
              ]
            }
          }
        }
      },
      "BatchValidationErrorResponse": {
        "title": "BatchValidationErrorResponse",
        "type": "object",
        "description": "Batch validation error response when one or more values provided from the client does not pass validation on server",
        "example": {
          "type": "problems/batch-validation",
          "title": "batch-validation error",
          "status": 400,
          "code": 1014,
          "detail": "See 'errors' for specific validation errors",
          "errors": [
            {
              "key": "KEY_1",
              "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/BatchValidationErrorBody"
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "errors"
        ]
      },
      "BatchValidationErrorBody": {
        "title": "BatchValidationErrorBody",
        "type": "object",
        "description": "Single error in the Batch Validation Error Response.",
        "properties": {
          "field": {
            "type": "string"
          },
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "key": {
            "type": "string"
          }
        },
        "required": [
          "field",
          "messages",
          "key"
        ]
      },
      "BatchBasicErrorResponse": {
        "title": "BatchBasicErrorResponse",
        "type": "object",
        "description": "Batch basic error response when one or more values provided from the client fails some condition",
        "example": {
          "type": "problems/batch-basic",
          "title": "batch-basic error",
          "status": 404,
          "code": 1016,
          "detail": "See 'errors' for error details",
          "errors": [
            {
              "key": "KEY_1",
              "messages": [
                "data item not found"
              ]
            }
          ]
        },
        "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/BatchBasicErrorBody"
            }
          }
        },
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "errors"
        ]
      },
      "BatchBasicErrorBody": {
        "title": "BatchBasicErrorBody",
        "type": "object",
        "description": "Single error in the Batch Basic Error Response.",
        "properties": {
          "messages": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "key": {
            "type": "string"
          }
        },
        "required": [
          "messages",
          "key"
        ]
      },
      "FieldFilter": {
        "title": "FieldFilter",
        "description": "A field filter for querying an index",
        "type": "object",
        "properties": {
          "key": {
            "$ref": "#/components/schemas/Key"
          },
          "value": {
            "type": "object",
            "description": "The indexed Cloud Save value"
          },
          "op": {
            "type": "string",
            "description": "The comparison operator to use for the filter. The specified value is compared to the indexed value (lexicographically for string data, numerically for numerical data) using one of the following operators:\n* `EQ` - Equal\n* `NE` - Not Equal\n* `LT` - Less Than\n* `LE` - Less Than or Equal\n* `GT` - Greater Than\n* `GE` - Greater Than or Equal",
            "enum": [
              "EQ",
              "NE",
              "LT",
              "LE",
              "GT",
              "GE"
            ]
          },
          "asc": {
            "type": "boolean",
            "description": "Whether the field is sorted in ascending order"
          }
        },
        "required": [
          "key",
          "value",
          "op",
          "asc"
        ]
      },
      "QueryIndexBody": {
        "title": "QueryIndexBody",
        "description": "The request body for querying an index",
        "type": "object",
        "properties": {
          "fields": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/FieldFilter"
            }
          },
          "returnKeys": {
            "type": "array",
            "description": "The keys to return in the response. This can include keys not on the index. If not specified or empty, the data on the results will be empty for any returned entities.",
            "items": {
              "$ref": "#/components/schemas/Key"
            }
          },
          "offset": {
            "type": "integer",
            "description": "The number of results to skip. Defaults to 0.",
            "minimum": 0
          },
          "limit": {
            "type": "integer",
            "description": "The maximum number of results to return. Defaults to 10. Specifying 0 will return the default number of results.",
            "minimum": 0,
            "maximum": 100
          },
          "sampleSize": {
            "type": "integer",
            "description": "If set, the given number of random items will be chosen from the total query results and returned as a sample. Defaults to null.",
            "minimum": 0,
            "maximum": 100
          }
        },
        "required": [
          "fields"
        ]
      },
      "BatchConflictErrorResponse": {
        "title": "BatchConflictErrorResponse",
        "type": "object",
        "description": "An error response sent back upon a batch update containing a resource conflict. All Data Items within the request should be considered unprocessed. The error response data[] property contains the Data Items that conflicted.",
        "example": {
          "type": "problems/data/batch-conflict",
          "title": "batch conflict error",
          "status": 409,
          "code": 1015,
          "detail": "WriteLock in one or more data items within update request does not match stored WriteLock",
          "data": [
            {
              "attempted": {
                "key": "ItemKey",
                "value": {
                  "value": "new data"
                },
                "writeLock": "7b8920a57912509f6b5cbb183eb7fcb0"
              }
            },
            {
              "existing": {
                "key": "ItemKey",
                "value": {
                  "value": "old data"
                },
                "writeLock": "2509f6b5cbb187b8920a57913eb7fcb0",
                "modified": {
                  "date": "2020-02-22T20:20:20Z"
                },
                "created": {
                  "date": "2020-01-20T20:20:20Z"
                }
              }
            }
          ]
        },
        "allOf": [
          {
            "$ref": "#/components/schemas/BaseErrorResponse"
          },
          {
            "properties": {
              "data": {
                "type": "array",
                "description": "A human-readable explanation specific to this occurrence of the problem.",
                "items": {
                  "$ref": "#/components/schemas/ConflictErrorResponseData"
                }
              }
            }
          }
        ],
        "required": [
          "type",
          "title",
          "status",
          "code",
          "detail",
          "data"
        ]
      },
      "GetPlayersResponse": {
        "title": "GetPlayersResponse",
        "description": "List of players with data set",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "$ref": "#/components/schemas/PlayerId"
                },
                "accessClasses": {
                  "$ref": "#/components/schemas/AccessClassesWithMetadata"
                }
              },
              "required": [
                "id",
                "accessClasses"
              ]
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "next": {
                "type": "string",
                "description": "The URL to the next page of results"
              }
            },
            "required": [
              "next"
            ]
          }
        },
        "required": [
          "results",
          "links"
        ]
      },
      "GetCustomIdsResponse": {
        "title": "GetCustomIdsResponse",
        "description": "List of custom IDs",
        "type": "object",
        "properties": {
          "results": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "$ref": "#/components/schemas/CustomId"
                },
                "accessClasses": {
                  "$ref": "#/components/schemas/AccessClassesWithMetadata"
                }
              },
              "required": [
                "id",
                "accessClasses"
              ]
            }
          },
          "links": {
            "type": "object",
            "properties": {
              "next": {
                "type": "string",
                "description": "The URL to the next page of results"
              }
            },
            "required": [
              "next"
            ]
          }
        },
        "required": [
          "results",
          "links"
        ]
      },
      "AccessClassesWithMetadata": {
        "title": "AccessClassesWithMetadata",
        "description": "The access classes for the ID. Any given ID can have data stored across multiple access classes.",
        "type": "object",
        "properties": {
          "default": {
            "$ref": "#/components/schemas/AccessClassMetadata"
          },
          "public": {
            "$ref": "#/components/schemas/AccessClassMetadata"
          },
          "protected": {
            "$ref": "#/components/schemas/AccessClassMetadata"
          },
          "private": {
            "$ref": "#/components/schemas/AccessClassMetadata"
          }
        }
      },
      "AccessClassMetadata": {
        "title": "AccessClassMetadata",
        "description": "Metadata regarding data in an access class",
        "type": "object",
        "properties": {
          "totalSize": {
            "type": "integer",
            "description": "The total size of the data stored in bytes for this access class"
          },
          "numKeys": {
            "type": "integer",
            "description": "The number of keys stored for this access class"
          }
        },
        "required": [
          "totalSize",
          "numKeys"
        ]
      }
    },
    "responses": {
      "BadRequest": {
        "description": "Bad Request. Returned code indicates one of:\n- Request parameter validation failure\n- Other\nSee the errors field for more details.\n",
        "content": {
          "application/problem+json": {
            "schema": {
              "oneOf": [
                {
                  "$ref": "#/components/schemas/BasicErrorResponse"
                },
                {
                  "$ref": "#/components/schemas/ValidationErrorResponse"
                }
              ],
              "discriminator": {
                "propertyName": "type",
                "mapping": {
                  "problems/basic": "#/components/schemas/BasicErrorResponse",
                  "problems/validation": "#/components/schemas/ValidationErrorResponse"
                }
              }
            }
          }
        }
      },
      "Unauthorized": {
        "description": "Invalid Authentication Token",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "Forbidden": {
        "description": "Forbidden",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "NotFound": {
        "description": "Not Found",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "Conflict": {
        "description": "Conflict. The 'writeLock' supplied in the request does not match the current stored state for this entity, some other client has updated this data item since you acquired this writeLock.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/ConflictErrorResponse"
            }
          }
        }
      },
      "DeleteConflict": {
        "description": "Conflict. The 'writeLock' supplied in the request does not match the current stored state for this entity, some other client has updated this data item since you acquired this writeLock.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/DeleteConflictErrorResponse"
            }
          }
        }
      },
      "BatchConflict": {
        "description": "Conflict. The 'writeLock' supplied in the request does not match the current stored state for this entity, some other client has updated this data item since you acquired this writeLock.",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BatchConflictErrorResponse"
            }
          }
        }
      },
      "TooManyRequests": {
        "description": "Too Many Requests",
        "headers": {
          "Retry-After": {
            "schema": {
              "type": "number"
            },
            "description": "The number of seconds until a request will be accepted"
          }
        },
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "InternalServerError": {
        "description": "Internal Server Error",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      },
      "ServiceUnavailable": {
        "description": "Service Unavailable",
        "content": {
          "application/problem+json": {
            "schema": {
              "$ref": "#/components/schemas/BasicErrorResponse"
            }
          }
        }
      }
    }
  }
}
```