This page explains how to implement the Recall API within your game. It first covers setting up your game server and client to support the API, and then goes through how to store and retrieve tokens.
Game server setup
Set up your game server to make Recall API calls to Google servers.
1. Set up your Play Games Services project
If you haven't already done so, follow the instructions in Set up Google Play Games Services.
2. Set up a service account for the game
Follow the instructions on creating a service account. At the end you should have a JSON file with service account credentials.
3. Download server-side Java library for PlayGamesServices
Download the latest google-api-services-games library and upload it to your server.
4. Prepare credentials for Recall API calls
See Preparing to make an authorized API call for more context.
import com.google.api.client.googleapis.auth.oauth2.GoogleCredential;
import com.google.api.services.games.Games;
import com.google.api.services.games.GamesScopes;
// ...
GoogleCredential credential =
GoogleCredential.fromStream(new FileInputStream("<credentials>.json"))
.createScoped(Collections.singleton(GamesScopes.ANDROIDPUBLISHER));
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
Game client setup
Set up your game client to retrieve the recall session IDs used by our server to communicate with Google servers.
Java SDK
Set up the Java SDK within your client, and make sure to include com.google.android.gms:play-services-games-v2:19.0.0
and com.google.android.gms:play-services-tasks:18.0.2 or higher in your
gradle file.
To communicate with Google's servers with the correct information, you need to request a Recall session ID from the client SDK, which you send to your game's server.
Kotlin
PlayGames.getRecallClient(getActivity())
.requestRecallAccess()
.addOnSuccessListener { recallAccess -> val recallSessionId: String = recallAccess.getSessionId() }
// Send the recallSessionId to your game server
Java
PlayGames.getRecallClient(getActivity())
.requestRecallAccess()
.addOnSuccessListener(
recallAccess -> {
String recallSessionId = recallAccess.getSessionId();
// Send the recallSessionId to your game server
});
Unity SDK
If not already completed, set up the Unity SDK within your client.
To communicate with Google's servers with the correct information, you need to request a Recall session ID from the client SDK, and send it to your game's server.
PlayGamesPlatform.Instance.RequestRecallAccess(
recallAccess => {
string recallSessionId = recallAccess.sessionId;
// Send the recallSessionId to your game server
});
Use the Recall API within your game server
After configuring your server and client, you can send the recallSessionID
from your game client to your game server and follow the following guidance to
start using the Java API to store, retrieve, or delete the Recall tokens
server-side.
Store tokens
A player account in the Google Play Games Recall API consists of two pieces of information:
- a Persona serving as a stable identifier for an in-game account
- a Token serving as the key to securely sign a player into the account
You can store a user's persona and token by using the LinkPersonaRequest
object. Use the GoogleCredential to call Google APIs (See Calling Google
APIs for context). A persona has a 1:1 cardinality constraint: a single
PGS profile can only contain a single persona and a persona can only exist in a
single PGS profile. Set the conflicting links resolution policy to define
how violations of the 1:1 cardinality constraint should resolve.
Optionally set the expiration time of the token. Use SetTtl() with a
Durations object to set a Time to Live or provide an exact expiration
time with setExpireTime().
You must encrypt the persona and game token, and they cannot contain personally identifiable information. Persona and token strings can be at most 256 characters long.
import com.google.api.services.games.Games.Recall.LinkPersona;
import com.google.api.services.games.model.LinkPersonaRequest;
import com.google.api.services.games.model.LinkPersonaResponse;
import com.google.protobuf.util.Durations;
// ...
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
String recallSessionId = ... // recallSessionID from game client
String persona = ... // encrypted opaque string, stable for in-game account
String token = ... // encrypted opaque string encoding the progress line
LinkPersonaRequest linkPersonaRequest =
LinkPersonaRequest.newBuilder()
.setSessionId(recallSessionId)
.setPersona(persona)
.setToken(token)
.setCardinalityConstraint(ONE_PERSONA_TO_ONE_PLAYER)
.setConflictingLinksResolutionPolicy(CREATE_NEW_LINK)
.setTtl(Durations.fromDays(7)) // Optionally set TTL for token
.build();
LinkPersonaResponse linkPersonaResponse =
gamesApi.recall().linkPersona(linkPersonaRequest).execute();
if (linkPersonaResponse.getState() == LINK_CREATED) {
// success
}
Retrieve tokens
There are three options to retrieve a token, based on your games' needs. You can request the following:
- The tokens associated with the current game, including game-scoped recall tokens.
- The last token stored across all games owned by the developer account.
- Given a list of games owned by the developer account, all the recall tokens associated with each game.
Game-scoped recall tokens
To retrieve the recall tokens from the current game, get the recallSessionId
from the client and pass it into the retrieveTokens API:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrievePlayerTokensResponse;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrievePlayerTokensResponse retrievePlayerTokensResponse =
gamesApi.recall().retrieveTokens(recallSessionId).execute();
for (RecallToken recallToken : retrievePlayerTokensResponse.getTokens()) {
String token recallToken.getToken();
// Same string as was written in LinkPersona call
// decrypt and recover in-game account
}
Latest recall token across all games owned by developer account
To retrieve the most recent token stored across all games owned by the developer
account in the Google Play Console, you need to get the recallSessionId from
the client and pass it into the lastTokenFromAllDeveloperGames API, as shown
in the following code snippet. As part of the response, you can inspect the
Application ID associated with this token.
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveDeveloperGamesLastPlayerTokenResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
RetrieveDeveloperGamesLastPlayerTokenResponse response =
gamesApi.recall().lastTokenFromAllDeveloperGames(recallSessionId)
.execute();
if (response.hasGamePlayerToken()) {
GamePlayerToken gamePlayerToken = response.getGamePlayerToken();
// The ID of the application that the token is associated with.
String applicationId = gamePlayerToken.getApplicationId();
// Same string as was written in LinkPersona call.
RecallToken recallToken = gamePlayerToken.getRecallToken();
// Decrypt and recover in-game account.
}
All recall tokens across a given list of games owned by the developer account
To retrieve all the tokens associated with a list of games which are owned by
your developer account in the Google Play Console, get the recallSessionId
from the client and pass it into the gamesPlayerTokens API. Supply a list of
Application IDs.
import com.google.api.services.games.Games;
import com.google.api.services.games.model.RetrieveGamesPlayerTokensResponse;
import com.google.api.services.games.model.GamePlayerToken;
import com.google.api.services.games.model.RecallToken;
// ...
String recallSessionId = ... // recallSessionID from game client
// Application IDs for which you would like to retrieve the recall tokens.
List<String> applicationIds = ...
RetrieveGamesPlayerTokensResponse response =
gamesApiClient
.recall()
.gamesPlayerTokens(recallSessionId)
.setApplicationIds(applicationIds)
.execute();
for (GamePlayerToken gamePlayerToken : response.getGamePlayerTokens()) {
// The ID of the application that the token is associated with.
String applicationId = gamePlayerToken.getApplicationId();
// Same string as was written in LinkPersona call.
RecallToken recallToken = gamePlayerToken.getRecallToken();
// Decrypt and recover in-game account.
}
Delete recall token
If needed, you can also delete the recall token with the following call:
import com.google.api.services.games.Games;
import com.google.api.services.games.model.UnlinkPersonaRequest;
import com.google.api.services.games.model.UnlinkPersonaResponse;
// ...
String recallSessionId = ...
String persona = ...
String token = ...
Games gamesApi =
new Games.Builder(httpTransport, JSON_FACTORY, credential).build();
UnlinkPersonaRequest unlinkPersonaRequest =
UnlinkPersonaRequest.newBuilder()
.setSessionId(recallSessionId)
.setPersona(persona)
// .setToken(token) - alternatively set token, but not both
.build();
UnlinkPersonaResponse unlinkPersonaResponse =
gamesApi.recall().unlinkPersona(unlinkPersonaRequest).execute();
boolean unlinked = unlinkPersonaResponse.isUnlinked();
Enable profileless mode
You can enable limited Recall API functionality for users that don't have PGS profiles by following these steps:
- Enable profileless recall for your PGS game project in the Play Developer
Console.

- Review the additional terms described later in this section.
- Add the following metadata tag into your app manifest:
<meta-data
android:name="com.google.android.gms.games.PROFILELESS_RECALL_ENABLED"
android:value="true" />
Additional terms
In addition to being subject to the Play Games Services Terms of Service, you agree that if you use the Recall API for users without a PGS profile, which enables sharing end user's data with Google without them having a Play Games Services profile, you must, prior to sharing such data with Google, provide the end user with appropriate notice describing the following:
- Your sharing of the data with Google to enable Play Games account linking feature.
- The availability of settings to manage such sharing such as those through Play Games settings.
- The processing of such data under the Google Privacy Policy, and obtain appropriate end user consent for such sharing that meets all applicable legal requirements.