Repository: codemagic-ci-cd/cli-tools (language: python)

Issue:
Feature: Submit apps to App Store review
**Add support to automatically submit published iOS application packages (*.ipa) to [App Store App review](https://developer.apple.com/app-store/review/).**

**New actions:**
- `app-store-connect app-store-versions create`
- `app-store-connect app-store-versions delete`
- `app-store-connect app-store-versions modify`
- `app-store-connect builds app-store-version`
- `app-store-connect builds submit-to-app-store`

**Updated actions:**
- `app-store-connect apps builds` - add capabilities to filter builds.
- `app-store-connect publish` - add options to automatically submit uploaded ipa to App Store review.

All changes to the actions are backwards compatible.

**Notable bugfixes, improvements and new features:**
- Optional action arguments can now be separated into named argument groups in both CLI `--help` messages and documentation.
- It is now possible to filter by multiple values for one parameter in App Store Connect API read and list queries.
- New App Store Connect API client methods to:
  - create an App Store version,
  - read the build information of an App Store version,
  - read the App Store version submission information of an App Store version,
  - modify an App Store version,
  - delete an App Store version,
-  Isolate setting up CLI app arguments from `CliApp` source code.
- Add new argument type for reading ISO 8601 formatted timestamps from CLI arguments into `datetime` objects.
- Move `app-store-connect app-store-version-submissions create` and `app-store-connect app-store-version-submissions delete` action definitions from main `AppStoreConnect` class to a dedicated action group implementation.
- Collect similar arguments into collections and reuse them without rewriting.

Check example usage from [this comment](https://github.com/codemagic-ci-cd/cli-tools/pull/164#issuecomment-979303593).


Discussion / hints:
~TODO: add proper description to PR.~
Edit: Done
Example usage of `app-store-connect publish` with App Store review submission enabled:

```bash
17:11:13 priit@groundhog build app-store-connect publish \
    --app-store \
    --copyright '2021 Codemagic' \
    --release-type 'SCHEDULED' \
    --earliest-release-date '2021-11-26T14:00:00+00:00'


Searching for files matching /Users/priit/build/**/*.ipa
Searching for files matching /Users/priit/build/**/*.pkg

Publish "banaan_1_0_208_234.ipa" to App Store Connect
App name: Banaan
Bundle identifier: io.codemagic.banaan
Certificate expires: 2022-11-01T06:04:55.000+0000
Distribution type: App Store
Min os version: 10.1
Provisioned devices: N/A
Provisions all devices: No
Supported platforms: iPhoneOS
Version code: 1.0.208.234
Version: 1.0.208

Validate "banaan_1_0_208_234.ipa" for App Store Connect
{
    "tool-version": "4.050.1210",
    "tool-path": "/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/Frameworks/AppStoreService.framework",
    "success-message": "No errors validating archive at 'banaan_1_0_208_234.ipa'.",
    "os-version": "11.2.3"
}
No errors validating archive at 'banaan_1_0_208_234.ipa'.

Upload "banaan_1_0_208_234.ipa" to App Store Connect
{
    "tool-version": "4.050.1210",
    "tool-path": "/Applications/Xcode.app/Contents/SharedFrameworks/ContentDeliveryServices.framework/Versions/A/Frameworks/AppStoreService.framework",
    "success-message": "No errors uploading 'banaan_1_0_208_234.ipa'",
    "os-version": "11.2.3"
}
No errors uploading 'banaan_1_0_208_234.ipa'

Find application entry from App Store Connect for uploaded binary
Found 1 App matching specified filters: bundleId=io.codemagic.banaan.
-- App --
Id: 1481211155
Type: apps
Bundle id: io.codemagic.banaan
Name: Banaan Codemagic
Primary locale: en-GB
Sku: banaanike
Available in new territories: True
Content rights declaration: DOES_NOT_USE_THIRD_PARTY_CONTENT
Is or ever was made for kids: False

Find uploaded build
Build has finished uploading but is processing on App Store Connect side. Could not find the build matching the uploaded version yet. Waiting 30 seconds to try again, 20 attempts remaining.
...
Build has finished uploading but is processing on App Store Connect side. Could not find the build matching the uploaded version yet. Waiting 30 seconds to try again, 15 attempts remaining.

Uploaded build is
-- Build --
Id: e688fd8e-3ea3-4db7-aa08-522c62affe05
Type: builds
Expired: False
Icon asset token:
	Template url: https://is5-ssl.mzstatic.com/image/thumb/Purple126/v4/bf/3b/97/bf3b97f4-48bc-57ae-ce0d-48570350ef1e/Icon-83.5@2x.png.png/{w}x{h}bb.{f}
	Height: 167
	Width: 167
Min os version: 10.1
Processing state: PROCESSING
Version: 1.0.208.234
Uses non exempt encryption: False
Uploaded date: 2021-11-25 07:16:11-08:00
Expiration date: 2022-02-23 07:16:11-08:00

Processing of builds by Apple can take a while, the timeout for waiting the processing to finish for build e688fd8e-3ea3-4db7-aa08-522c62affe05 is set to 20 minutes.
Build e688fd8e-3ea3-4db7-aa08-522c62affe05 is still being processed on App Store Connect side, waiting 30 seconds and checking again
...
Build e688fd8e-3ea3-4db7-aa08-522c62affe05 is still being processed on App Store Connect side, waiting 30 seconds and checking again
Processing build e688fd8e-3ea3-4db7-aa08-522c62affe05 is completed


Submit build 'e688fd8e-3ea3-4db7-aa08-522c62affe05' to App Store review

Using version 1.0.208 for App Store submission

Found existing App Store Version 409ebefb-ebd1-4f1a-903d-6ba16e013ebf in state "DEVELOPER_REJECTED".
Use it for current submission by updating it with build: e688fd8e-3ea3-4db7-aa08-522c62affe05, copyright: '2021 Codemagic', earliest release date: 2021-11-26T14:00:00.000+0000, release type: scheduled, version string: 1.0.208.
Modify App Store Version 409ebefb-ebd1-4f1a-903d-6ba16e013ebf
Successfully modified App Store Version 409ebefb-ebd1-4f1a-903d-6ba16e013ebf
-- App Store Version --
Id: 409ebefb-ebd1-4f1a-903d-6ba16e013ebf
Type: appStoreVersions
Platform: IOS
App store state: PREPARE_FOR_SUBMISSION
Copyright: 2021 Codemagic
Earliest release date: 2021-11-26 06:00:00-08:00
Release type: SCHEDULED
Version string: 1.0.208
Created date: 2019-09-24 06:02:48-07:00
Downloadable: True

Creating new App Store Version Submission: app store version: 409ebefb-ebd1-4f1a-903d-6ba16e013ebf
-- App Store Version Submission (Created) --
Id: 409ebefb-ebd1-4f1a-903d-6ba16e013ebf
Type: appStoreVersionSubmissions
Created App Store Version Submission 409ebefb-ebd1-4f1a-903d-6ba16e013ebf

Check App Store submission details from
https://appstoreconnect.apple.com/apps/1481211155/appstore/ios/version/inflight
```

Fix patch:
diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0dd54ec..bec58516 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,58 @@
+Version 0.13.1
+-------------
+
+This is an enhancement release to further streamline the App Store review submission automation capabilities.
+
+Additions and changes from [pull request #172](https://github.com/codemagic-ci-cd/cli-tools/pull/172).
+
+**Features**
+- Support setting localized meta information for App Store versions when submitting build to App Store review.
+- Add new actions group `app-store-version-localizations` to `app-store-connect`.
+- Add new action `app-store-connect app-store-version-localizations create` to add localized metadata to an App Store version.
+- Add new action `app-store-connect app-store-version-localizations delete` to remove localized metadata from an App Store version.
+- Add new action `app-store-connect app-store-version-localizations get` to read App Store version localized metadata.
+- Add new action `app-store-connect app-store-version-localizations modify` to edit App Store version localized metadata.
+- Add new action `app-store-connect app-store-versions localizations` to list App Store version localizations for an App Store version.
+- Change `app-store-connect publish` to support adding or updating localized version metadata when submitting build to App Store review.
+- Change `app-store-connect builds submit-to-app-store` to support adding or updating localized version metadata for App Store version.
+- Add new App Store Connect API client method `AppStoreVersionLocalizations.create` to create App Store version localization meta information. See official API method [documentation](https://developer.apple.com/documentation/appstoreconnectapi/create_an_app_store_version_localization).
+- Add new App Store Connect API client method `AppStoreVersionLocalizations.read` to obtain App Store version localization meta information. See official API method [documentation](https://developer.apple.com/documentation/appstoreconnectapi/read_app_store_version_localization_information).
+- Add new App Store Connect API client method `AppStoreVersionLocalizations.modify` to edit existing App Store version localization meta information. See official API method [documentation](https://developer.apple.com/documentation/appstoreconnectapi/modify_an_app_store_version_localization).
+- Add new App Store Connect API client method `AppStoreVersionLocalizations.delete` to remove existing App Store version localization meta information. See official API method [documentation](https://developer.apple.com/documentation/appstoreconnectapi/delete_an_app_store_version_localization).
+- Add new App Store Connect API client method `AppStoreVersions.list_app_store_version_localizations` to list all App Store version localizations for given App Store version. See official API method [documentation](https://developer.apple.com/documentation/appstoreconnectapi/list_all_app_store_version_localizations_for_an_app_store_version).
+- Show more informative error messages in case CLI arguments from environment variables or files are invalid.
+- Add new options to actions `app-store-connect publish` and `app-store-connect builds submit-to-app-store`:
+  - `--app-store-version-info`,
+  - `--description`,
+  - `--keywords`,
+  - `--marketing-url`,
+  - `--promotional-text`,
+  - `--support-url`,
+  - `--app-store-version-localizations`.
+
+**Docs**
+
+- Create docs for `app-store-connect` actions group `app-store-version-localizations`.
+- Create docs for action `app-store-connect app-store-version-localizations create`.
+- Create docs for action `app-store-connect app-store-version-localizations delete`.
+- Create docs for action `app-store-connect app-store-version-localizations get`.
+- Create docs for action `app-store-connect app-store-version-localizations modify`.
+- Update docs for `app-store-connect` actions group `app-store-versions`.
+- Create docs for action `app-store-connect app-store-versions localizations`.
+- Update docs for action `app-store-connect app-store-versions create`.
+- Update docs for action `app-store-connect app-store-versions modify`.
+- Update docs for action `app-store-connect builds submit-to-app-store`.
+- Update docs for action `app-store-connect publish`.
+- Remove backticks from terminal help messages and keep them only for markdown documentation formatting.
+
+**Development**
+
+- Add option to limit number of responses in App Store Connect API client pagination method.
+- Change type of `App.Attributes.locale` from plain `str` to `Locale` enumeration.
+- Add definition for `AppStoreVersionLocalization` resource. See official resource [documentation](https://developer.apple.com/documentation/appstoreconnectapi/appstoreversionlocalization).
+- Reorder method signatures in `AbstractBaseAction` and unify indentation for method arguments.
+- Add references to implementing methods to `AbstractBaseAction` interface.
+
 Version 0.13.0
 -------------
 
@@ -25,7 +80,6 @@ Additions and changes from [pull request #164](https://github.com/codemagic-ci-c
   - `-su` for `--skip-package-upload`,
   - `-sv` for `--skip-package-validation`,
   - `-w` for `--max-build-processing-wait`.
-- 
 
 **Fixes**
 
diff --git a/doc.py b/doc.py
index d90693b1..82db989a 100755
--- a/doc.py
+++ b/doc.py
@@ -72,14 +72,16 @@ def __init__(self, raw_arguments):
     @classmethod
     def _replace_quotes(cls, description: str) -> str:
         json_array = re.compile(r'"(\[[^\]]+\])"')
-        # Dummy handling for description containing JSON arrays as an example
-        if not json_array.search(description):
-            return description.replace('"', '`')
-
-        before, array, after = json_array.split(description)
-        before = before.replace('"', '`')
-        after = after.replace('"', '`')
-        return f'{before}`{array}`{after}'
+        json_object = re.compile(r'"(\{[^\}]+\})"')
+        # Dummy handling for description containing JSON arrays and objects as an example
+        for patt in (json_object, json_array):
+            if not patt.search(description):
+                continue
+            before, obj, after = patt.split(description)
+            before = before.replace('"', '`')
+            after = after.replace('"', '`')
+            return f'{before}`{obj}`{after}'
+        return description.replace('"', '`')
 
     def _serialize_argument(self, arg) -> SerializedArgument:
         description = str_plain(arg._value_.description)
diff --git a/docs/app-store-connect/README.md b/docs/app-store-connect/README.md
index ed4b8f29..501fddc7 100644
--- a/docs/app-store-connect/README.md
+++ b/docs/app-store-connect/README.md
@@ -101,6 +101,7 @@ Enable verbose logging for commands
 
 |Action group|Description|
 | :--- | :--- |
+|[`app-store-version-localizations`](app-store-version-localizations.md)|Create and maintain version-specific App Store metadata that is localized.|
 |[`app-store-version-submissions`](app-store-version-submissions.md)|Manage your application's App Store version review process|
 |[`app-store-versions`](app-store-versions.md)|Manage the information related to an App Store version of your app|
 |[`apps`](apps.md)|Manage your apps in App Store Connect|
diff --git a/docs/app-store-connect/app-store-version-localizations.md b/docs/app-store-connect/app-store-version-localizations.md
new file mode 100644
index 00000000..371da997
--- /dev/null
+++ b/docs/app-store-connect/app-store-version-localizations.md
@@ -0,0 +1,82 @@
+
+app-store-version-localizations
+===============================
+
+
+**Create and maintain version-specific App Store metadata that is localized.**
+### Usage
+```bash
+app-store-connect app-store-version-localizations [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    ACTION
+```
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
+### Actions
+
+|Action|Description|
+| :--- | :--- |
+|[`create`](app-store-version-localizations/create.md)|Create an App Store Version Localization.         Add localized version-level information for a new locale.|
+|[`delete`](app-store-version-localizations/delete.md)|Delete an App Store Version Localization.         Remove a language from your version metadata.|
+|[`get`](app-store-version-localizations/get.md)|Read App Store Version Localization Information.         Get localized version-level information.|
+|[`modify`](app-store-version-localizations/modify.md)|Modify an App Store Version Localization.         Edit localized version-level information for a particular language.|
diff --git a/docs/app-store-connect/app-store-version-localizations/create.md b/docs/app-store-connect/app-store-version-localizations/create.md
new file mode 100644
index 00000000..c3e6b95e
--- /dev/null
+++ b/docs/app-store-connect/app-store-version-localizations/create.md
@@ -0,0 +1,117 @@
+
+create
+======
+
+
+**Create an App Store Version Localization.         Add localized version-level information for a new locale.**
+### Usage
+```bash
+app-store-connect app-store-version-localizations create [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    [--description DESCRIPTION]
+    [--keywords KEYWORDS]
+    [--marketing-url MARKETING_URL]
+    [--promotional-text PROMOTIONAL_TEXT]
+    [--support-url SUPPORT_URL]
+    [--whats-new WHATS_NEW]
+    APP_STORE_VERSION_ID
+    LOCALE
+```
+### Required arguments for action `create`
+
+##### `APP_STORE_VERSION_ID`
+
+
+UUID value of the App Store Version
+##### `LOCALE`
+
+
+The locale code name for App Store metadata in different languages. See available locale code names from https://developer.apple.com/documentation/appstoreconnectapi/betabuildlocalizationcreaterequest/data/attributes
+### Optional arguments for action `create`
+
+##### `--description, -d=DESCRIPTION`
+
+
+A description of your app, detailing features and functionality.
+##### `--keywords, -k=KEYWORDS`
+
+
+Include one or more keywords that describe your app. Keywords make App Store search results more accurate. Separate keywords with an English comma, Chinese comma, or a mix of both.
+##### `--marketing-url=MARKETING_URL`
+
+
+A URL with marketing information about your app. This URL will be visible on the App Store.
+##### `--promotional-text=PROMOTIONAL_TEXT`
+
+
+Promotional text lets you inform your App Store visitors of any current app features without requiring an updated submission. This text will appear above your description on the App Store for customers with devices running iOS 11 or later, and macOS 10.13 or later.
+##### `--support-url=SUPPORT_URL`
+
+
+A URL with support information for your app. This URL will be visible on the App Store.
+##### `--whats-new, -n=WHATS_NEW`
+
+
+Describe what's new in this version of your app, such as new features, improvements, and bug fixes. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_WHATS_NEW`. Alternatively to entering `WHATS_NEW` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
\ No newline at end of file
diff --git a/docs/app-store-connect/app-store-version-localizations/delete.md b/docs/app-store-connect/app-store-version-localizations/delete.md
new file mode 100644
index 00000000..d8267247
--- /dev/null
+++ b/docs/app-store-connect/app-store-version-localizations/delete.md
@@ -0,0 +1,87 @@
+
+delete
+======
+
+
+**Delete an App Store Version Localization.         Remove a language from your version metadata.**
+### Usage
+```bash
+app-store-connect app-store-version-localizations delete [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    [--ignore-not-found]
+    APP_STORE_VERSION_LOCALIZATION_ID
+```
+### Required arguments for action `delete`
+
+##### `APP_STORE_VERSION_LOCALIZATION_ID`
+
+
+UUID value of the App Store Version localization
+### Optional arguments for action `delete`
+
+##### `--ignore-not-found`
+
+
+Do not raise exceptions if the specified resource does not exist.
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
\ No newline at end of file
diff --git a/docs/app-store-connect/app-store-version-localizations/get.md b/docs/app-store-connect/app-store-version-localizations/get.md
new file mode 100644
index 00000000..66325d88
--- /dev/null
+++ b/docs/app-store-connect/app-store-version-localizations/get.md
@@ -0,0 +1,80 @@
+
+get
+===
+
+
+**Read App Store Version Localization Information.         Get localized version-level information.**
+### Usage
+```bash
+app-store-connect app-store-version-localizations get [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    APP_STORE_VERSION_LOCALIZATION_ID
+```
+### Required arguments for action `get`
+
+##### `APP_STORE_VERSION_LOCALIZATION_ID`
+
+
+UUID value of the App Store Version localization
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
\ No newline at end of file
diff --git a/docs/app-store-connect/app-store-version-localizations/modify.md b/docs/app-store-connect/app-store-version-localizations/modify.md
new file mode 100644
index 00000000..404614f9
--- /dev/null
+++ b/docs/app-store-connect/app-store-version-localizations/modify.md
@@ -0,0 +1,112 @@
+
+modify
+======
+
+
+**Modify an App Store Version Localization.         Edit localized version-level information for a particular language.**
+### Usage
+```bash
+app-store-connect app-store-version-localizations modify [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    [--description DESCRIPTION]
+    [--keywords KEYWORDS]
+    [--marketing-url MARKETING_URL]
+    [--promotional-text PROMOTIONAL_TEXT]
+    [--support-url SUPPORT_URL]
+    [--whats-new WHATS_NEW]
+    APP_STORE_VERSION_LOCALIZATION_ID
+```
+### Required arguments for action `modify`
+
+##### `APP_STORE_VERSION_LOCALIZATION_ID`
+
+
+UUID value of the App Store Version localization
+### Optional arguments for action `modify`
+
+##### `--description, -d=DESCRIPTION`
+
+
+A description of your app, detailing features and functionality.
+##### `--keywords, -k=KEYWORDS`
+
+
+Include one or more keywords that describe your app. Keywords make App Store search results more accurate. Separate keywords with an English comma, Chinese comma, or a mix of both.
+##### `--marketing-url=MARKETING_URL`
+
+
+A URL with marketing information about your app. This URL will be visible on the App Store.
+##### `--promotional-text=PROMOTIONAL_TEXT`
+
+
+Promotional text lets you inform your App Store visitors of any current app features without requiring an updated submission. This text will appear above your description on the App Store for customers with devices running iOS 11 or later, and macOS 10.13 or later.
+##### `--support-url=SUPPORT_URL`
+
+
+A URL with support information for your app. This URL will be visible on the App Store.
+##### `--whats-new, -n=WHATS_NEW`
+
+
+Describe what's new in this version of your app, such as new features, improvements, and bug fixes. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_WHATS_NEW`. Alternatively to entering `WHATS_NEW` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
\ No newline at end of file
diff --git a/docs/app-store-connect/app-store-versions.md b/docs/app-store-connect/app-store-versions.md
index 610e30fa..88eea573 100644
--- a/docs/app-store-connect/app-store-versions.md
+++ b/docs/app-store-connect/app-store-versions.md
@@ -78,4 +78,5 @@ Enable verbose logging for commands
 | :--- | :--- |
 |[`create`](app-store-versions/create.md)|Add a new App Store version to an app using specified build.|
 |[`delete`](app-store-versions/delete.md)|Delete specified App Store version from Apple Developer portal|
+|[`localizations`](app-store-versions/localizations.md)|List All App Store Version Localizations for an App Store Version.         Get a list of localized, version-level information about an app, for all locales.|
 |[`modify`](app-store-versions/modify.md)|Update the app store version for a specific app.|
diff --git a/docs/app-store-connect/app-store-versions/create.md b/docs/app-store-connect/app-store-versions/create.md
index 443b8ae9..512d62ef 100644
--- a/docs/app-store-connect/app-store-versions/create.md
+++ b/docs/app-store-connect/app-store-versions/create.md
@@ -32,7 +32,7 @@ Alphanumeric ID value of the Build
 ##### `--copyright=COPYRIGHT`
 
 
-The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, "2008 Acme Inc."). Do not provide a URL.
+The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, `2008 Acme Inc.`). Do not provide a URL.
 ##### `--version-string, --app-store-version=VERSION_STRING`
 
 
diff --git a/docs/app-store-connect/app-store-versions/localizations.md b/docs/app-store-connect/app-store-versions/localizations.md
new file mode 100644
index 00000000..a9fe6677
--- /dev/null
+++ b/docs/app-store-connect/app-store-versions/localizations.md
@@ -0,0 +1,80 @@
+
+localizations
+=============
+
+
+**List All App Store Version Localizations for an App Store Version.         Get a list of localized, version-level information about an app, for all locales.**
+### Usage
+```bash
+app-store-connect app-store-versions localizations [-h] [--log-stream STREAM] [--no-color] [--version] [-s] [-v]
+    [--log-api-calls]
+    [--json]
+    [--issuer-id ISSUER_ID]
+    [--key-id KEY_IDENTIFIER]
+    [--private-key PRIVATE_KEY]
+    [--certificates-dir CERTIFICATES_DIRECTORY]
+    [--profiles-dir PROFILES_DIRECTORY]
+    APP_STORE_VERSION_ID
+```
+### Required arguments for action `localizations`
+
+##### `APP_STORE_VERSION_ID`
+
+
+UUID value of the App Store Version
+### Optional arguments for command `app-store-connect`
+
+##### `--log-api-calls`
+
+
+Turn on logging for App Store Connect API HTTP requests
+##### `--json`
+
+
+Whether to show the resource in JSON format
+##### `--issuer-id=ISSUER_ID`
+
+
+App Store Connect API Key Issuer ID. Identifies the issuer who created the authentication token. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_ISSUER_ID`. Alternatively to entering `ISSUER_ID` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--key-id=KEY_IDENTIFIER`
+
+
+App Store Connect API Key ID. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_KEY_IDENTIFIER`. Alternatively to entering `KEY_IDENTIFIER` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--private-key=PRIVATE_KEY`
+
+
+App Store Connect API private key used for JWT authentication to communicate with Apple services. Learn more at https://developer.apple.com/documentation/appstoreconnectapi/creating_api_keys_for_app_store_connect_api. If not provided, the key will be searched from the following directories in sequence for a private key file with the name `AuthKey_<key_identifier>.p8`: private_keys, ~/private_keys, ~/.private_keys, ~/.appstoreconnect/private_keys, where <key_identifier> is the value of --key-id. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_PRIVATE_KEY`. Alternatively to entering `PRIVATE_KEY` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--certificates-dir=CERTIFICATES_DIRECTORY`
+
+
+Directory where the code signing certificates will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Certificates`
+##### `--profiles-dir=PROFILES_DIRECTORY`
+
+
+Directory where the provisioning profiles will be saved. Default:&nbsp;`$HOME/Library/MobileDevice/Provisioning Profiles`
+### Common options
+
+##### `-h, --help`
+
+
+show this help message and exit
+##### `--log-stream=stderr | stdout`
+
+
+Log output stream. Default `stderr`
+##### `--no-color`
+
+
+Do not use ANSI colors to format terminal output
+##### `--version`
+
+
+Show tool version and exit
+##### `-s, --silent`
+
+
+Disable log output for commands
+##### `-v, --verbose`
+
+
+Enable verbose logging for commands
\ No newline at end of file
diff --git a/docs/app-store-connect/app-store-versions/modify.md b/docs/app-store-connect/app-store-versions/modify.md
index 3432b13e..d3cbd3a2 100644
--- a/docs/app-store-connect/app-store-versions/modify.md
+++ b/docs/app-store-connect/app-store-versions/modify.md
@@ -36,7 +36,7 @@ Alphanumeric ID value of the Build
 ##### `--copyright=COPYRIGHT`
 
 
-The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, "2008 Acme Inc."). Do not provide a URL.
+The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, `2008 Acme Inc.`). Do not provide a URL.
 ##### `--earliest-release-date=EARLIEST_RELEASE_DATE`
 
 
diff --git a/docs/app-store-connect/builds/submit-to-app-store.md b/docs/app-store-connect/builds/submit-to-app-store.md
index a2e98229..1c587ff0 100644
--- a/docs/app-store-connect/builds/submit-to-app-store.md
+++ b/docs/app-store-connect/builds/submit-to-app-store.md
@@ -14,12 +14,21 @@ app-store-connect builds submit-to-app-store [-h] [--log-stream STREAM] [--no-co
     [--private-key PRIVATE_KEY]
     [--certificates-dir CERTIFICATES_DIRECTORY]
     [--profiles-dir PROFILES_DIRECTORY]
+    [--max-build-processing-wait MAX_BUILD_PROCESSING_WAIT]
+    [--app-store-version-info APP_STORE_VERSION_INFO]
     [--copyright COPYRIGHT]
     [--earliest-release-date EARLIEST_RELEASE_DATE]
     [--platform PLATFORM]
     [--release-type RELEASE_TYPE]
     [--version-string VERSION_STRING]
-    [--max-build-processing-wait MAX_BUILD_PROCESSING_WAIT]
+    [--description DESCRIPTION]
+    [--keywords KEYWORDS]
+    [--locale LOCALE_DEFAULT]
+    [--marketing-url MARKETING_URL]
+    [--promotional-text PROMOTIONAL_TEXT]
+    [--support-url SUPPORT_URL]
+    [--whats-new WHATS_NEW]
+    [--app-store-version-localizations APP_STORE_VERSION_LOCALIZATION_INFOS]
     BUILD_ID_RESOURCE_ID
 ```
 ### Required arguments for action `submit-to-app-store`
@@ -30,10 +39,18 @@ app-store-connect builds submit-to-app-store [-h] [--log-stream STREAM] [--no-co
 Alphanumeric ID value of the Build
 ### Optional arguments for action `submit-to-app-store`
 
+##### `--max-build-processing-wait, -w=MAX_BUILD_PROCESSING_WAIT`
+
+
+Maximum amount of minutes to wait for the freshly uploaded build to be processed by Apple and retry submitting the build for (beta) review. Works in conjunction with TestFlight beta review submission, or App Store review submission and operations that depend on either one of those. If the processing is not finished within the specified timeframe, further submission will be terminated. Waiting will be skipped if the value is set to 0, further actions might fail if the build is not processed yet. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_MAX_BUILD_PROCESSING_WAIT`. [Default: 20]
+##### `--app-store-version-info, -vi=APP_STORE_VERSION_INFO`
+
+
+General App information and version release options for App Store version submission as a JSON encoded object. Alternative to individually defining `--platform`, `--copyright`, `--earliest-release-date`, `--release-type` and `--version-string`. For example, `{"platform": "IOS", "copyright": "2008 Acme Inc.", "version_string": "1.0.8", "release_type": "SCHEDULED", "earliest_release_date": "2021-11-10T14:00:00+00:00"}`. Definitions from the JSON will be overridden by dedicated CLI options if provided. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_APP_STORE_VERSION_INFO`. Alternatively to entering `APP_STORE_VERSION_INFO` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
 ##### `--copyright=COPYRIGHT`
 
 
-The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, "2008 Acme Inc."). Do not provide a URL.
+The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, `2008 Acme Inc.`). Do not provide a URL.
 ##### `--earliest-release-date=EARLIEST_RELEASE_DATE`
 
 
@@ -50,10 +67,38 @@ Choose when to release the app. You can either manually release the app at a lat
 
 
 Version of the build published to App Store that identifies an iteration of the bundle. The string can only contain one to three groups of numeric characters (0-9) separated by period in the format [Major].[Minor].[Patch]. For example `3.2.46`
-##### `--max-build-processing-wait, -w=MAX_BUILD_PROCESSING_WAIT`
+##### `--description, -d=DESCRIPTION`
 
 
-Maximum amount of minutes to wait for the freshly uploaded build to be processed by Apple and retry submitting the build for (beta) review. Works in conjunction with TestFlight beta review submission, or App Store review submission and operations that depend on either one of those. If the processing is not finished within the specified timeframe, further submission will be terminated. Waiting will be skipped if the value is set to 0, further actions might fail if the build is not processed yet. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_MAX_BUILD_PROCESSING_WAIT`. [Default: 20]
+A description of your app, detailing features and functionality.
+##### `--keywords, -k=KEYWORDS`
+
+
+Include one or more keywords that describe your app. Keywords make App Store search results more accurate. Separate keywords with an English comma, Chinese comma, or a mix of both.
+##### `--locale, -l=da | de-DE | el | en-AU | en-CA | en-GB | en-US | es-ES | es-MX | fi | fr-CA | fr-FR | id | it | ja | ko | ms | nl-NL | no | pt-BR | pt-PT | ru | sv | th | tr | vi | zh-Hans | zh-Hant`
+
+
+The locale code name for App Store metadata in different languages. In case not provided, application's primary locale is used instead. Learn more from https://developer.apple.com/documentation/appstoreconnectapi/betabuildlocalizationcreaterequest/data/attributes
+##### `--marketing-url=MARKETING_URL`
+
+
+A URL with marketing information about your app. This URL will be visible on the App Store.
+##### `--promotional-text=PROMOTIONAL_TEXT`
+
+
+Promotional text lets you inform your App Store visitors of any current app features without requiring an updated submission. This text will appear above your description on the App Store for customers with devices running iOS 11 or later, and macOS 10.13 or later.
+##### `--support-url=SUPPORT_URL`
+
+
+A URL with support information for your app. This URL will be visible on the App Store.
+##### `--whats-new, -n=WHATS_NEW`
+
+
+Describe what's new in this version of your app, such as new features, improvements, and bug fixes. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_WHATS_NEW`. Alternatively to entering `WHATS_NEW` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+##### `--app-store-version-localizations, -vl=APP_STORE_VERSION_LOCALIZATION_INFOS`
+
+
+Localized App Store version meta information for App Store version submission as a JSON encoded list. Alternative to individually defining version release notes and other options via dedicated CLI options such as `--whats-new`. Definitions for duplicate locales are not allowed. For example, `[{"description": "App description", "keywords": "keyword, other keyword", "locale": "en-US", "marketing_url": "https://example.com", "promotional_text": "Promotional text", "support_url": "https://example.com", "whats_new": "Fixes an issue .."}]`. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_APP_STORE_VERSION_LOCALIZATIONS`. Alternatively to entering APP_STORE_VERSION_LOCALIZATIONS in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
 ### Optional arguments for command `app-store-connect`
 
 ##### `--log-api-calls`
diff --git a/docs/app-store-connect/publish.md b/docs/app-store-connect/publish.md
index c55f898e..6151c1cc 100644
--- a/docs/app-store-connect/publish.md
+++ b/docs/app-store-connect/publish.md
@@ -21,16 +21,23 @@ app-store-connect publish [-h] [--log-stream STREAM] [--no-color] [--version] [-
     [--skip-package-upload]
     [--max-build-processing-wait MAX_BUILD_PROCESSING_WAIT]
     [--beta-build-localizations BETA_BUILD_LOCALIZATIONS]
-    [--locale LOCALE_DEFAULT]
-    [--whats-new WHATS_NEW]
     [--testflight]
     [--beta-group BETA_GROUP_NAMES_OPTIONAL]
     [--app-store]
     [--platform PLATFORM_OPTIONAL]
+    [--app-store-version-info APP_STORE_VERSION_INFO]
     [--copyright COPYRIGHT]
     [--earliest-release-date EARLIEST_RELEASE_DATE]
     [--release-type RELEASE_TYPE]
     [--version-string VERSION_STRING]
+    [--description DESCRIPTION]
+    [--keywords KEYWORDS]
+    [--marketing-url MARKETING_URL]
+    [--promotional-text PROMOTIONAL_TEXT]
+    [--support-url SUPPORT_URL]
+    [--app-store-version-localizations APP_STORE_VERSION_LOCALIZATION_INFOS]
+    [--locale LOCALE_DEFAULT]
+    [--whats-new WHATS_NEW]
     [--altool-retries ALTOOL_RETRIES_COUNT]
     [--altool-retry-wait ALTOOL_RETRY_WAIT]
     [--altool-verbose-logging]
@@ -67,14 +74,6 @@ Maximum amount of minutes to wait for the freshly uploaded build to be processed
 
 
 Localized beta test info for what's new in the uploaded build as a JSON encoded list. For example, `[{"locale": "en-US", "whats_new": "What's new in English"}]`. See `--locale` for possible locale options. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_BETA_BUILD_LOCALIZATIONS`. Alternatively to entering `BETA_BUILD_LOCALIZATIONS` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
-##### `--locale, -l=da | de-DE | el | en-AU | en-CA | en-GB | en-US | es-ES | es-MX | fi | fr-CA | fr-FR | id | it | ja | ko | ms | nl-NL | no | pt-BR | pt-PT | ru | sv | th | tr | vi | zh-Hans | zh-Hant`
-
-
-The locale code name for displaying localized "What's new" content in TestFlight. In case not provided, application's primary locale from test information is used instead. Learn more from https://developer.apple.com/documentation/appstoreconnectapi/betabuildlocalizationcreaterequest/data/attributes
-##### `--whats-new, -n=WHATS_NEW`
-
-
-Describe the changes and additions to the build and indicate the features you would like your users to tests. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_WHATS_NEW`. Alternatively to entering `WHATS_NEW` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
 ### Optional arguments to submit build to TestFlight for beta review
 
 ##### `--testflight, -t`
@@ -97,10 +96,14 @@ Enable submission of an app to App Store app review procedure.
 
 
 App Store Version platform
+##### `--app-store-version-info, -vi=APP_STORE_VERSION_INFO`
+
+
+General App information and version release options for App Store version submission as a JSON encoded object. Alternative to individually defining `--platform`, `--copyright`, `--earliest-release-date`, `--release-type` and `--version-string`. For example, `{"platform": "IOS", "copyright": "2008 Acme Inc.", "version_string": "1.0.8", "release_type": "SCHEDULED", "earliest_release_date": "2021-11-10T14:00:00+00:00"}`. Definitions from the JSON will be overridden by dedicated CLI options if provided. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_APP_STORE_VERSION_INFO`. Alternatively to entering `APP_STORE_VERSION_INFO` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
 ##### `--copyright=COPYRIGHT`
 
 
-The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, "2008 Acme Inc."). Do not provide a URL.
+The name of the person or entity that owns the exclusive rights to your app, preceded by the year the rights were obtained (for example, `2008 Acme Inc.`). Do not provide a URL.
 ##### `--earliest-release-date=EARLIEST_RELEASE_DATE`
 
 
@@ -113,6 +116,40 @@ Choose when to release the app. You can either manually release the app at a lat
 
 
 Version of the build published to App Store that identifies an iteration of the bundle. The string can only contain one to three groups of numeric characters (0-9) separated by period in the format [Major].[Minor].[Patch]. For example `3.2.46`
+##### `--description, -d=DESCRIPTION`
+
+
+A description of your app, detailing features and functionality.
+##### `--keywords, -k=KEYWORDS`
+
+
+Include one or more keywords that describe your app. Keywords make App Store search results more accurate. Separate keywords with an English comma, Chinese comma, or a mix of both.
+##### `--marketing-url=MARKETING_URL`
+
+
+A URL with marketing information about your app. This URL will be visible on the App Store.
+##### `--promotional-text=PROMOTIONAL_TEXT`
+
+
+Promotional text lets you inform your App Store visitors of any current app features without requiring an updated submission. This text will appear above your description on the App Store for customers with devices running iOS 11 or later, and macOS 10.13 or later.
+##### `--support-url=SUPPORT_URL`
+
+
+A URL with support information for your app. This URL will be visible on the App Store.
+##### `--app-store-version-localizations, -vl=APP_STORE_VERSION_LOCALIZATION_INFOS`
+
+
+Localized App Store version meta information for App Store version submission as a JSON encoded list. Alternative to individually defining version release notes and other options via dedicated CLI options such as `--whats-new`. Definitions for duplicate locales are not allowed. For example, `[{"description": "App description", "keywords": "keyword, other keyword", "locale": "en-US", "marketing_url": "https://example.com", "promotional_text": "Promotional text", "support_url": "https://example.com", "whats_new": "Fixes an issue .."}]`. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_APP_STORE_VERSION_LOCALIZATIONS`. Alternatively to entering APP_STORE_VERSION_LOCALIZATIONS in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
+### Optional arguments to add localized meta information about build for TestFlight or App Store review submission
+
+##### `--locale, -l=da | de-DE | el | en-AU | en-CA | en-GB | en-US | es-ES | es-MX | fi | fr-CA | fr-FR | id | it | ja | ko | ms | nl-NL | no | pt-BR | pt-PT | ru | sv | th | tr | vi | zh-Hans | zh-Hant`
+
+
+The locale code name for App Store metadata in different languages, or for displaying localized "What's new" content in TestFlight. In case not provided, application's primary locale is used instead. Learn more from https://developer.apple.com/documentation/appstoreconnectapi/betabuildlocalizationcreaterequest/data/attributes
+##### `--whats-new, -n=WHATS_NEW`
+
+
+Release notes either for TestFlight or App Store review submission. Describe what's new in this version of your app, such as new features, improvements, and bug fixes. If not given, the value will be checked from the environment variable `APP_STORE_CONNECT_WHATS_NEW`. Alternatively to entering `WHATS_NEW` in plaintext, it may also be specified using the `@env:` prefix followed by an environment variable name, or the `@file:` prefix followed by a path to the file containing the value. Example: `@env:<variable>` uses the value in the environment variable named `<variable>`, and `@file:<file_path>` uses the value from the file at `<file_path>`.
 ### Optional arguments to set Apple's altool configuration options
 
 ##### `--altool-retries=ALTOOL_RETRIES_COUNT`
diff --git a/src/codemagic/__version__.py b/src/codemagic/__version__.py
index 8f9e3a0a..592a805f 100644
--- a/src/codemagic/__version__.py
+++ b/src/codemagic/__version__.py
@@ -1,5 +1,5 @@
 __title__ = 'codemagic-cli-tools'
 __description__ = 'CLI tools used in Codemagic builds'
-__version__ = '0.13.0'
+__version__ = '0.13.1'
 __url__ = 'https://github.com/codemagic-ci-cd/cli-tools'
 __licence__ = 'GNU General Public License v3.0'
diff --git a/src/codemagic/apple/app_store_connect/api_client.py b/src/codemagic/apple/app_store_connect/api_client.py
index 9d348beb..49079e76 100644
--- a/src/codemagic/apple/app_store_connect/api_client.py
+++ b/src/codemagic/apple/app_store_connect/api_client.py
@@ -22,6 +22,7 @@
 from .provisioning import Profiles
 from .provisioning import SigningCertificates
 from .testflight import BetaGroups
+from .versioning import AppStoreVersionLocalizations
 from .versioning import AppStoreVersions
 from .versioning import AppStoreVersionSubmissions
 from .versioning import BetaAppReviewSubmissions
@@ -99,14 +100,27 @@ def _get_jwt_payload(self) -> Dict:
     def generate_auth_headers(self) -> Dict[str, str]:
         return {'Authorization': f'Bearer {self.jwt}'}
 
-    def _paginate(self, url, params, page_size) -> PaginateResult:
+    @classmethod
+    def _get_pagination_page_size(cls, page_size: Optional[int], limit: Optional[int]) -> Optional[int]:
+        if page_size is not None and limit is not None:
+            return min(page_size, limit)
+        return page_size or limit
+
+    def _paginate(
+            self,
+            url: str,
+            params: Dict,
+            page_size: Optional[int],
+            limit: Optional[int],
+    ) -> PaginateResult:
         params = {k: v for k, v in (params or {}).items() if v is not None}
+        page_size = self._get_pagination_page_size(page_size, limit)
         if page_size is None:
             response = self.session.get(url, params=params).json()
         else:
             response = self.session.get(url, params={'limit': page_size, **params}).json()
         result = PaginateResult(response.get('data', []), response.get('included', []))
-        while 'next' in response['links']:
+        while 'next' in response['links'] and (limit is None or len(result.data) < limit):
             # Query params from previous pagination call can be included in the next URL
             # and duplicate parameters are not allowed, so we need to filter those out.
             parsed_url = parse.urlparse(response['links']['next'])
@@ -117,11 +131,11 @@ def _paginate(self, url, params, page_size) -> PaginateResult:
             result.included.extend(response.get('included', []))
         return result
 
-    def paginate(self, url, params=None, page_size: Optional[int] = 100) -> List[Dict]:
-        return self._paginate(url, params, page_size).data
+    def paginate(self, url, params=None, page_size: Optional[int] = 100, limit=None) -> List[Dict]:
+        return self._paginate(url, params, page_size, limit).data
 
-    def paginate_with_included(self, url, params=None, page_size: Optional[int] = 100) -> PaginateResult:
-        return self._paginate(url, params, page_size)
+    def paginate_with_included(self, url, params=None, page_size: Optional[int] = 100, limit=None) -> PaginateResult:
+        return self._paginate(url, params, page_size, limit)
 
     @property
     def apps(self) -> Apps:
@@ -131,6 +145,10 @@ def apps(self) -> Apps:
     def app_store_versions(self) -> AppStoreVersions:
         return AppStoreVersions(self)
 
+    @property
+    def app_store_version_localizations(self) -> AppStoreVersionLocalizations:
+        return AppStoreVersionLocalizations(self)
+
     @property
     def app_store_version_submissions(self) -> AppStoreVersionSubmissions:
         return AppStoreVersionSubmissions(self)
diff --git a/src/codemagic/apple/app_store_connect/apps/apps.py b/src/codemagic/apple/app_store_connect/apps/apps.py
index a9d85031..2704aabc 100644
--- a/src/codemagic/apple/app_store_connect/apps/apps.py
+++ b/src/codemagic/apple/app_store_connect/apps/apps.py
@@ -93,9 +93,12 @@ def list_pre_release_versions(self, app: Union[LinkedResourceData, ResourceId])
             url = f'{self.client.API_URL}/apps/{app}/preReleaseVersions'
         return [PreReleaseVersion(version) for version in self.client.paginate(url, page_size=None)]
 
-    def list_app_store_versions(self,
-                                app: Union[LinkedResourceData, ResourceId],
-                                resource_filter: Optional[AppStoreVersions.Filter] = None) -> List[AppStoreVersion]:
+    def list_app_store_versions(
+            self,
+            app: Union[LinkedResourceData, ResourceId],
+            resource_filter: Optional[AppStoreVersions.Filter] = None,
+            limit: Optional[int] = None,
+    ) -> List[AppStoreVersion]:
         """
         https://developer.apple.com/documentation/appstoreconnectapi/list_all_app_store_versions_for_an_app
         """
@@ -104,7 +107,7 @@ def list_app_store_versions(self,
         else:
             url = f'{self.client.API_URL}/apps/{app}/appStoreVersions'
         params = resource_filter.as_query_params() if resource_filter else None
-        app_store_versions = self.client.paginate(url, params=params, page_size=None)
+        app_store_versions = self.client.paginate(url, params=params, limit=limit)
         return [AppStoreVersion(app_store_version) for app_store_version in app_store_versions]
 
     def list_beta_app_localizations(self, app: Union[App, ResourceId]) -> List[BetaAppLocalization]:
diff --git a/src/codemagic/apple/app_store_connect/versioning/__init__.py b/src/codemagic/apple/app_store_connect/versioning/__init__.py
index 43a20d2f..443b6abc 100644
--- a/src/codemagic/apple/app_store_connect/versioning/__init__.py
+++ b/src/codemagic/apple/app_store_connect/versioning/__init__.py
@@ -1,3 +1,4 @@
+from .app_store_version_localizations import AppStoreVersionLocalizations
 from .app_store_version_submissions import AppStoreVersionSubmissions
 from .app_store_versions import AppStoreVersions
 from .beta_app_review_submissions import BetaAppReviewSubmissions
diff --git a/src/codemagic/apple/app_store_connect/versioning/app_store_version_localizations.py b/src/codemagic/apple/app_store_connect/versioning/app_store_version_localizations.py
new file mode 100644
index 00000000..d4d42051
--- /dev/null
+++ b/src/codemagic/apple/app_store_connect/versioning/app_store_version_localizations.py
@@ -0,0 +1,145 @@
+from typing import Optional
+from typing import Type
+from typing import Union
+
+from codemagic.apple.app_store_connect.resource_manager import ResourceManager
+from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
+from codemagic.apple.resources import LinkedResourceData
+from codemagic.apple.resources import Locale
+from codemagic.apple.resources import ResourceId
+from codemagic.apple.resources import ResourceType
+
+
+class AppStoreVersionLocalizations(ResourceManager[AppStoreVersionLocalization]):
+    """
+    App Store Version Localizations
+    https://developer.apple.com/documentation/appstoreconnectapi/app_metadata/app_store_version_localizations
+    """
+
+    @property
+    def resource_type(self) -> Type[AppStoreVersionLocalization]:
+        return AppStoreVersionLocalization
+
+    def read(
+        self,
+        app_store_version_localization: Union[LinkedResourceData, ResourceId],
+    ) -> AppStoreVersionLocalization:
+        """
+        https://developer.apple.com/documentation/appstoreconnectapi/read_app_store_version_localization_information
+        """
+        app_store_version_localization_id = self._get_resource_id(app_store_version_localization)
+        response = self.client.session.get(
+            f'{self.client.API_URL}/appStoreVersionLocalizations/{app_store_version_localization_id}',
+        ).json()
+        return AppStoreVersionLocalization(response['data'])
+
+    def create(
+        self,
+        app_store_version: Union[ResourceId, AppStoreVersion],
+        locale: Locale,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[str] = None,
+    ) -> AppStoreVersionLocalization:
+        """
+        https://developer.apple.com/documentation/appstoreconnectapi/create_an_app_store_version_localization
+        """
+        attributes = {
+            'locale': locale.value,
+            **self._construct_payload_attributes(
+                description=description,
+                keywords=keywords,
+                marketing_url=marketing_url,
+                promotional_text=promotional_text,
+                support_url=support_url,
+                whats_new=whats_new,
+            ),
+        }
+
+        relationships = {
+            'appStoreVersion': {
+                'data': self._get_attribute_data(app_store_version, ResourceType.APP_STORE_VERSIONS),
+            },
+        }
+
+        payload = self._get_create_payload(
+            ResourceType.APP_STORE_VERSION_LOCALIZATIONS,
+            attributes=attributes,
+            relationships=relationships,
+        )
+        response = self.client.session.post(f'{self.client.API_URL}/appStoreVersionLocalizations', json=payload).json()
+        return AppStoreVersionLocalization(response['data'], created=True)
+
+    def modify(
+        self,
+        app_store_version_localization: Union[ResourceId, AppStoreVersionLocalization],
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[str] = None,
+    ) -> AppStoreVersionLocalization:
+        """
+        https://developer.apple.com/documentation/appstoreconnectapi/modify_an_app_store_version_localization
+        """
+        attributes = self._construct_payload_attributes(
+            description=description,
+            keywords=keywords,
+            marketing_url=marketing_url,
+            promotional_text=promotional_text,
+            support_url=support_url,
+            whats_new=whats_new,
+        )
+        app_store_version_localization_id = self._get_resource_id(app_store_version_localization)
+        payload = self._get_update_payload(
+            app_store_version_localization_id,
+            ResourceType.APP_STORE_VERSION_LOCALIZATIONS,
+            attributes=attributes,
+        )
+        response = self.client.session.patch(
+            f'{self.client.API_URL}/appStoreVersionLocalizations/{app_store_version_localization_id}',
+            json=payload,
+        ).json()
+        return AppStoreVersionLocalization(response['data'])
+
+    def delete(
+        self,
+        app_store_version_localization: Union[ResourceId, AppStoreVersionLocalization],
+    ) -> None:
+        """
+        https://developer.apple.com/documentation/appstoreconnectapi/delete_an_app_store_version_localization
+        """
+        app_store_version_localization_id = self._get_resource_id(app_store_version_localization)
+        self.client.session.delete(
+            f'{self.client.API_URL}/appStoreVersionLocalizations/{app_store_version_localization_id}',
+        )
+
+    @classmethod
+    def _construct_payload_attributes(
+        cls,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[str] = None,
+    ):
+        attributes = {}
+        if description is not None:
+            attributes['description'] = description
+        if keywords is not None:
+            attributes['keywords'] = keywords
+        if marketing_url is not None:
+            attributes['marketingUrl'] = marketing_url
+        if promotional_text is not None:
+            attributes['promotionalText'] = promotional_text
+        if support_url is not None:
+            attributes['supportUrl'] = support_url
+        if whats_new is not None:
+            attributes['whatsNew'] = whats_new
+        return attributes
diff --git a/src/codemagic/apple/app_store_connect/versioning/app_store_versions.py b/src/codemagic/apple/app_store_connect/versioning/app_store_versions.py
index 29e57715..5a7f346d 100644
--- a/src/codemagic/apple/app_store_connect/versioning/app_store_versions.py
+++ b/src/codemagic/apple/app_store_connect/versioning/app_store_versions.py
@@ -12,6 +12,7 @@
 from codemagic.apple.resources import App
 from codemagic.apple.resources import AppStoreState
 from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
 from codemagic.apple.resources import AppStoreVersionSubmission
 from codemagic.apple.resources import Build
 from codemagic.apple.resources import LinkedResourceData
@@ -123,6 +124,22 @@ def read_app_store_version_submission(
         response = self.client.session.get(url).json()
         return AppStoreVersionSubmission(response['data'])
 
+    def list_app_store_version_localizations(
+        self,
+        app_store_version: Union[LinkedResourceData, ResourceId],
+    ) -> List[AppStoreVersionLocalization]:
+        """
+        https://developer.apple.com/documentation/appstoreconnectapi/list_all_app_store_version_localizations_for_an_app_store_version
+        """
+        if isinstance(app_store_version, AppStoreVersion):
+            url = app_store_version.relationships.appStoreVersionLocalizations.links.related
+        else:
+            url = f'{self.client.API_URL}/appStoreVersions/{app_store_version}/appStoreVersionLocalizations'
+        return [
+            AppStoreVersionLocalization(app_store_version_localization)
+            for app_store_version_localization in self.client.paginate(url, page_size=None)
+        ]
+
     def list_with_include(
             self,
             application_id: ResourceId,
diff --git a/src/codemagic/apple/resources/__init__.py b/src/codemagic/apple/resources/__init__.py
index f9c8fe6b..dd6aed12 100644
--- a/src/codemagic/apple/resources/__init__.py
+++ b/src/codemagic/apple/resources/__init__.py
@@ -1,5 +1,6 @@
 from .app import App
 from .app_store_version import AppStoreVersion
+from .app_store_version_localization import AppStoreVersionLocalization
 from .app_store_version_submission import AppStoreVersionSubmission
 from .beta_app_localization import BetaAppLocalization
 from .beta_app_review_detail import BetaAppReviewDetail
diff --git a/src/codemagic/apple/resources/app.py b/src/codemagic/apple/resources/app.py
index 8bae3634..37fcebbd 100644
--- a/src/codemagic/apple/resources/app.py
+++ b/src/codemagic/apple/resources/app.py
@@ -4,6 +4,7 @@
 from typing import Optional
 
 from .enums import ContentRightsDeclaration
+from .enums import Locale
 from .resource import Relationship
 from .resource import Resource
 
@@ -17,7 +18,7 @@ class App(Resource):
     class Attributes(Resource.Attributes):
         bundleId: str
         name: str
-        primaryLocale: str
+        primaryLocale: Locale
         sku: str
         availableInNewTerritories: bool
         contentRightsDeclaration: ContentRightsDeclaration
@@ -26,6 +27,8 @@ class Attributes(Resource.Attributes):
         def __post_init__(self):
             if isinstance(self.contentRightsDeclaration, str):
                 self.contentRightsDeclaration = ContentRightsDeclaration(self.contentRightsDeclaration)
+            if isinstance(self.primaryLocale, str):
+                self.primaryLocale = Locale(self.primaryLocale)
 
     @dataclass
     class Relationships(Resource.Relationships):
diff --git a/src/codemagic/apple/resources/app_store_version_localization.py b/src/codemagic/apple/resources/app_store_version_localization.py
new file mode 100644
index 00000000..9546f6ec
--- /dev/null
+++ b/src/codemagic/apple/resources/app_store_version_localization.py
@@ -0,0 +1,34 @@
+from __future__ import annotations
+
+from dataclasses import dataclass
+from typing import Optional
+
+from .enums import Locale
+from .resource import Relationship
+from .resource import Resource
+
+
+class AppStoreVersionLocalization(Resource):
+    """
+    https://developer.apple.com/documentation/appstoreconnectapi/appstoreversionlocalization
+    """
+
+    @dataclass
+    class Attributes(Resource.Attributes):
+        description: str
+        keywords: str
+        locale: Locale
+        marketingUrl: str
+        promotionalText: str
+        supportUrl: str
+        whatsNew: str
+
+        def __post_init__(self):
+            if isinstance(self.locale, str):
+                self.locale = Locale(self.locale)
+
+    @dataclass
+    class Relationships(Resource.Relationships):
+        appPreviewSets: Optional[Relationship] = None
+        appScreenshotSets: Optional[Relationship] = None
+        appStoreVersion: Optional[Relationship] = None
diff --git a/src/codemagic/apple/resources/enums.py b/src/codemagic/apple/resources/enums.py
index 60a72288..73ea7001 100644
--- a/src/codemagic/apple/resources/enums.py
+++ b/src/codemagic/apple/resources/enums.py
@@ -257,6 +257,7 @@ class ReleaseType(ResourceEnum):
 class ResourceType(ResourceEnum):
     APPS = 'apps'
     APP_STORE_VERSIONS = 'appStoreVersions'
+    APP_STORE_VERSION_LOCALIZATIONS = 'appStoreVersionLocalizations'
     APP_STORE_VERSION_SUBMISSIONS = 'appStoreVersionSubmissions'
     BETA_APP_LOCALIZATIONS = 'betaAppLocalizations'
     BETA_APP_REVIEW_DETAILS = 'betaAppReviewDetails'
diff --git a/src/codemagic/cli/argument/argument.py b/src/codemagic/cli/argument/argument.py
index 65eee048..88f078c9 100644
--- a/src/codemagic/cli/argument/argument.py
+++ b/src/codemagic/cli/argument/argument.py
@@ -67,7 +67,7 @@ def register(self, argument_group: argparse._ArgumentGroup):
             kwargs['type'] = self.value.type
         self._parser_argument = argument_group.add_argument(
             *self.value.flags,
-            help=self.get_description(),
+            help=self.get_description().replace('`', ''),
             dest=self.value.key,
             **kwargs)
 
diff --git a/src/codemagic/cli/argument/typed_cli_argument.py b/src/codemagic/cli/argument/typed_cli_argument.py
index f4e5f021..75d93818 100644
--- a/src/codemagic/cli/argument/typed_cli_argument.py
+++ b/src/codemagic/cli/argument/typed_cli_argument.py
@@ -130,7 +130,8 @@ def _get_from_environment(self) -> T:
         except KeyError:
             raise argparse.ArgumentTypeError(f'Environment variable "{key}" is not defined')
         except argparse.ArgumentTypeError as ate:
-            raise argparse.ArgumentTypeError(f'Provided value in environment variable "{key}" is not valid') from ate
+            error_message = f'Provided value in environment variable "{key}" is not valid. {ate}'
+            raise argparse.ArgumentTypeError(error_message) from ate
 
     def _get_from_file(self) -> T:
         path = Path(self._raw_value[6:])
@@ -142,7 +143,8 @@ def _get_from_file(self) -> T:
         try:
             return self._apply_type(content)
         except argparse.ArgumentTypeError as ate:
-            raise argparse.ArgumentTypeError(f'Provided value in file "{path}" is not valid') from ate
+            error_message = f'Provided value in file "{path}" is not valid. {ate}'
+            raise argparse.ArgumentTypeError(error_message) from ate
 
     def _parse_value(self) -> T:
         if self._is_from_environment():
diff --git a/src/codemagic/tools/_app_store_connect/abstract_base_action.py b/src/codemagic/tools/_app_store_connect/abstract_base_action.py
index 3fd1ad27..a77e0f90 100644
--- a/src/codemagic/tools/_app_store_connect/abstract_base_action.py
+++ b/src/codemagic/tools/_app_store_connect/abstract_base_action.py
@@ -3,6 +3,7 @@
 import logging
 import pathlib
 from abc import ABCMeta
+from abc import abstractmethod
 from datetime import datetime
 from typing import List
 from typing import Optional
@@ -15,6 +16,7 @@
 from codemagic.apple.resources import App
 from codemagic.apple.resources import AppStoreState
 from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
 from codemagic.apple.resources import AppStoreVersionSubmission
 from codemagic.apple.resources import BetaAppReviewSubmission
 from codemagic.apple.resources import BetaBuildLocalization
@@ -26,11 +28,18 @@
 from codemagic.apple.resources import ResourceId
 from codemagic.mixins import PathFinderMixin
 
+from .arguments import AppStoreVersionInfo
+from .arguments import AppStoreVersionLocalizationInfo
 from .arguments import BetaBuildInfo
 from .arguments import Types
 from .resource_manager_mixin import ResourceManagerMixin
 from .resource_printer import ResourcePrinter
 
+AppStoreVersionLocalizationInfos = Union[
+    List[AppStoreVersionLocalizationInfo],
+    Types.AppStoreVersionLocalizationInfoArgument,
+]
+
 
 class AbstractBaseAction(ResourceManagerMixin, PathFinderMixin, metaclass=ABCMeta):
     logger: logging.Logger
@@ -54,101 +63,211 @@ def echo(cls, message: str, *args, **kwargs) -> None:
     def _assert_api_client_credentials(self, custom_error: Optional[str] = None):
         ...
 
+    # Action signatures in alphabetical order
+
+    @abstractmethod
+    def add_beta_test_info(
+        self,
+        build_id: ResourceId,
+        beta_build_localizations: Optional[Union[List[BetaBuildInfo], Types.BetaBuildLocalizations]] = None,
+        locale: Optional[Locale] = None,
+        whats_new: Optional[Types.WhatsNewArgument] = None,
+    ):
+        from .action_groups import BuildsActionGroup
+        _ = BuildsActionGroup.add_beta_test_info  # Implementation
+        raise NotImplementedError()
+
+    @abstractmethod
+    def add_build_to_beta_groups(
+        self,
+        build_id: ResourceId,
+        beta_group_names: Sequence[str],
+    ):
+        from .action_groups import BetaGroupsActionGroup
+        _ = BetaGroupsActionGroup.add_build_to_beta_groups  # Implementation
+        raise NotImplementedError()
+
+    @abstractmethod
     def create_app_store_version(
-            self,
-            build_id: Union[ResourceId, Build],
-            app_id: Optional[Union[ResourceId, App]] = None,
-            platform: Platform = Platform.IOS,
-            copyright: Optional[str] = None,
-            version_string: Optional[str] = None,
-            should_print: bool = True,
+        self,
+        build_id: ResourceId,
+        platform: Platform = Platform.IOS,
+        copyright: Optional[str] = None,
+        version_string: Optional[str] = None,
+        release_type: Optional[ReleaseType] = None,
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
+        should_print: bool = True,
     ) -> AppStoreVersion:
-        ...
+        from .action_groups import AppStoreVersionsActionGroup
+        _ = AppStoreVersionsActionGroup.create_app_store_version  # Implementation
+        raise NotImplementedError()
+
+    @abstractmethod
+    def create_app_store_version_localization(
+        self,
+        app_store_version_id: ResourceId,
+        locale: Locale,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersionLocalization:
+        from .action_groups import AppStoreVersionLocalizationsActionGroup
+        _ = AppStoreVersionLocalizationsActionGroup.create_app_store_version_localization  # Implementation
+        raise NotImplementedError()
 
+    @abstractmethod
     def create_app_store_version_submission(
-            self, app_store_version_id: ResourceId, should_print: bool = True) -> AppStoreVersionSubmission:
-        ...
+        self,
+        app_store_version_id: ResourceId,
+        should_print: bool = True,
+    ) -> AppStoreVersionSubmission:
+        from .action_groups import AppStoreVersionSubmissionsActionGroup
+        _ = AppStoreVersionSubmissionsActionGroup.create_app_store_version_submission  # Implementation
+        raise NotImplementedError()
 
+    @abstractmethod
     def create_beta_app_review_submission(
-            self, build_id: ResourceId, should_print: bool = True) -> BetaAppReviewSubmission:
-        ...
+        self,
+        build_id: ResourceId,
+        should_print: bool = True,
+    ) -> BetaAppReviewSubmission:
+        from .action_groups import BetaAppReviewSubmissionsActionGroup
+        _ = BetaAppReviewSubmissionsActionGroup.create_beta_app_review_submission  # Implementation
+        raise NotImplementedError()
 
+    @abstractmethod
     def create_beta_build_localization(
-            self,
-            build_id: ResourceId,
-            locale: Optional[Locale],
-            whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
-            should_print: bool = True) -> BetaBuildLocalization:
-        ...
+        self,
+        build_id: ResourceId,
+        locale: Optional[Locale],
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        should_print: bool = True,
+    ) -> BetaBuildLocalization:
+        from .action_groups import BetaBuildLocalizationsActionGroup
+        _ = BetaBuildLocalizationsActionGroup.create_beta_build_localization  # Implementation
+        raise NotImplementedError()
 
-    def add_build_to_beta_groups(self, build_id: ResourceId, beta_group_names: Sequence[str]):
-        ...
+    @abstractmethod
+    def list_app_store_version_localizations(
+        self,
+        app_store_version_id: ResourceId,
+        should_print: bool = True,
+    ) -> List[AppStoreVersionLocalization]:
+        from .action_groups import AppStoreVersionsActionGroup
+        _ = AppStoreVersionsActionGroup.list_app_store_version_localizations  # Implementation
+        raise NotImplementedError()
 
-    def add_beta_test_info(
-            self,
-            build_id: ResourceId,
-            beta_build_localizations: Optional[Union[List[BetaBuildInfo], Types.BetaBuildLocalizations]] = None,
-            locale: Optional[Locale] = None,
-            whats_new: Optional[Types.WhatsNewArgument] = None):
-        ...
+    @abstractmethod
+    def list_apps(
+        self,
+        bundle_id_identifier: Optional[str] = None,
+        bundle_id_identifier_strict_match: bool = False,
+        application_id: Optional[ResourceId] = None,
+        application_name: Optional[str] = None,
+        application_sku: Optional[str] = None,
+        version_string: Optional[str] = None,
+        platform: Optional[Platform] = None,
+        app_store_state: Optional[AppStoreState] = None,
+        should_print: bool = True,
+    ) -> List[App]:
+        from .action_groups import AppsActionGroup
+        _ = AppsActionGroup.list_apps  # Implementation
+        raise NotImplementedError()
 
-    def update_app_store_version(
-            self,
-            app_store_version_id: ResourceId,
-            build_id: Optional[ResourceId] = None,
-            copyright: Optional[str] = None,
-            earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
-            release_type: Optional[ReleaseType] = None,
-            version_string: Optional[str] = None,
-            should_print: bool = True) -> AppStoreVersion:
-        ...
+    @abstractmethod
+    def list_builds(
+        self,
+        application_id: Optional[ResourceId] = None,
+        expired: Optional[bool] = None,
+        not_expired: Optional[bool] = None,
+        build_id: Optional[ResourceId] = None,
+        pre_release_version: Optional[str] = None,
+        processing_state: Optional[BuildProcessingState] = None,
+        build_version_number: Optional[int] = None,
+        should_print: bool = True,
+    ) -> List[Build]:
+        from ..app_store_connect import AppStoreConnect
+        _ = AppStoreConnect.list_builds  # Implementation
+        raise NotImplementedError()
 
-    def wait_until_build_is_processed(
+    @abstractmethod
+    def submit_to_app_store(
         self,
-        build: Build,
-        max_processing_minutes: int,
-        retry_wait_seconds: int = 30,
-    ) -> Build:
-        ...
+        build_id: ResourceId,
+        max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
+        # App Store Version information arguments
+        copyright: Optional[str] = None,
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
+        platform: Platform = Platform.IOS,
+        release_type: Optional[ReleaseType] = None,
+        version_string: Optional[str] = None,
+        app_store_version_info: Optional[Union[AppStoreVersionInfo, Types.AppStoreVersionInfoArgument]] = None,
+        # App Store Version Localization arguments
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        locale: Optional[Locale] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        app_store_version_localizations: Optional[AppStoreVersionLocalizationInfos] = None,
+    ) -> AppStoreVersionSubmission:
+        from .action_groups import BuildsActionGroup
+        _ = BuildsActionGroup.submit_to_app_store  # Implementation
+        raise NotImplementedError()
 
+    @abstractmethod
     def submit_to_testflight(
-            self,
-            build_id: ResourceId,
-            max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
+        self,
+        build_id: ResourceId,
+        max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
     ) -> BetaAppReviewSubmission:
-        ...
+        from .action_groups import BuildsActionGroup
+        _ = BuildsActionGroup.submit_to_testflight  # Implementation
+        raise NotImplementedError()
 
-    def submit_to_app_store(
-            self,
-            build_id: ResourceId,
-            copyright: Optional[str] = None,
-            earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
-            max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
-            platform: Platform = Platform.IOS,
-            release_type: Optional[ReleaseType] = None,
-            version_string: Optional[str] = None,
-    ) -> AppStoreVersionSubmission:
-        ...
+    @abstractmethod
+    def update_app_store_version(
+        self,
+        app_store_version_id: ResourceId,
+        build_id: Optional[ResourceId] = None,
+        copyright: Optional[str] = None,
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
+        release_type: Optional[ReleaseType] = None,
+        version_string: Optional[str] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersion:
+        from .action_groups import AppStoreVersionsActionGroup
+        _ = AppStoreVersionsActionGroup.update_app_store_version  # Implementation
+        raise NotImplementedError()
 
-    def list_apps(self,
-                  bundle_id_identifier: Optional[str] = None,
-                  bundle_id_identifier_strict_match: bool = False,
-                  application_id: Optional[ResourceId] = None,
-                  application_name: Optional[str] = None,
-                  application_sku: Optional[str] = None,
-                  version_string: Optional[str] = None,
-                  platform: Optional[Platform] = None,
-                  app_store_state: Optional[AppStoreState] = None,
-                  should_print: bool = True) -> List[App]:
-        ...
+    @abstractmethod
+    def update_app_store_version_localization(
+        self,
+        app_store_version_localization_id: ResourceId,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersionLocalization:
+        from .action_groups import AppStoreVersionLocalizationsActionGroup
+        _ = AppStoreVersionLocalizationsActionGroup.update_app_store_version_localization  # Implementation
+        raise NotImplementedError()
 
-    def list_builds(self,
-                    application_id: Optional[ResourceId] = None,
-                    expired: Optional[bool] = None,
-                    not_expired: Optional[bool] = None,
-                    build_id: Optional[ResourceId] = None,
-                    pre_release_version: Optional[str] = None,
-                    processing_state: Optional[BuildProcessingState] = None,
-                    build_version_number: Optional[int] = None,
-                    should_print: bool = True) -> List[Build]:
-        ...
+    @abstractmethod
+    def wait_until_build_is_processed(
+        self,
+        build: Build,
+        max_processing_minutes: int,
+        retry_wait_seconds: int = 30,
+    ) -> Build:
+        from .action_groups import BuildsActionGroup
+        _ = BuildsActionGroup.wait_until_build_is_processed  # Implementation
+        raise NotImplementedError()
diff --git a/src/codemagic/tools/_app_store_connect/action_group.py b/src/codemagic/tools/_app_store_connect/action_group.py
index 68e21ad3..15f46363 100644
--- a/src/codemagic/tools/_app_store_connect/action_group.py
+++ b/src/codemagic/tools/_app_store_connect/action_group.py
@@ -10,6 +10,10 @@ class AppStoreConnectActionGroup(cli.ActionGroup):
         name='app-store-versions',
         description='Manage the information related to an App Store version of your app',
     )
+    APP_STORE_VERSION_LOCALIZATIONS = cli.ActionGroupProperties(
+        name='app-store-version-localizations',
+        description='Create and maintain version-specific App Store metadata that is localized.',
+    )
     APP_STORE_VERSION_SUBMISSIONS = cli.ActionGroupProperties(
         name='app-store-version-submissions',
         description="Manage your application's App Store version review process",
diff --git a/src/codemagic/tools/_app_store_connect/action_groups/__init__.py b/src/codemagic/tools/_app_store_connect/action_groups/__init__.py
index fee9d72b..db5809fd 100644
--- a/src/codemagic/tools/_app_store_connect/action_groups/__init__.py
+++ b/src/codemagic/tools/_app_store_connect/action_groups/__init__.py
@@ -1,3 +1,4 @@
+from .app_store_version_localizations_action_group import AppStoreVersionLocalizationsActionGroup
 from .app_store_version_submissions_action_group import AppStoreVersionSubmissionsActionGroup
 from .app_store_versions_action_group import AppStoreVersionsActionGroup
 from .apps_action_group import AppsActionGroup
diff --git a/src/codemagic/tools/_app_store_connect/action_groups/app_store_version_localizations_action_group.py b/src/codemagic/tools/_app_store_connect/action_groups/app_store_version_localizations_action_group.py
new file mode 100644
index 00000000..2e86899c
--- /dev/null
+++ b/src/codemagic/tools/_app_store_connect/action_groups/app_store_version_localizations_action_group.py
@@ -0,0 +1,143 @@
+from __future__ import annotations
+
+from abc import ABCMeta
+from typing import Optional
+from typing import Union
+
+from codemagic import cli
+from codemagic.apple.resources import AppStoreVersionLocalization
+from codemagic.apple.resources import Locale
+from codemagic.apple.resources import ResourceId
+
+from ..abstract_base_action import AbstractBaseAction
+from ..action_group import AppStoreConnectActionGroup
+from ..arguments import AppStoreVersionArgument
+from ..arguments import AppStoreVersionLocalizationArgument
+from ..arguments import CommonArgument
+from ..arguments import Types
+
+
+class AppStoreVersionLocalizationsActionGroup(AbstractBaseAction, metaclass=ABCMeta):
+
+    @cli.action(
+        'get',
+        AppStoreVersionLocalizationArgument.APP_STORE_VERSION_LOCALIZATION_ID,
+        action_group=AppStoreConnectActionGroup.APP_STORE_VERSION_LOCALIZATIONS,
+    )
+    def get_app_store_version_localization(
+        self,
+        app_store_version_localization_id: ResourceId,
+        should_print: bool = True,
+    ) -> AppStoreVersionLocalization:
+        """
+        Read App Store Version Localization Information.
+        Get localized version-level information.
+        """
+        return self._get_resource(
+            app_store_version_localization_id,
+            self.api_client.app_store_version_localizations,
+            should_print,
+        )
+
+    @cli.action(
+        'create',
+        AppStoreVersionArgument.APP_STORE_VERSION_ID,
+        AppStoreVersionLocalizationArgument.LOCALE,
+        AppStoreVersionLocalizationArgument.DESCRIPTION,
+        AppStoreVersionLocalizationArgument.KEYWORDS,
+        AppStoreVersionLocalizationArgument.MARKETING_URL,
+        AppStoreVersionLocalizationArgument.PROMOTIONAL_TEXT,
+        AppStoreVersionLocalizationArgument.SUPPORT_URL,
+        AppStoreVersionLocalizationArgument.WHATS_NEW,
+        action_group=AppStoreConnectActionGroup.APP_STORE_VERSION_LOCALIZATIONS,
+    )
+    def create_app_store_version_localization(
+        self,
+        app_store_version_id: ResourceId,
+        locale: Locale,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersionLocalization:
+        """
+        Create an App Store Version Localization.
+        Add localized version-level information for a new locale.
+        """
+        create_params = dict(
+            app_store_version=app_store_version_id,
+            locale=locale,
+            description=description,
+            keywords=keywords,
+            marketing_url=marketing_url,
+            promotional_text=promotional_text,
+            support_url=support_url,
+            whats_new=whats_new.value if isinstance(whats_new, Types.WhatsNewArgument) else whats_new,
+        )
+        return self._create_resource(
+            self.api_client.app_store_version_localizations,
+            should_print,
+            **{k: v for k, v in create_params.items() if v is not None},
+        )
+
+    @cli.action(
+        'modify',
+        AppStoreVersionLocalizationArgument.APP_STORE_VERSION_LOCALIZATION_ID,
+        AppStoreVersionLocalizationArgument.DESCRIPTION,
+        AppStoreVersionLocalizationArgument.KEYWORDS,
+        AppStoreVersionLocalizationArgument.MARKETING_URL,
+        AppStoreVersionLocalizationArgument.PROMOTIONAL_TEXT,
+        AppStoreVersionLocalizationArgument.SUPPORT_URL,
+        AppStoreVersionLocalizationArgument.WHATS_NEW,
+        action_group=AppStoreConnectActionGroup.APP_STORE_VERSION_LOCALIZATIONS,
+    )
+    def update_app_store_version_localization(
+        self,
+        app_store_version_localization_id: ResourceId,
+        description: Optional[str] = None,
+        keywords: Optional[str] = None,
+        marketing_url: Optional[str] = None,
+        promotional_text: Optional[str] = None,
+        support_url: Optional[str] = None,
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersionLocalization:
+        """
+        Modify an App Store Version Localization.
+        Edit localized version-level information for a particular language.
+        """
+        return self._modify_resource(
+            self.api_client.app_store_version_localizations,
+            app_store_version_localization_id,
+            should_print,
+            description=description,
+            keywords=keywords,
+            marketing_url=marketing_url,
+            promotional_text=promotional_text,
+            support_url=support_url,
+            whats_new=whats_new.value if isinstance(whats_new, Types.WhatsNewArgument) else whats_new,
+        )
+
+    @cli.action(
+        'delete',
+        AppStoreVersionLocalizationArgument.APP_STORE_VERSION_LOCALIZATION_ID,
+        CommonArgument.IGNORE_NOT_FOUND,
+        action_group=AppStoreConnectActionGroup.APP_STORE_VERSION_LOCALIZATIONS,
+    )
+    def delete_app_store_version_localization(
+        self,
+        app_store_version_localization_id: ResourceId,
+        ignore_not_found: bool = False,
+    ) -> None:
+        """
+        Delete an App Store Version Localization.
+        Remove a language from your version metadata.
+        """
+        self._delete_resource(
+            self.api_client.app_store_version_localizations,
+            app_store_version_localization_id,
+            ignore_not_found,
+        )
diff --git a/src/codemagic/tools/_app_store_connect/action_groups/app_store_versions_action_group.py b/src/codemagic/tools/_app_store_connect/action_groups/app_store_versions_action_group.py
index cbeaee0b..3075e486 100644
--- a/src/codemagic/tools/_app_store_connect/action_groups/app_store_versions_action_group.py
+++ b/src/codemagic/tools/_app_store_connect/action_groups/app_store_versions_action_group.py
@@ -2,6 +2,7 @@
 
 from abc import ABCMeta
 from datetime import datetime
+from typing import List
 from typing import Optional
 from typing import Union
 
@@ -9,6 +10,7 @@
 from codemagic.apple import AppStoreConnectApiError
 from codemagic.apple.resources import App
 from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
 from codemagic.apple.resources import Build
 from codemagic.apple.resources import Platform
 from codemagic.apple.resources import ReleaseType
@@ -36,14 +38,14 @@ class AppStoreVersionsActionGroup(AbstractBaseAction, metaclass=ABCMeta):
         action_group=AppStoreConnectActionGroup.APP_STORE_VERSIONS,
     )
     def create_app_store_version(
-            self,
-            build_id: ResourceId,
-            platform: Platform = CommonArgument.PLATFORM.get_default(),
-            copyright: Optional[str] = None,
-            version_string: Optional[str] = None,
-            release_type: Optional[ReleaseType] = None,
-            earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
-            should_print: bool = True,
+        self,
+        build_id: ResourceId,
+        platform: Platform = CommonArgument.PLATFORM.get_default(),
+        copyright: Optional[str] = None,
+        version_string: Optional[str] = None,
+        release_type: Optional[ReleaseType] = None,
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
+        should_print: bool = True,
     ) -> AppStoreVersion:
         """
         Add a new App Store version to an app using specified build.
@@ -82,14 +84,15 @@ def create_app_store_version(
         action_group=AppStoreConnectActionGroup.APP_STORE_VERSIONS,
     )
     def update_app_store_version(
-            self,
-            app_store_version_id: ResourceId,
-            build_id: Optional[ResourceId] = None,
-            copyright: Optional[str] = None,
-            earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
-            release_type: Optional[ReleaseType] = None,
-            version_string: Optional[str] = None,
-            should_print: bool = True) -> AppStoreVersion:
+        self,
+        app_store_version_id: ResourceId,
+        build_id: Optional[ResourceId] = None,
+        copyright: Optional[str] = None,
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
+        release_type: Optional[ReleaseType] = None,
+        version_string: Optional[str] = None,
+        should_print: bool = True,
+    ) -> AppStoreVersion:
         """
         Update the app store version for a specific app.
         """
@@ -112,9 +115,11 @@ def update_app_store_version(
         CommonArgument.IGNORE_NOT_FOUND,
         action_group=AppStoreConnectActionGroup.APP_STORE_VERSIONS,
     )
-    def delete_app_store_version(self,
-                                 app_store_version_id: ResourceId,
-                                 ignore_not_found: bool = False) -> None:
+    def delete_app_store_version(
+        self,
+        app_store_version_id: ResourceId,
+        ignore_not_found: bool = False,
+    ) -> None:
         """
         Delete specified App Store version from Apple Developer portal
         """
@@ -138,3 +143,26 @@ def _get_build_version(self, version_string: Optional[str], build: Build) -> str
                 'Build version is not specified and build does not have prerelease version to check the version from')
 
         return pre_release_version.attributes.version
+
+    @cli.action(
+        'localizations',
+        AppStoreVersionArgument.APP_STORE_VERSION_ID,
+        action_group=AppStoreConnectActionGroup.APP_STORE_VERSIONS,
+    )
+    def list_app_store_version_localizations(
+        self,
+        app_store_version_id: ResourceId,
+        should_print: bool = True,
+    ) -> List[AppStoreVersionLocalization]:
+        """
+        List All App Store Version Localizations for an App Store Version.
+        Get a list of localized, version-level information about an app, for all locales.
+        """
+        return self._list_related_resources(
+            app_store_version_id,
+            AppStoreVersion,
+            AppStoreVersionLocalization,
+            self.api_client.app_store_versions.list_app_store_version_localizations,
+            None,
+            should_print,
+        )
diff --git a/src/codemagic/tools/_app_store_connect/action_groups/beta_build_localizations_action_group.py b/src/codemagic/tools/_app_store_connect/action_groups/beta_build_localizations_action_group.py
index 842636f3..b085e765 100644
--- a/src/codemagic/tools/_app_store_connect/action_groups/beta_build_localizations_action_group.py
+++ b/src/codemagic/tools/_app_store_connect/action_groups/beta_build_localizations_action_group.py
@@ -66,7 +66,7 @@ def create_beta_build_localization(
         """
         if locale is None:
             app = self.api_client.builds.read_app(build_id)
-            locale = Locale(app.attributes.primaryLocale)
+            locale = app.attributes.primaryLocale
             msg_template = 'Using application %s primary locale %s for beta build localization'
             self.logger.info(msg_template, app.attributes.name, locale.value)
 
diff --git a/src/codemagic/tools/_app_store_connect/action_groups/builds_action_group.py b/src/codemagic/tools/_app_store_connect/action_groups/builds_action_group.py
index f289af7c..df3d1e94 100644
--- a/src/codemagic/tools/_app_store_connect/action_groups/builds_action_group.py
+++ b/src/codemagic/tools/_app_store_connect/action_groups/builds_action_group.py
@@ -15,6 +15,7 @@
 from codemagic.apple.resources import App
 from codemagic.apple.resources import AppStoreState
 from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
 from codemagic.apple.resources import AppStoreVersionSubmission
 from codemagic.apple.resources import BetaAppLocalization
 from codemagic.apple.resources import BetaAppReviewSubmission
@@ -30,6 +31,8 @@
 from ..abstract_base_action import AbstractBaseAction
 from ..action_group import AppStoreConnectActionGroup
 from ..arguments import AppStoreVersionArgument
+from ..arguments import AppStoreVersionInfo
+from ..arguments import AppStoreVersionLocalizationInfo
 from ..arguments import ArgumentGroups
 from ..arguments import BetaBuildInfo
 from ..arguments import BuildArgument
@@ -37,6 +40,15 @@
 from ..arguments import Types
 from ..errors import AppStoreConnectError
 
+AppStoreVersionLocalizationInfos = Union[
+    List[AppStoreVersionLocalizationInfo],
+    Types.AppStoreVersionLocalizationInfoArgument,
+]
+BetaBuildLocalizationsInfo = Union[
+    List[BetaBuildInfo],
+    Types.BetaBuildLocalizations,
+]
+
 
 class BuildsActionGroup(AbstractBaseAction, metaclass=ABCMeta):
 
@@ -98,7 +110,7 @@ def get_build_app_store_version(
     def add_beta_test_info(
             self,
             build_id: ResourceId,
-            beta_build_localizations: Optional[Union[List[BetaBuildInfo], Types.BetaBuildLocalizations]] = None,
+            beta_build_localizations: Optional[BetaBuildLocalizationsInfo] = None,
             locale: Optional[Locale] = None,
             whats_new: Optional[Types.WhatsNewArgument] = None):
         """
@@ -158,21 +170,59 @@ def submit_to_testflight(
     def submit_to_app_store(
             self,
             build_id: ResourceId,
+            max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
+            # App Store Version information arguments
             copyright: Optional[str] = None,
             earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]] = None,
-            max_build_processing_wait: Optional[Union[int, Types.MaxBuildProcessingWait]] = None,
             platform: Platform = AppStoreVersionArgument.PLATFORM.get_default(),
             release_type: Optional[ReleaseType] = None,
             version_string: Optional[str] = None,
+            app_store_version_info: Optional[Union[AppStoreVersionInfo, Types.AppStoreVersionInfoArgument]] = None,
+            # App Store Version Localization arguments
+            description: Optional[str] = None,
+            keywords: Optional[str] = None,
+            locale: Optional[Locale] = None,
+            marketing_url: Optional[str] = None,
+            promotional_text: Optional[str] = None,
+            support_url: Optional[str] = None,
+            whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+            app_store_version_localizations: Optional[AppStoreVersionLocalizationInfos] = None,
     ) -> AppStoreVersionSubmission:
         """
         Submit build to App Store review
         """
+        app_store_version_info = self._get_app_store_version_info(
+            app_store_version_info,
+            copyright,
+            earliest_release_date,
+            platform,
+            release_type,
+            version_string,
+        )
+        app_store_version_localization_infos = self._get_app_store_version_localization_infos(
+            app_store_version_localizations,
+            description,
+            keywords,
+            locale,
+            marketing_url,
+            promotional_text,
+            support_url,
+            whats_new,
+        )
+        return self._submit_to_app_store(
+            build_id,
+            Types.MaxBuildProcessingWait.resolve_value(max_build_processing_wait),
+            app_store_version_info,
+            app_store_version_localization_infos,
+        )
 
-        max_processing_minutes = Types.MaxBuildProcessingWait.resolve_value(max_build_processing_wait)
-        if isinstance(earliest_release_date, Types.EarliestReleaseDate):
-            earliest_release_date = earliest_release_date.value
-
+    def _submit_to_app_store(
+        self,
+        build_id: ResourceId,
+        max_processing_minutes: int,
+        app_store_version_info: AppStoreVersionInfo,
+        app_store_version_localization_infos: List[AppStoreVersionLocalizationInfo],
+    ) -> AppStoreVersionSubmission:
         self.logger.info(Colors.BLUE(f'\nSubmit build {build_id!r} to App Store review'))
 
         try:
@@ -183,27 +233,27 @@ def submit_to_app_store(
         if max_processing_minutes:
             build = self.wait_until_build_is_processed(build, max_processing_minutes)
 
-        if version_string is None:
+        if app_store_version_info.version_string is None:
             self.logger.info("\nVersion string is not specified. Obtain it from build's pre-release version...")
             pre_release_version = self.get_build_pre_release_version(build_id, should_print=False)
-            version_string = pre_release_version.attributes.version
+            app_store_version_info.version_string = pre_release_version.attributes.version
+
+        self.logger.info(
+            Colors.BLUE(f'\nUsing version {app_store_version_info.version_string} for App Store submission'),
+        )
 
-        self.logger.info(Colors.BLUE(f'\nUsing version {version_string} for App Store submission'))
+        app_store_version = self._ensure_app_store_version(app, build, app_store_version_info)
+        self.echo('')
 
-        app_store_version = self._ensure_app_store_version(
+        self._create_or_update_app_store_version_localizations(
             app,
-            build,
-            platform,
-            copyright=copyright,
-            earliest_release_date=earliest_release_date,
-            release_type=release_type,
-            version_string=version_string,
+            app_store_version,
+            app_store_version_localization_infos,
         )
-        self.logger.info('')
 
         app_store_version_submission = self.create_app_store_version_submission(app_store_version.id)
 
-        platform_slug = platform.value.lower().replace('_', '')
+        platform_slug = app_store_version_info.platform.value.lower().replace('_', '')
         submission_url = f'https://appstoreconnect.apple.com/apps/{app.id}/appstore/{platform_slug}/version/inflight'
         self.logger.info(f'\nCheck App Store submission details from\n{submission_url}\n')
 
@@ -297,43 +347,81 @@ def _get_missing_beta_app_review_information(self, app: App) -> List[str]:
     def _get_app_default_beta_localization(self, app: App) -> Optional[BetaAppLocalization]:
         beta_app_localizations = self.api_client.apps.list_beta_app_localizations(app)
         for beta_app_localization in beta_app_localizations:
-            if beta_app_localization.attributes.locale.value == app.attributes.primaryLocale:
+            if beta_app_localization.attributes.locale is app.attributes.primaryLocale:
                 return beta_app_localization
         # If nothing matches, then just take the first
         return beta_app_localizations[0] if beta_app_localizations else None
 
     def _ensure_app_store_version(
-            self,
-            app: App,
-            build: Build,
-            platform: Platform,
-            **app_store_version_params,
+        self,
+        app: App,
+        build: Build,
+        app_store_version_info: AppStoreVersionInfo,
     ) -> AppStoreVersion:
-        app_store_version = self._get_editable_app_store_version(app, platform)
+        app_store_version = self._get_editable_app_store_version(app, app_store_version_info.platform)
         if app_store_version is None:
             # Version does not exist, create a new version for App Store review submission
             self.logger.info(f'\n{AppStoreVersion} does not exist for build {build.id}')
             app_store_version = self.create_app_store_version(
                 build.id,
-                platform=platform,
-                **app_store_version_params,
+                platform=app_store_version_info.platform,
+                copyright=app_store_version_info.copyright,
+                earliest_release_date=app_store_version_info.earliest_release_date,
+                release_type=app_store_version_info.release_type,
+                version_string=app_store_version_info.version_string,
             )
         else:
-            self._update_existing_app_store_version(
-                app_store_version,
-                build,
-                **app_store_version_params,
-            )
+            self._update_existing_app_store_version(app_store_version, build, app_store_version_info)
         return app_store_version
 
+    def _create_or_update_app_store_version_localizations(
+        self,
+        app: App,
+        app_store_version: AppStoreVersion,
+        app_store_version_localizations: List[AppStoreVersionLocalizationInfo],
+    ):
+        is_first_app_store_version = self._is_first_app_store_version(app, app_store_version.attributes.platform)
+        existing_localizations = self._get_existing_app_store_version_localizations(app_store_version)
+        for localization in app_store_version_localizations:
+            if localization.locale is None:  # Use primary locale
+                localization.locale = app.attributes.primaryLocale
+
+            if is_first_app_store_version:  # Release notes are not allowed for first releases
+                localization.whats_new = None
+
+            try:
+                existing_localization_id = existing_localizations[localization.locale]
+            except KeyError:
+                self.echo(Colors.GREEN(f'Create new {AppStoreVersionLocalization} for locale {localization.locale}'))
+                app_store_version_localization = self.api_client.app_store_version_localizations.create(
+                    app_store_version,
+                    localization.locale,
+                    description=localization.description,
+                    keywords=localization.keywords,
+                    marketing_url=localization.marketing_url,
+                    promotional_text=localization.promotional_text,
+                    support_url=localization.support_url,
+                    whats_new=localization.whats_new,
+                )
+            else:
+                self.echo(Colors.GREEN(f'Update {AppStoreVersionLocalization} for locale {localization.locale}'))
+                app_store_version_localization = self.api_client.app_store_version_localizations.modify(
+                    existing_localization_id,
+                    description=localization.description,
+                    keywords=localization.keywords,
+                    marketing_url=localization.marketing_url,
+                    promotional_text=localization.promotional_text,
+                    support_url=localization.support_url,
+                    whats_new=localization.whats_new,
+                )
+            self.printer.print_resource(app_store_version_localization, True)
+            self.echo('')
+
     def _update_existing_app_store_version(
         self,
         app_store_version: AppStoreVersion,
         build: Build,
-        copyright: Optional[str] = None,
-        earliest_release_date: Optional[datetime] = None,
-        release_type: Optional[ReleaseType] = None,
-        version_string: Optional[str] = None,
+        app_store_version_info: AppStoreVersionInfo,
     ):
         self.logger.info((
             f'\nFound existing {AppStoreVersion} {app_store_version.id} '
@@ -341,14 +429,14 @@ def _update_existing_app_store_version(
         ))
 
         updates: Dict[str, str] = {'build': build.id}
-        if copyright:
-            updates['copyright'] = copyright
-        if earliest_release_date:
-            updates['earliest release date'] = AppStoreVersion.to_iso_8601(earliest_release_date)
-        if release_type:
-            updates['release type'] = release_type.value.lower()
-        if version_string:
-            updates['version string'] = version_string
+        if app_store_version_info.copyright:
+            updates['copyright'] = app_store_version_info.copyright
+        if app_store_version_info.earliest_release_date:
+            updates['earliest release date'] = AppStoreVersion.to_iso_8601(app_store_version_info.earliest_release_date)
+        if app_store_version_info.release_type:
+            updates['release type'] = app_store_version_info.release_type.value.lower()
+        if app_store_version_info.version_string:
+            updates['version string'] = app_store_version_info.version_string
 
         update_message = ', '.join(
             f'{param}: {shlex.quote(value)}'
@@ -359,12 +447,31 @@ def _update_existing_app_store_version(
         return self.update_app_store_version(
             app_store_version.id,
             build_id=build.id,
-            copyright=copyright,
-            earliest_release_date=earliest_release_date,
-            release_type=release_type,
-            version_string=version_string,
+            copyright=app_store_version_info.copyright,
+            earliest_release_date=app_store_version_info.earliest_release_date,
+            release_type=app_store_version_info.release_type,
+            version_string=app_store_version_info.version_string,
         )
 
+    def _is_first_app_store_version(self, app: App, platform: Platform) -> bool:
+        versions_filter = self.api_client.app_store_versions.Filter(platform=platform)
+        app_store_versions = self.api_client.apps.list_app_store_versions(
+            app,
+            resource_filter=versions_filter,
+            limit=2,
+        )
+        return len(app_store_versions) < 2
+
+    def _get_existing_app_store_version_localizations(
+        self,
+        app_store_version: AppStoreVersion,
+    ) -> Dict[Locale, ResourceId]:
+        localizations = self.api_client.app_store_versions.list_app_store_version_localizations(app_store_version)
+        return {
+            localization.attributes.locale: localization.id
+            for localization in localizations
+        }
+
     def _get_editable_app_store_version(self, app: App, platform: Platform) -> Optional[AppStoreVersion]:
         versions_filter = self.api_client.app_store_versions.Filter(
             app_store_state=AppStoreState.editable_states(),
@@ -373,3 +480,69 @@ def _get_editable_app_store_version(self, app: App, platform: Platform) -> Optio
         app_store_versions = self.api_client.apps.list_app_store_versions(app, resource_filter=versions_filter)
         app_store_versions.sort(key=lambda asv: LooseVersion(asv.attributes.versionString))
         return app_store_versions[-1] if app_store_versions else None
+
+    @classmethod
+    def _get_app_store_version_info(
+        cls,
+        app_store_version_info_argument: Optional[Union[AppStoreVersionInfo, Types.AppStoreVersionInfoArgument]],
+        copyright: Optional[str],
+        earliest_release_date: Optional[Union[datetime, Types.EarliestReleaseDate]],
+        platform: Platform,
+        release_type: Optional[ReleaseType],
+        version_string: Optional[str],
+    ) -> AppStoreVersionInfo:
+        if app_store_version_info_argument is None:
+            app_store_version_info = AppStoreVersionInfo(platform=platform)
+        elif isinstance(app_store_version_info_argument, Types.AppStoreVersionInfoArgument):
+            app_store_version_info = app_store_version_info_argument.value
+        else:
+            app_store_version_info = app_store_version_info_argument
+
+        if platform is not AppStoreVersionArgument.PLATFORM.get_default():
+            # Platform has a default value when invoked from CLI,
+            # override it only in case non-default value was provided
+            app_store_version_info.platform = platform
+        if copyright:
+            app_store_version_info.copyright = copyright
+        if earliest_release_date:
+            if isinstance(earliest_release_date, Types.EarliestReleaseDate):
+                app_store_version_info.earliest_release_date = earliest_release_date.value
+            else:
+                app_store_version_info.earliest_release_date = earliest_release_date
+        if release_type:
+            app_store_version_info.release_type = release_type
+        if version_string:
+            app_store_version_info.version_string = version_string
+        return app_store_version_info
+
+    @classmethod
+    def _get_app_store_version_localization_infos(
+        cls,
+        app_store_version_localizations: Optional[AppStoreVersionLocalizationInfos],
+        description: Optional[str],
+        keywords: Optional[str],
+        locale: Optional[Locale],
+        marketing_url: Optional[str],
+        promotional_text: Optional[str],
+        support_url: Optional[str],
+        whats_new: Optional[Union[str, Types.WhatsNewArgument]] = None,
+    ) -> List[AppStoreVersionLocalizationInfo]:
+        if isinstance(app_store_version_localizations, Types.AppStoreVersionLocalizationInfoArgument):
+            app_store_version_localization_infos = app_store_version_localizations.value
+        else:
+            app_store_version_localization_infos = app_store_version_localizations or []
+
+        app_store_version_localization_info = AppStoreVersionLocalizationInfo(
+            description=description,
+            keywords=keywords,
+            locale=locale,
+            marketing_url=marketing_url,
+            promotional_text=promotional_text,
+            support_url=support_url,
+            whats_new=whats_new.value if isinstance(whats_new, Types.WhatsNewArgument) else whats_new,
+        )
+        if set(app_store_version_localization_info.__dict__.values()) != {None}:
+            # At least some field is defined
+            app_store_version_localization_infos.append(app_store_version_localization_info)
+
+        return app_store_version_localization_infos
diff --git a/src/codemagic/tools/_app_store_connect/actions/publish_action.py b/src/codemagic/tools/_app_store_connect/actions/publish_action.py
index 4707eef6..2ee532ac 100644
--- a/src/codemagic/tools/_app_store_connect/actions/publish_action.py
+++ b/src/codemagic/tools/_app_store_connect/actions/publish_action.py
@@ -25,11 +25,20 @@
 from codemagic.tools._app_store_connect.arguments import AppStoreVersionArgument
 
 from ..abstract_base_action import AbstractBaseAction
+from ..arguments import AppStoreVersionInfo
+from ..arguments import AppStoreVersionLocalizationArgument
+from ..arguments import AppStoreVersionLocalizationInfo
 from ..arguments import ArgumentGroups
+from ..arguments import BuildArgument
 from ..arguments import PublishArgument
 from ..arguments import Types
 from ..errors import AppStoreConnectError
 
+AppStoreVersionLocalizationInfos = Union[
+    List[AppStoreVersionLocalizationInfo],
+    Types.AppStoreVersionLocalizationInfoArgument,
+]
+
 
 @dataclass
 class AddBetaTestInfoOptions:
@@ -51,11 +60,22 @@ class SubmitToTestFlightOptions:
 @dataclass
 class SubmitToAppStoreOptions:
     max_build_processing_wait: int
+    # App Store Version information arguments
     copyright: Optional[str] = None
     earliest_release_date: Optional[datetime] = None
     platform: Platform = AppStoreVersionArgument.PLATFORM.get_default()
     release_type: Optional[ReleaseType] = None
     version_string: Optional[str] = None
+    app_store_version_info: Optional[AppStoreVersionInfo] = None
+    # App Store Version Localization arguments
+    description: Optional[str] = None
+    keywords: Optional[str] = None
+    locale: Optional[Locale] = None
+    marketing_url: Optional[str] = None
+    promotional_text: Optional[str] = None
+    support_url: Optional[str] = None
+    whats_new: Optional[str] = None
+    app_store_version_localizations: Optional[List[AppStoreVersionLocalizationInfo]] = None
 
 
 ACTION_ARGUMENTS = (
@@ -67,10 +87,10 @@ class SubmitToAppStoreOptions:
     *PublishArgument.with_custom_argument_group(
         "add localized What's new (what to test) information to uploaded build",
         *ArgumentGroups.ADD_BETA_TEST_INFO_OPTIONAL_ARGUMENTS,
-    ),
-    *PublishArgument.with_custom_argument_group(
-        "add localized What's new (what to test) information to uploaded build",
-        *ArgumentGroups.ADD_BETA_TEST_INFO_OPTIONAL_ARGUMENTS,
+        exclude=(
+            BuildArgument.LOCALE_DEFAULT,
+            BuildArgument.WHATS_NEW,
+        ),
     ),
     *PublishArgument.with_custom_argument_group(
         'submit build to TestFlight for beta review',
@@ -86,7 +106,16 @@ class SubmitToAppStoreOptions:
         PublishArgument.SUBMIT_TO_APP_STORE,
         AppStoreVersionArgument.PLATFORM_OPTIONAL,
         *ArgumentGroups.SUBMIT_TO_APP_STORE_OPTIONAL_ARGUMENTS,
-        exclude=(AppStoreVersionArgument.PLATFORM,),
+        exclude=(
+            AppStoreVersionArgument.PLATFORM,
+            AppStoreVersionLocalizationArgument.LOCALE_DEFAULT,
+            AppStoreVersionLocalizationArgument.WHATS_NEW,
+        ),
+    ),
+    *PublishArgument.with_custom_argument_group(
+        'add localized meta information about build for TestFlight or App Store review submission',
+        PublishArgument.LOCALE_DEFAULT,
+        PublishArgument.WHATS_NEW,
     ),
     *PublishArgument.with_custom_argument_group(
         "set Apple's altool configuration options",
@@ -156,6 +185,14 @@ def _get_app_store_connect_submit_options(
             platform: Optional[Platform] = None,
             release_type: Optional[ReleaseType] = None,
             version_string: Optional[str] = None,
+            app_store_version_info: Optional[Union[AppStoreVersionInfo, Types.AppStoreVersionInfoArgument]] = None,
+            # App Store Version Localization arguments
+            description: Optional[str] = None,
+            keywords: Optional[str] = None,
+            marketing_url: Optional[str] = None,
+            promotional_text: Optional[str] = None,
+            support_url: Optional[str] = None,
+            app_store_version_localizations: Optional[AppStoreVersionLocalizationInfos] = None,
     ):
         submit_to_testflight_options = None
         submit_to_app_store_options = None
@@ -175,13 +212,28 @@ def _get_app_store_connect_submit_options(
         if submit_to_app_store:
             if isinstance(earliest_release_date, Types.EarliestReleaseDate):
                 earliest_release_date = earliest_release_date.value
+            if isinstance(app_store_version_info, Types.AppStoreVersionInfoArgument):
+                app_store_version_info = app_store_version_info.value
+            if isinstance(app_store_version_localizations, Types.AppStoreVersionLocalizationInfoArgument):
+                app_store_version_localizations = app_store_version_localizations.value
             submit_to_app_store_options = SubmitToAppStoreOptions(
                 max_build_processing_wait=Types.MaxBuildProcessingWait.resolve_value(max_build_processing_wait),
+                # Non localized app metadata
                 copyright=copyright,
                 earliest_release_date=earliest_release_date,
                 platform=platform,
                 release_type=release_type,
                 version_string=version_string,
+                app_store_version_info=app_store_version_info,
+                # Localized app metadata
+                description=description,
+                keywords=keywords,
+                locale=locale,
+                marketing_url=marketing_url,
+                promotional_text=promotional_text,
+                support_url=support_url,
+                whats_new=whats_new.value if isinstance(whats_new, Types.WhatsNewArgument) else whats_new,
+                app_store_version_localizations=app_store_version_localizations,
             )
         if submit_to_testflight and beta_group_names:
             # Only builds submitted to TestFlight can be added to beta groups
diff --git a/src/codemagic/tools/_app_store_connect/arguments.py b/src/codemagic/tools/_app_store_connect/arguments.py
index a9ba1a9e..0188d00d 100644
--- a/src/codemagic/tools/_app_store_connect/arguments.py
+++ b/src/codemagic/tools/_app_store_connect/arguments.py
@@ -4,6 +4,7 @@
 from argparse import ArgumentTypeError
 from collections import Counter
 from dataclasses import dataclass
+from dataclasses import fields
 from datetime import datetime
 from datetime import timezone
 from typing import List
@@ -35,6 +36,26 @@ class BetaBuildInfo:
     locale: Optional[Locale]
 
 
+@dataclass
+class AppStoreVersionInfo:
+    platform: Platform
+    copyright: Optional[str] = None
+    earliest_release_date: Optional[datetime] = None
+    release_type: Optional[ReleaseType] = None
+    version_string: Optional[str] = None
+
+
+@dataclass
+class AppStoreVersionLocalizationInfo:
+    description: Optional[str] = None
+    keywords: Optional[str] = None
+    locale: Optional[Locale] = None
+    marketing_url: Optional[str] = None
+    promotional_text: Optional[str] = None
+    support_url: Optional[str] = None
+    whats_new: Optional[str] = None
+
+
 class Types:
     class IssuerIdArgument(cli.EnvironmentArgumentValue[IssuerId]):
         argument_type = IssuerId
@@ -116,8 +137,7 @@ class EarliestReleaseDate(cli.TypedCliArgument[datetime]):
         argument_type = datetime
 
         @classmethod
-        def _apply_type(cls, non_typed_value: str) -> datetime:
-            value = cli.CommonArgumentTypes.iso_8601_datetime(non_typed_value)
+        def validate(cls, value: datetime):
             if value <= datetime.utcnow().replace(tzinfo=timezone.utc):
                 raise ArgumentTypeError(f'Provided value "{value}" is not valid, date cannot be in the past')
             elif (value.minute, value.second, value.microsecond) != (0, 0, 0):
@@ -126,8 +146,130 @@ def _apply_type(cls, non_typed_value: str) -> datetime:
                     f'only hour precision is allowed and '
                     f'minutes and seconds are not permitted'
                 ))
+
+        @classmethod
+        def _apply_type(cls, non_typed_value: str) -> datetime:
+            value = cli.CommonArgumentTypes.iso_8601_datetime(non_typed_value)
+            cls.validate(value)
             return value
 
+    class AppStoreVersionInfoArgument(cli.EnvironmentArgumentValue[AppStoreVersionInfo]):
+        argument_type = List[AppStoreVersionInfo]
+        environment_variable_key = 'APP_STORE_CONNECT_APP_STORE_VERSION_INFO'
+        example_value = json.dumps({
+            'platform': 'IOS',
+            'copyright': '2008 Acme Inc.',
+            'version_string': '1.0.8',
+            'release_type': 'SCHEDULED',
+            'earliest_release_date': '2021-11-10T14:00:00+00:00',
+        })
+
+        @classmethod
+        def _apply_type(cls, non_typed_value: str) -> AppStoreVersionInfo:
+            try:
+                given_app_store_version_info = json.loads(non_typed_value)
+                assert isinstance(given_app_store_version_info, dict)
+            except (ValueError, AssertionError):
+                raise ArgumentTypeError(f'Provided value {non_typed_value!r} is not a valid JSON encoded object')
+
+            allowed_fields = {field.name for field in fields(AppStoreVersionInfo)}
+            invalid_keys = given_app_store_version_info.keys() - allowed_fields
+            if invalid_keys:
+                keys = ', '.join(map(str, invalid_keys))
+                raise ArgumentTypeError(f'Unknown App Store version option(s) {keys}')
+
+            try:
+                platform = Platform(given_app_store_version_info['platform'])
+            except KeyError:
+                platform = AppStoreVersionArgument.PLATFORM.get_default()
+            except ValueError as ve:
+                raise ArgumentTypeError(f'Invalid App Store version info: {ve}')
+            app_store_version_info = AppStoreVersionInfo(platform=platform)
+
+            try:
+                given_earliest_release_date = given_app_store_version_info['given_app_store_version_info']
+                app_store_version_info.earliest_release_date = \
+                    cli.CommonArgumentTypes.iso_8601_datetime(given_earliest_release_date)
+                Types.EarliestReleaseDate.validate(app_store_version_info.earliest_release_date)
+            except KeyError:
+                pass
+            except ArgumentTypeError as ate:
+                raise ArgumentTypeError(f'Invalid "earliest_release_date" in App Store version info: {ate}') from ate
+
+            if 'release_type' in given_app_store_version_info:
+                try:
+                    app_store_version_info.release_type = ReleaseType(given_app_store_version_info['release_type'])
+                except ValueError as ve:
+                    raise ArgumentTypeError(f'Invalid App Store version info: {ve}')
+
+            if 'copyright' in given_app_store_version_info:
+                app_store_version_info.copyright = given_app_store_version_info['copyright']
+            if 'version_string' in given_app_store_version_info:
+                app_store_version_info.version_string = given_app_store_version_info['version_string']
+
+            return app_store_version_info
+
+    class AppStoreVersionLocalizationInfoArgument(cli.EnvironmentArgumentValue[List[AppStoreVersionLocalizationInfo]]):
+        argument_type = List[AppStoreVersionLocalizationInfo]
+        environment_variable_key = 'APP_STORE_CONNECT_APP_STORE_VERSION_LOCALIZATIONS'
+        example_value = json.dumps([{
+            'description': 'App description',
+            'keywords': 'keyword, other keyword',
+            'locale': 'en-US',
+            'marketing_url': 'https://example.com',
+            'promotional_text': 'Promotional text',
+            'support_url': 'https://example.com',
+            'whats_new': 'Fixes an issue ...',
+        }])
+
+        @classmethod
+        def _apply_type(cls, non_typed_value: str) -> List[AppStoreVersionLocalizationInfo]:
+            try:
+                given_localization_infos = json.loads(non_typed_value)
+                assert isinstance(given_localization_infos, list)
+            except (ValueError, AssertionError):
+                raise ArgumentTypeError(f'Provided value {non_typed_value!r} is not a valid JSON encoded list')
+
+            app_store_version_localization_infos: List[AppStoreVersionLocalizationInfo] = []
+            error_prefix = 'Invalid App Store Version localization'
+            for i, given_localization_info in enumerate(given_localization_infos):
+                try:
+                    locale: Optional[Locale] = Locale(given_localization_info['locale'])
+                except KeyError:
+                    locale = None
+                except ValueError as ve:  # Invalid locale
+                    raise ArgumentTypeError(f'{error_prefix} on index {i}, {ve} in {given_localization_info!r}')
+                except TypeError:  # Given beta build localization is not a dictionary
+                    raise ArgumentTypeError(f'{error_prefix} value {given_localization_info!r} on index {i}')
+
+                localization_info = AppStoreVersionLocalizationInfo(
+                    description=given_localization_info.get('description'),
+                    keywords=given_localization_info.get('keywords'),
+                    locale=locale,
+                    marketing_url=given_localization_info.get('marketing_url'),
+                    promotional_text=given_localization_info.get('promotional_text'),
+                    support_url=given_localization_info.get('support_url'),
+                    whats_new=given_localization_info.get('whats_new'),
+                )
+
+                if set(localization_info.__dict__.values()) == {None}:
+                    raise ArgumentTypeError(f'{error_prefix} value {given_localization_info!r} on index {i}')
+                app_store_version_localization_infos.append(localization_info)
+
+            locales = Counter(info.locale for info in app_store_version_localization_infos)
+            duplicate_locales = {
+                locale.value if locale else 'primary'
+                for locale, uses in locales.items()
+                if uses > 1
+            }
+            if duplicate_locales:
+                raise ArgumentTypeError((
+                    f'Ambiguous definitions for locale(s) {", ".join(duplicate_locales)}. '
+                    'Please define App Store Version localization for each locale exactly once.'
+                ))
+
+            return app_store_version_localization_infos
+
     class BetaBuildLocalizations(cli.EnvironmentArgumentValue[List[BetaBuildInfo]]):
         argument_type = List[BetaBuildInfo]
         environment_variable_key = 'APP_STORE_CONNECT_BETA_BUILD_LOCALIZATIONS'
@@ -167,6 +309,8 @@ def _apply_type(cls, non_typed_value: str) -> List[BetaBuildInfo]:
 
 
 _API_DOCS_REFERENCE = f'Learn more at {AppStoreConnectApiClient.API_KEYS_DOCS_URL}.'
+_LOCALE_CODES_URL = \
+    'https://developer.apple.com/documentation/appstoreconnectapi/betabuildlocalizationcreaterequest/data/attributes'
 
 
 class AppArgument(cli.Argument):
@@ -281,6 +425,23 @@ class AppStoreVersionArgument(cli.Argument):
         description='UUID value of the App Store Version',
         argparse_kwargs={'required': False},
     )
+    APP_STORE_VERSION_INFO = cli.ArgumentProperties(
+        key='app_store_version_info',
+        flags=('--app-store-version-info', '-vi'),
+        type=Types.AppStoreVersionInfoArgument,
+        description=(
+            'General App information and version release options for App Store version submission '
+            'as a JSON encoded object. Alternative to individually defining '
+            f'`{Colors.BRIGHT_BLUE("--platform")}`, `{Colors.BRIGHT_BLUE("--copyright")}`, '
+            f'`{Colors.BRIGHT_BLUE("--earliest-release-date")}`, `{Colors.BRIGHT_BLUE("--release-type")}` '
+            f'and `{Colors.BRIGHT_BLUE("--version-string")}`. '
+            f'For example, "{Colors.WHITE(Types.AppStoreVersionInfoArgument.example_value)}". '
+            'Definitions from the JSON will be overridden by dedicated CLI options if provided.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
     APP_STORE_VERSION_SUBMISSION_ID = cli.ArgumentProperties(
         key='app_store_version_submission_id',
         type=ResourceId,
@@ -291,7 +452,7 @@ class AppStoreVersionArgument(cli.Argument):
         flags=('--copyright',),
         description=(
             'The name of the person or entity that owns the exclusive rights to your app, '
-            'preceded by the year the rights were obtained (for example, "2008 Acme Inc."). '
+            f'preceded by the year the rights were obtained (for example, `{Colors.WHITE("2008 Acme Inc.")}`). '
             'Do not provide a URL.'
         ),
         argparse_kwargs={'required': False},
@@ -304,7 +465,7 @@ class AppStoreVersionArgument(cli.Argument):
             f'Specify earliest return date for scheduled release type '
             f'(see `{Colors.BRIGHT_BLUE("--release-type")}` configuration option). '
             f'Timezone aware ISO8601 timestamp with hour precision, '
-            f'for example `2021-11-10T14:00:00+00:00`.'
+            f'for example "{Colors.WHITE("2021-11-10T14:00:00+00:00")}".'
         ),
         argparse_kwargs={'required': False},
     )
@@ -345,12 +506,125 @@ class AppStoreVersionArgument(cli.Argument):
             'that identifies an iteration of the bundle. '
             'The string can only contain one to three groups of numeric characters (0-9) '
             'separated by period in the format [Major].[Minor].[Patch]. '
-            'For example `3.2.46`'
+            f'For example `{Colors.WHITE("3.2.46")}`'
         ),
         argparse_kwargs={'required': False},
     )
 
 
+class AppStoreVersionLocalizationArgument(cli.Argument):
+    APP_STORE_VERSION_LOCALIZATION_ID = cli.ArgumentProperties(
+        key='app_store_version_localization_id',
+        type=ResourceId,
+        description='UUID value of the App Store Version localization',
+    )
+    LOCALE = cli.ArgumentProperties(
+        key='locale',
+        type=Locale,
+        description=(
+            'The locale code name for App Store metadata in different languages. '
+            f'See available locale code names from {_LOCALE_CODES_URL}'
+        ),
+        argparse_kwargs={
+            'choices': list(Locale),
+        },
+    )
+    LOCALE_DEFAULT = LOCALE.duplicate(
+        flags=('--locale', '-l'),
+        description=(
+            'The locale code name for App Store metadata in different languages. '
+            "In case not provided, application's primary locale is used instead. "
+            f'Learn more from {_LOCALE_CODES_URL}'
+        ),
+        argparse_kwargs={
+            'required': False,
+            'choices': list(Locale),
+        },
+    )
+    DESCRIPTION = cli.ArgumentProperties(
+        key='description',
+        flags=('--description', '-d'),
+        description='A description of your app, detailing features and functionality.',
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    KEYWORDS = cli.ArgumentProperties(
+        key='keywords',
+        flags=('--keywords', '-k'),
+        description=(
+            'Include one or more keywords that describe your app. Keywords make '
+            'App Store search results more accurate. Separate keywords with an '
+            'English comma, Chinese comma, or a mix of both.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    MARKETING_URL = cli.ArgumentProperties(
+        key='marketing_url',
+        flags=('--marketing-url',),
+        description=(
+            'A URL with marketing information about your app. '
+            'This URL will be visible on the App Store.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    PROMOTIONAL_TEXT = cli.ArgumentProperties(
+        key='promotional_text',
+        flags=('--promotional-text',),
+        description=(
+            'Promotional text lets you inform your App Store visitors of any current '
+            'app features without requiring an updated submission. This text will '
+            'appear above your description on the App Store for customers with devices '
+            'running iOS 11 or later, and macOS 10.13 or later.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    SUPPORT_URL = cli.ArgumentProperties(
+        key='support_url',
+        flags=('--support-url',),
+        description=(
+            'A URL with support information for your app. '
+            'This URL will be visible on the App Store.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    WHATS_NEW = cli.ArgumentProperties(
+        key='whats_new',
+        flags=('--whats-new', '-n'),
+        type=Types.WhatsNewArgument,
+        description=(
+            "Describe what's new in this version of your app, "
+            'such as new features, improvements, and bug fixes.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+    APP_STORE_VERSION_LOCALIZATION_INFOS = cli.ArgumentProperties(
+        key='app_store_version_localizations',
+        flags=('--app-store-version-localizations', '-vl'),
+        type=Types.AppStoreVersionLocalizationInfoArgument,
+        description=(
+            'Localized App Store version meta information for App Store version submission '
+            'as a JSON encoded list. Alternative to individually defining version release notes '
+            f'and other options via dedicated CLI options such as `{Colors.BRIGHT_BLUE("--whats-new")}`. '
+            'Definitions for duplicate locales are not allowed. '
+            f'For example, "{Colors.WHITE(Types.AppStoreVersionLocalizationInfoArgument.example_value)}"'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
+
+
 class PublishArgument(cli.Argument):
     APPLICATION_PACKAGE_PATH_PATTERNS = cli.ArgumentProperties(
         key='application_package_path_patterns',
@@ -438,6 +712,34 @@ class PublishArgument(cli.Argument):
             'action': 'store_true',
         },
     )
+    LOCALE_DEFAULT = cli.ArgumentProperties(
+        key='locale',
+        flags=('--locale', '-l'),
+        type=Locale,
+        description=(
+            'The locale code name for App Store metadata in different languages, '
+            'or for displaying localized "What\'s new" content in TestFlight. '
+            "In case not provided, application's primary locale is used instead. "
+            f'Learn more from {_LOCALE_CODES_URL}'
+        ),
+        argparse_kwargs={
+            'required': False,
+            'choices': list(Locale),
+        },
+    )
+    WHATS_NEW = cli.ArgumentProperties(
+        key='whats_new',
+        flags=('--whats-new', '-n'),
+        type=Types.WhatsNewArgument,
+        description=(
+            'Release notes either for TestFlight or App Store review submission. '
+            "Describe what's new in this version of your app, "
+            'such as new features, improvements, and bug fixes.'
+        ),
+        argparse_kwargs={
+            'required': False,
+        },
+    )
     MAX_BUILD_PROCESSING_WAIT = cli.ArgumentProperties(
         key='max_build_processing_wait',
         flags=('--max-build-processing-wait', '-w'),
@@ -576,8 +878,7 @@ class BuildArgument(cli.Argument):
         type=Locale,
         description=(
             'The locale code name for displaying localized "What\'s new" content in TestFlight. '
-            'Learn more from https://developer.apple.com/documentation/appstoreconnectapi/'
-            'betabuildlocalizationcreaterequest/data/attributes'
+            f'Learn more from {_LOCALE_CODES_URL}'
         ),
         argparse_kwargs={
             'required': False,
@@ -588,8 +889,7 @@ class BuildArgument(cli.Argument):
         description=(
             'The locale code name for displaying localized "What\'s new" content in TestFlight. '
             "In case not provided, application's primary locale from test information is used instead. "
-            'Learn more from https://developer.apple.com/documentation/appstoreconnectapi/'
-            'betabuildlocalizationcreaterequest/data/attributes'
+            f'Learn more from {_LOCALE_CODES_URL}'
         ),
     )
     WHATS_NEW = cli.ArgumentProperties(
@@ -945,12 +1245,23 @@ class ArgumentGroups:
         PublishArgument.SKIP_PACKAGE_UPLOAD,
     )
     SUBMIT_TO_APP_STORE_OPTIONAL_ARGUMENTS = (
+        PublishArgument.MAX_BUILD_PROCESSING_WAIT,
+        # Generic App Store Version information arguments
+        AppStoreVersionArgument.APP_STORE_VERSION_INFO,
         AppStoreVersionArgument.COPYRIGHT,
         AppStoreVersionArgument.EARLIEST_RELEASE_DATE,
         AppStoreVersionArgument.PLATFORM,
         AppStoreVersionArgument.RELEASE_TYPE,
         AppStoreVersionArgument.VERSION_STRING,
-        PublishArgument.MAX_BUILD_PROCESSING_WAIT,
+        # Localized App Store Version arguments
+        AppStoreVersionLocalizationArgument.DESCRIPTION,
+        AppStoreVersionLocalizationArgument.KEYWORDS,
+        AppStoreVersionLocalizationArgument.LOCALE_DEFAULT,
+        AppStoreVersionLocalizationArgument.MARKETING_URL,
+        AppStoreVersionLocalizationArgument.PROMOTIONAL_TEXT,
+        AppStoreVersionLocalizationArgument.SUPPORT_URL,
+        AppStoreVersionLocalizationArgument.WHATS_NEW,
+        AppStoreVersionLocalizationArgument.APP_STORE_VERSION_LOCALIZATION_INFOS,
     )
     SUBMIT_TO_TESTFLIGHT_OPTIONAL_ARGUMENTS = (
         PublishArgument.MAX_BUILD_PROCESSING_WAIT,
diff --git a/src/codemagic/tools/app_store_connect.py b/src/codemagic/tools/app_store_connect.py
index fbf0a8aa..cc02b652 100755
--- a/src/codemagic/tools/app_store_connect.py
+++ b/src/codemagic/tools/app_store_connect.py
@@ -41,6 +41,7 @@
 from codemagic.models import ProvisioningProfile
 
 from ._app_store_connect.action_groups import AppsActionGroup
+from ._app_store_connect.action_groups import AppStoreVersionLocalizationsActionGroup
 from ._app_store_connect.action_groups import AppStoreVersionsActionGroup
 from ._app_store_connect.action_groups import AppStoreVersionSubmissionsActionGroup
 from ._app_store_connect.action_groups import BetaAppReviewSubmissionsActionGroup
@@ -51,6 +52,8 @@
 from ._app_store_connect.arguments import AppArgument
 from ._app_store_connect.arguments import AppStoreConnectArgument
 from ._app_store_connect.arguments import AppStoreVersionArgument
+from ._app_store_connect.arguments import AppStoreVersionInfo  # noqa: F401
+from ._app_store_connect.arguments import AppStoreVersionLocalizationInfo  # noqa: F401
 from ._app_store_connect.arguments import ArgumentGroups
 from ._app_store_connect.arguments import BetaBuildInfo  # noqa: F401
 from ._app_store_connect.arguments import BuildArgument
@@ -79,17 +82,20 @@ def _get_certificate_key(
 
 
 @cli.common_arguments(*AppStoreConnectArgument)
-class AppStoreConnect(cli.CliApp,
-                      AppStoreVersionSubmissionsActionGroup,
-                      AppStoreVersionsActionGroup,
-                      AppsActionGroup,
-                      BetaAppReviewSubmissionsActionGroup,
-                      BetaBuildLocalizationsActionGroup,
-                      BetaGroupsActionGroup,
-                      BuildsActionGroup,
-                      PublishAction,
-                      ResourceManagerMixin,
-                      PathFinderMixin):
+class AppStoreConnect(
+    cli.CliApp,
+    AppStoreVersionSubmissionsActionGroup,
+    AppStoreVersionsActionGroup,
+    AppStoreVersionLocalizationsActionGroup,
+    AppsActionGroup,
+    BetaAppReviewSubmissionsActionGroup,
+    BetaBuildLocalizationsActionGroup,
+    BetaGroupsActionGroup,
+    BuildsActionGroup,
+    PublishAction,
+    ResourceManagerMixin,
+    PathFinderMixin,
+):
     """
     Interact with Apple services via App Store Connect API
     """


Test patch:
diff --git a/tests/apple/app_store_connect/versioning/test_app_store_version_localizations.py b/tests/apple/app_store_connect/versioning/test_app_store_version_localizations.py
new file mode 100644
index 00000000..712a4186
--- /dev/null
+++ b/tests/apple/app_store_connect/versioning/test_app_store_version_localizations.py
@@ -0,0 +1,18 @@
+import os
+
+import pytest
+
+from codemagic.apple.resources import AppStoreVersionLocalization
+from codemagic.apple.resources import ResourceId
+from tests.apple.app_store_connect.resource_manager_test_base import ResourceManagerTestsBase
+
+
+@pytest.mark.skipif(not os.environ.get('RUN_LIVE_API_TESTS'), reason='Live App Store Connect API access')
+class AppStoreVersionLocalizationsTest(ResourceManagerTestsBase):
+    def test_read(self):
+        app_store_localization_id = ResourceId('253cf0c8-8057-49b7-be16-3b1cc78837e5')
+        app_store_localization = self.api_client.app_store_version_localizations.read(
+            app_store_localization_id,
+        )
+        assert isinstance(app_store_localization, AppStoreVersionLocalization)
+        assert app_store_localization.id == app_store_localization_id
diff --git a/tests/apple/app_store_connect/versioning/test_app_store_versions.py b/tests/apple/app_store_connect/versioning/test_app_store_versions.py
index 8647b412..a980732c 100644
--- a/tests/apple/app_store_connect/versioning/test_app_store_versions.py
+++ b/tests/apple/app_store_connect/versioning/test_app_store_versions.py
@@ -3,6 +3,7 @@
 import pytest
 
 from codemagic.apple.resources import AppStoreVersion
+from codemagic.apple.resources import AppStoreVersionLocalization
 from codemagic.apple.resources import AppStoreVersionSubmission
 from codemagic.apple.resources import Build
 from codemagic.apple.resources import Platform
@@ -63,3 +64,11 @@ def test_read_build(self):
         build = self.api_client.app_store_versions.read_build(app_store_version_id)
         assert isinstance(build, Build)
         assert build.id == ResourceId('9d967d5e-4946-432f-a111-1fd94949820b')
+
+    def test_list_app_store_version_localizations(self):
+        app_store_version_id = ResourceId('409ebefb-ebd1-4f1a-903d-6ba16e013ebf')
+        app_store_version_localizations = \
+            self.api_client.app_store_versions.list_app_store_version_localizations(app_store_version_id)
+        for app_store_version_localization in app_store_version_localizations:
+            assert isinstance(app_store_version_localization, AppStoreVersionLocalization)
+            print(app_store_version_localization.json())
diff --git a/tests/tools/app_store_connect/test_from_cli_args.py b/tests/tools/app_store_connect/test_from_cli_args.py
index 7d54e121..b7e091e1 100644
--- a/tests/tools/app_store_connect/test_from_cli_args.py
+++ b/tests/tools/app_store_connect/test_from_cli_args.py
@@ -74,7 +74,11 @@ def test_invalid_private_key_from_file(namespace_kwargs):
         cli_args = argparse.Namespace(**{k: v for k, v in namespace_kwargs.items()})
         with pytest.raises(argparse.ArgumentError) as exception_info:
             AppStoreConnect.from_cli_args(cli_args)
-        assert str(exception_info.value) == f'argument --private-key: Provided value in file "{tf.name}" is not valid'
+
+        assert str(exception_info.value) == (
+            f'argument --private-key: Provided value in file "{tf.name}" is not valid. '
+            f'Provided value "not a valid private key" is not valid'
+        )
 
 
 def test_private_key_invalid_path(namespace_kwargs):
diff --git a/tests/tools/app_store_connect/test_publish_action.py b/tests/tools/app_store_connect/test_publish_action.py
index dc422c23..b925cd4f 100644
--- a/tests/tools/app_store_connect/test_publish_action.py
+++ b/tests/tools/app_store_connect/test_publish_action.py
@@ -175,12 +175,23 @@ def test_publish_action_app_store_submit(publishing_namespace_kwargs):
         mock_submit_to_testflight.assert_not_called()
         mock_submit_to_app_store.assert_called_with(
             build.id,
+            max_build_processing_wait=0,
+            # General App Store version info
             copyright=None,
             earliest_release_date=None,
-            max_build_processing_wait=0,
             platform=Platform.IOS,
             release_type=ReleaseType.AFTER_APPROVAL,
             version_string='1.2.3',
+            # Localized App Store version information
+            app_store_version_info=None,
+            app_store_version_localizations=None,
+            description=None,
+            keywords=None,
+            locale=None,
+            marketing_url=None,
+            promotional_text=None,
+            support_url=None,
+            whats_new=None,
         )
         mock_add_beta_test_info.assert_not_called()