App Store Review API Developer Guide

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:

  1. You upload individual files and assets (APKs, images, and policy files) in separate, direct calls.
  2. You cache the returned IDs for those files.
  3. You submit a single, final UpdateAppStoreHostedApp request 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:

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:

  1. 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.
  2. 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.
  3. Advertising ID: Help us understand whether the app uses advertising ID.
  4. 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.
  5. Privacy Policy: A link to and details about the app's privacy policy.
  6. 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.
  7. Ads: You must let us know whether the app contains ads.

Conditionally Required:

  1. 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.
  2. 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.
  3. 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 of PolicyResponse, 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:

  1. Upload the Document: Use the UploadAppStoreAppPolicyDeclarationFile endpoint. This is a media upload request. The fileType should be set to DECLARATION_FILE_TYPE_DOCUMENT.

    • Endpoint: POST /androidpublisher/v3/appstore/{appStorePackageName}/apps/{packageName}/policyDeclarationFiles:upload
    • Successful upload responses will include a fileId.
  2. Reference the Document ID: In the PolicyResponse for the document question, use the documentResponse type. Populate the documentId field with the fileId obtained from the upload step.

PolicyDocumentResponse Object:

  • documentId (string, Required): The ID returned from the UploadAppStoreAppPolicyDeclarationFile endpoint.
  • expiryDate (Date, Optional): The expiry date of the document, if applicable.
  • nonExpiring (boolean, Optional): Set to true if 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 publishState field to APP_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 publishState field to APP_STORE_APP_PUBLISH_STATE_PUBLISHED.