Steamworks Documentation
ICloudService Interface
Provides access to a Steam user's Steam Cloud files. This is mostly intended to enable cross-platform saves for your game. The Steam version of the game can use the Steamworks Cloud features (either the ISteamRemoteStorage API, or Steam Auto-Cloud). Non-Steam versions can use this WebAPI to access the files and upload new versions.

Your game will need to obtain permission from the user to access their Steam Cloud files. This can be done via OAuth. Note that you will most likely want to request both read_cloud and write_cloud permissions.

Please also see the general Steam WebAPI overview documentation, specifically the section titled "Service Interfaces". GET requests can be done with parameters in the URL, however it is recommended for POST requests that all parameters are in the request body. The access-token parameter is directly form-encoded, and then the remaining parameters should be in a JSON structure set via the input-json field.

Responses to well-formed and authenticated requests will usually be 200 OK. However the request may have failed - the detailed Steam error code will be found in the x-eresult header. The value for "success" is 1. All other values are likely to be errors; see the documentation for steam_api.h for details.

Enumerating Files

Requires read_cloud OAuth access.

EnumerateUserFiles


Example:
GET https://api.steampowered.com/ICloudService/EnumerateUserFiles/v1/?access_token=<token>&appid=1234&extended_details=1 HTTP/1.1 Host: api.steampowered.com Content-Length: 0

NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
extended_detailsboolInclude details such as download links for the files
countuint32Max number of file to enumerate (default 500)
start_indexuint32Beginning file index to enumerate (default 0)

Enumerate the user's Steam Cloud files for your game. Begin with a "start_index" of zero, and iterate if necessary if the user has more than "count" files.

The response has two fields:
NameTypeDescription
filessee belowA list of file details
total_filesuint32The total number of files the user has in Steam Cloud for your app.

The files list contains this data:
NameTypeDescription
appiduint32same app id
ugciduint64unique file ID
filenamestringthe file name
timestampuint64epoch time when the file was last modified
file_sizeuint32size of the file in bytes
urlstringa URL which can be used to download the file
steamid_creatoruint64SteamID of the user
flagsuint32Steam internal use only
platforms_to_syncstringList of platforms for which this file is valid. See Uploading Files for the list of possible values.
file_shastringHex string (40 digits) representing the SHA1 digest of the file.

Downloading Files


To download a file, simple make a GET request to the URL returned by EnumerateUserFiles above.

Modifying Files


Requires write_cloud OAuth access.

Modifying files includes uploading new files, uploading new versions of existing files, and deleting files from Steam Cloud.

A set of file modification actions should be wrapped in a Batch. Batches are used to communicate intent to the Steam Cloud for your set of modifications, and help reduce the likelihood of file conflicts.

A full batch sequence will look like the following:

  • BeginAppUploadBatch call, listing the intended uploads and deletes
  • 0 or more uploads, using the sequence:
    • BeginHTTPUpload
    • HTTP PUT operation to upload the file
    • CommitHTTPUpload
  • 0 or more deletes, using Delete
  • CompleteAppUploadBatch

Note that you must call CompleteAppUploadBatch whether or not all uploads and/or deletes complete successfully. Failing to call CompleteAppUploadBatch will result in a time period of several minutes where new upload attempts for this user and app are blocked with a "too many pending requests" response.

BeginAppUploadBatch


The first operation for a set of file modifications is to call BeginAppUploadBatch. This call communicates the set of intended uploads and deletes to the SteamCloud, as well as information about the user's machine which is doing the update.

Example:
POST https://api.steampowered.com/ICloudService/BeginAppUploadBatch/v1/ HTTP/1.1 Host: api.steampowered.com Content-Type: application/x-www-form-urlencoded Content-Length: <body length> access_token=<token>&input_json={ "appid": "1234", "machine_name": "My%20Handheld", "files_to_upload": ["%25WinAppDataLocal%25Foobar%2FGamename%2Fcloud%2Fgames%2Fsave.sav"], "files_to_delete": ["%25WinAppDataLocal%25Foobar%2FGamename%2Fcloud%2Fgames%2Fsave_old.sav"] }

NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
machine_namestringA name for the source machine, preferably one the user has applied to the device
files_to_uploadstring listList of all files to be uploaded (new files or updates for existing files) as part of this batch.
files_to_deletestring listList of all files to be deleted from Steam Cloud as part of this batch.

Call this API to begin the upload batch.

Note that for list parameters, such as "files_to_upload", the syntax when used as a GET param is as follows:
&files_to_upload[0]=file1.sav&files_to_upload[1]=file2.sav

In a JSON-encoded field in a POST param, it is as follows:
"files_to_upload": ["file1.sav", "file2.sav"]

The response data:
NameTypeDescription
batch_iduint64ID of this batch, to be used with the CompleteAppUploadBatch call
app_change_numberuint64currently unused by this API

Your application must remember the batch_id from this response and submit it to the CompleteAppUploadBatch request once all uploads and deletes have been attempted.

CompleteAppUploadBatch


Once all uploads and deletes have been attempted, successful or not, you must call CompleteAppUploadBatch. This indicates to Steam that all operations for this batch have been attempted and it will then allow any newly-requested batches immediately.

