The App Store Review API allows third-party app stores registered on Google Play through the Third-party app store on Play program to provide required details for apps hosted on their store. This includes app metadata, listings, APK binaries, and policy compliance declarations.
For a complete list of endpoints, methods, and resource schemas, see the App Store Review API Reference.
Before You Begin
You must complete the main Getting Started Guide to set up your API access, service credentials, and Google Cloud project before you can make calls to the App Store Review API. The App Store Review API expects at most 300 requests per minute per app store.
API Design & Architecture
The App Store Review API operates on an atomic snapshot pattern. Rather than using transactional sessions, you upload files individually and then commit the complete state in a single, atomic call:
- You upload individual files and assets (APKs, images, and policy files) in separate, direct calls.
- You cache the returned IDs for those files.
- You submit a single, final
UpdateAppStoreHostedApprequest to commit the entire hosted app state atomically.
1. Registration
To register a hosted app, call the
createappstorehostedapp
method, specifying the package name of the app and your store's package name.
For details on the request and response schemas, see the API reference.
2. Binary and asset uploads
Once the hosted app is registered, you must upload its assets using the specialized upload endpoints:
- APKs: All actively distributed APK binaries of the app (using
uploadapk). - Images: Image assets, such as the app icon and screenshots (using
uploadimage). - Policies: (If relevant) Policy-related documentation (using
uploadappstoreapppolicydeclarationfile).
Asset Caching & Reuse
To optimize bandwidth and performance, do not re-upload identical assets.
All returned apkId, imageId, and fileId tokens are persistent. You can
cache these IDs in your own backend database and reuse them in subsequent hosted
app updates. For example, if you are updating a hosted app's description but the
app icon and screenshots remain unchanged, use the cached imageId tokens in
your next update call.
3. Assemble and commit
After successfully uploading all assets and retrieving their respective IDs, you
must assemble the full hosted app state and commit it using the
updateappstorehostedapp
method. This method accepts a complete, atomic representation of the hosted
app's details, localized store listings, active APK sets, and safety
declarations.
This call replaces any previously active state with the new state described in the request.
Request Body Example
The following is a realistic and syntactically valid JSON request body illustrating all key elements:
{
"appStorePackageName": "com.example.thirdparty.store",
"packageName": "com.example.hostedapp.game",
"appDetails": {
"developerName": "Adventure Games Studio Ltd.",
"contactEmail": "support@adventuregames.example.com",
"developerWebsite": "https://adventuregames.example.com"
},
"activeLocalizedStoreListings": [
{
"languageCode": "en-US",
"appName": "Super Quest Legends",
"shortDescription": "An epic fantasy RPG adventure.",
"fullDescription": "Super Quest Legends is an immersive action RPG featuring real-time battles, customizable classes, and a deep fantasy narrative. Journey through a magical realm, fight epic bosses, and team up with friends in dungeon raids.",
"appIconId": "987123",
"screenshotId": [
"102938",
"475869",
"384756"
],
"videoLink": "https://www.youtube.com/watch?v=dQw4w9WgXcQ"
},
{
"languageCode": "es-ES",
"appName": "Super Quest Leyendas",
"shortDescription": "Una aventura épica de RPG fantástico.",
"fullDescription": "Super Quest Leyendas es un RPG de acción inmersivo con batallas en tiempo real, clases personalizables y una profunda narrativa de fantasía. Viaja a través de un reino mágico, lucha contra jefes épicos y únete a amigos en incursiones.",
"appIconId": "987123",
"screenshotId": [
"102938",
"475869",
"384756"
]
}
],
"activeApks": {
"activeApkSets": [
{
"baseApkId": "554433"
},
{
"baseApkId": "990011"
}
]
},
"policyDeclarations": [
{
"declarationId": "POLICY_DECLARATION_ID_TARGET_AUDIENCE_CONTENT",
"responses": [
{
"questionId": "POLICY_QUESTION_ID_TAC_TARGET_AGE_GROUPS",
"multipleChoiceResponse": {
"values": [
"POLICY_RESPONSE_CHOICE_ID_TAC_AGE_EIGHTEEN_AND_ABOVE"
]
}
},
// ... other responses for TAC
]
},
{
"declarationId": "POLICY_DECLARATION_ID_ADVERTISING_ID",
"responses": [
{
"questionId": "POLICY_QUESTION_ID_AD_ID_IS_USED",
"booleanResponse": {
"value": false
}
}
// ... other responses for AD_ID
]
}
// ... other declarations
]
}
Policy Declarations
When submitting or updating app information using the API, you must include any required policy declarations.
Declaration Requirements
The following declarations are in scope:
Required for all apps to confirm if additional declarations are needed:
- Health Apps: Tell us what health features the app uses to help us to understand which requirements the app must meet in the Health apps policy.
- Financial Features: Apps that provide financial features might need to comply with certain regulations in some countries or regions. Submit accurate and up-to-date details of the financial features in the app to help us make sure the right teams review the submission.
- Advertising ID: Help us understand whether the app uses advertising ID.
- Testing Credentials (Sign in details): If any part of the app is restricted based on sign in details, memberships, location, or other forms of authentication, provide instructions on how to access them.
- Privacy Policy: A link to and details about the app's privacy policy.
- Target Audience and Content: You must let us know the target age group of the app, and other information about its contents. This helps make sure that apps designed for children are safe and appropriate.
- Ads: You must let us know whether the app contains ads.
Conditionally Required:
- Government Apps: Tell us if the app is for use by a government of any kind. This includes national, state and city governments, and local authorities. This helps us to make sure the right teams review the submission. If this declaration is not completed, the app will be considered not a government app.
- Child Safety Standards: Required for apps in the "Social" or "Dating" categories. Apps in the social or dating categories must provide published safety standards and contact information to comply with our child safety standards policy.
- News and Magazine Apps: Required for apps in the "News and Magazines" category. Add details about the news and magazine app to provide transparency about the entities behind the app.
API Request Structure
Policy declarations are provided within the policyDeclarations array in the
body of the
UpdateAppStoreHostedAppRequest.
Each item in this array is an AppStoreAppPolicyDeclaration object.
AppStoreAppPolicyDeclaration Object:
declarationId(string, Required): The unique identifier for the policy declaration (e.g.,POLICY_DECLARATION_ID_FINANCE,POLICY_DECLARATION_ID_TARGET_AUDIENCE_CONTENT).responses(Array ofPolicyResponse, Required): A list of answers to the questions within that specific declaration.
PolicyResponse Object:
questionId(string, Required): The unique identifier for the specific question being answered (e.g.,POLICY_QUESTION_ID_FINANCIAL_PRODUCT_TYPES,POLICY_QUESTION_ID_TAC_TARGET_AGE_GROUPS).value(Required): The answer itself, which can be one of the following types:booleanResponse: For Yes or No questions.value(boolean)
stringResponse: For plain text answers, including URLs.value(string)
singleChoiceResponse: When only one option can be selected from a list.value(string): The ID of the chosen response choice.
multipleChoiceResponse: When multiple options can be selected.values(Array of string): The IDs of the chosen response choices.
documentResponse: For questions requiring a document upload. See Handling Document Uploads.groupResponse: For repeating sets of nested questions.keyedGroupResponse: For sets of nested questions grouped by a specific key.
For example snippets for declaration, refer to the detailed guide.
Handling Document Uploads
Some policy questions require you to provide supporting documents (e.g.,
licenses for Financial Features). Documents cannot be embedded directly in the
UpdateAppStoreHostedAppRequest.
Instead, you must:
Upload the Document: Use the
UploadAppStoreAppPolicyDeclarationFileendpoint. This is a media upload request. ThefileTypeshould be set toDECLARATION_FILE_TYPE_DOCUMENT.- Endpoint:
POST /androidpublisher/v3/appstore/{appStorePackageName}/apps/{packageName}/policyDeclarationFiles:upload - Successful upload responses will include a
fileId.
- Endpoint:
Reference the Document ID: In the
PolicyResponsefor the document question, use thedocumentResponsetype. Populate thedocumentIdfield with thefileIdobtained from the upload step.
PolicyDocumentResponse Object:
documentId(string, Required): The ID returned from theUploadAppStoreAppPolicyDeclarationFileendpoint.expiryDate(Date, Optional): The expiry date of the document, if applicable.nonExpiring(boolean, Optional): Set totrueif the document does not expire.
Example for Document Response:
// Inside a PolicyResponse object
{
"questionId": "POLICY_QUESTION_ID_FINANCE_CRYPTO_US_FINCEN_LICENSE", // Example ID
"documentResponse": {
"documentId": "123456789", // The fileId from upload
"expiryDate": {
"year": 2027,
"month": 6,
"day": 1
}
}
}
4. Controlling availability
Once you commit the hosted app state using
UpdateAppStoreHostedApp,
the app is automatically processed and marked as published by default in
Google Play for the third-party app store.
To control the app's availability after it has been committed, call the
updateappstorehostedapppublishstatus
method to update its state:
- Unpublishing an App: To make the hosted app unavailable, set the
publishStatefield toAPP_STORE_APP_PUBLISH_STATE_UNPUBLISHED. - Re-publishing an App: To make a previously unpublished app available
again without modifying listings or re-uploading assets, set the
publishStatefield toAPP_STORE_APP_PUBLISH_STATE_PUBLISHED.