Example:
POST https://api.steampowered.com/ICloudService/CompleteAppUploadBatch/v1/ HTTP/1.1 Host: api.steampowered.com Content-Type: application/x-www-form-urlencoded Content-Length: <body length> access_token=<token>&input_json={ "appid": "1234", "batch_id": "434565457423", "batch_eresult": "1" }

NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
batch_iduint64The ID number of this batch
batch_eresultuint32Result of the batch (see remarks)

The batch_eresult parameter should be either 1 (success) or 2 (failure). Technically this is an EResult value (see steam_api.h for the list). Indicating success or failure to Steam is sufficient for this method.

There's no body data in the response from this API.

BeginHTTPUpload


Uploading is done via a two-part API. You'll first call BeginHTTPUpload to get details on where to upload the file, then when that is complete, call CommitHTTPUpload.

Example:
POST https://api.steampowered.com/ICloudService/BeginHTTPUpload/v1/ HTTP/1.1 Host: api.steampowered.com Content-Type: application/x-www-form-urlencoded Content-Length: <body length> access_token=<token>&input_json={ "appid": "1234", "file_size": "7448889", "filename": "%25WinAppDataLocal%25Foobar%2FGamename%2Fcloud%2Fgames%2Fsave.sav", "file_sha": "FDFE308499263F9361B472648E9F49DC0B8799C8", "is_public": "0", "platforms_to_sync": ["all"] }

NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
file_sizeuint32size of the file in bytes
filenamestringthe file name
file_shastringHex string (40 digits) representing the SHA1 digest of the file.
platforms_to_syncstringList of platforms for which this file is valid. Possible values: All, Windows, MacOS, linux, Android, iPhoneOS, Switch. Case-insensitive.

Call this API to initiate uploading a new file (or new version of an existing file) to Steam Cloud for the user. New versions of existing files will overwrite the existing version.

Note that for list parameters, such as "platforms_to_sync", the syntax when used as a GET param is as follows:
&platforms_to_sync[0]=macos&platforms_to_sync[1]=windows

In a JSON-encoded field in a POST param, it is as follows:
"platforms_to_sync": ["macos", "windows"]

The response data:
NameTypeDescription
ugciduint64unique file id (not needed)
timestampuint32epoch timestamp for this change
url_hoststringHost FQDN you will upload the file to
url_pathstringpath for request. Note that currently this includes a leading slash character (/) already.
use_httpsboolset to true if you must use HTTPS to perform the upload (generally always true)
request_headerssee belowlist of HTTP headers you must set on the subsequent PUT request

The "request_headers" list contains this data:
NameTypeDescription
namestringthe header name
valuestringthe header value

To upload the file, make a PUT request to https://<url_host><url_path>, where each of the above specified HTTP headers has the specified value. On success you may receive a 200 OK, 201 Created, or 204 No Content response, depending on the storage provider.

This request may look like:
PUT https://steamcloud-us-west1.storage.googleapis.com/00/00/00/00/1234/012_3_4A77D494_9D267_1464.dat?GoogleAccessId=numbersandletters@developer.gserviceaccount.com&Expires=1595961837&Signature=morestuffhere HTTP/1.1 Host: steamcloud-us-west1.storage.googleapis.com Content-Type: application/octet-stream Content-Length: <body length> Header-from-Steam1: value1 Header-from-Steam2: value2 <file data>

When that completes (whether a success or a failure), call:

CommitHTTPUpload


Example:
POST https://api.steampowered.com/ICloudService/CommitHTTPUpload/v1/ HTTP/1.1 Host: api.steampowered.com Content-Type: application/x-www-form-urlencoded Content-Length: <body length> access_token=<token>&input_json={ "appid": "1234", "transfer_succeeded": "1", "filename": "%25WinAppDataLocal%25Foobar%2FGamename%2Fcloud%2Fgames%2Fsave.sav", "file_sha": "FDFE308499263F9361B472648E9F49DC0B8799C8" }
NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
transfer_succeededbooltrue if the PUT request succeeded
filenamestringthe file name
file_shastringHex string (40 digits) representing the SHA1 digest of the file.

The response to this API currently has a single field, "file_committed", which will be true if Steam was able to fully commit the change. If false, then the upload has failed -- a new file was not recorded, and if it was an update to an existing file, the existing file still exists and will be returned by future Enumerate/Download requests.

Delete


Example:
POST https://api.steampowered.com/ICloudService/Delete/v1/ HTTP/1.1 Host: api.steampowered.com Content-Type: application/x-www-form-urlencoded Content-Length: <body length> access_token=<token>&input_json={ "appid": "1234", "filename": "%25WinAppDataLocal%25Foobar%2FGamename%2Fcloud%2Fgames%2Fsave.sav" }

NameTypeRequiredDescription
access_tokenstringOAuth access token for the user
appiduint32Your App ID
filenamestringfilename of the file to delete

This API will delete the specified file from the user's Steam Cloud. Deleting files is permanent; no prior versions of the file are retained. There's no body data in the response from this API.