ℹ️ 注意:您需要使用开发者控制台才能获取您的开发者凭证和应用ID。
应用提交API支持应用文件上传、元数据管理和应用提交。使用对API进行HTTP调用的代码,您可以将提交流程直接集成到CI/CD管道中以进行连续部署。
在使用API时,您应该熟悉以下两个概念:Edit和ETag。
Edits就像容器或会话,其中包含您要对应用进行的所有待定更改。从创建新的Edit开始更新您的应用。然后,您的所有更改(如新的APK上传、本地化产品信息更新和标志替换)都将应用于Edit。准备就绪后,可以提交Edit,其将提交更改以进行验证和发布。
ETags是唯一的标识符,API使用这些标识符来确保Edit中的并发更新不会彼此覆盖。因为属于RESTful,应用提交API具有终端节点可对各种资源进行GET,如APK、屏幕截图或预览视频。这些GET请求的响应标头包含一个ETag,这是一个唯一的值,用于标识处于最新状态的资源。
当提交影响这些资源的请求时,请确保在请求标头中加入该资源的ETag,以便服务器验证您是否在对给定资源的最新版本进行更改。所有PUT和DELETE请求(以及某些POST请求)需要您提供ETag进行验证。
第一次使用应用提交API时,需要设置一些内容来促进身份验证。对API的调用要求您纳入持有者身份验证令牌,并且您可以通过Login with Amazon (LWA)获得该令牌:
3. 单击创建新的安全配置文件。
4. 为您的新安全配置文件提供名称和描述。
5. 然后单击保存。
6. 您随即会看到新创建的安全配置文件的基本信息。然后单击Web设置选项卡。
7. 在“Web设置”页面,您会看到一个客户端ID和客户端密钥。复制它们并安全地存储。您将需要用这些值来请求LWA访问令牌。
8. 接下来,导航至应用与服务 > API访问。
9. 在应用提交API下,选择您刚才创建的现有安全配置文件。单击附加。
现在,您已启用要与此安全配置文件一起使用的应用提交API,可以请求您的LWA令牌。
10. 导航至Login with Amazon页面。
11. 首先选择安全配置文件。
12. 然后单击确认。
使用LWA时,每当您请求访问用户的个人数据时,都会向用户显示同意隐私声明。
13. 在下一个屏幕上,提供一个指向贵组织同意隐私声明的URL。
14. 然后单击保存。
这样就完成了LWA配置。
现在,您可以发送请求以获取LWA访问令牌,并使用安全配置文件的客户端ID和客户端密钥进行身份验证。示例curl请求如下所示:
$ curl \
--url https://api.amazon.com/auth/O2/token
--request POST \
--header 'Content-Type: application/json' \
--data '{"grant_type":"client_credentials","client_id":"SECURITY-PROFILE-CLIENT-ID","client_secret":"SECURITY-PROFILE-CLIENT-SECRET","scope":"appstore::apps:readwrite"}'
{"access_token":"Atc|MQEBIEfESLSMKydIgiJPi-fhYvSSyOPXzgNvvT7WaWoBxKVfyCzexE31mmhC5w6rI-uI7kuoIAf4hSxIK33HSXeyO570fEHeb4gere8t5bUShE3iZgjXOQa5nGlNXsf01ZvOjig8M0Zdjd5s2_q5-2xMq6nQEZdCR3MOQtcM1SqZdLmnmEiTEQ-PwTWTAXAovkbY4i5NAdp9hhpvDneh7zQuOjDqnWyBqxG-qjCcxtRFVEhx9TZRDhsCUbUUiDLCFKMqWz8","scope":"appstore::apps:readwrite","token_type":"bearer","expires_in":3600}
复制生成的access_token值,您将使用该值验证所有后续的应用提交API请求。您将通过添加如下所示的Authorization标头来使用持有者身份验证令牌:
Authorization: Bearer Atc|MQEBIEfESLSMKydIgiJPi-fhYvSSyOPXzgNvvT7WaWoBxKVfyCzexE31mmhC5w6rI-uI7kuoIAf4hSxIK33HSXeyO570fEHeb4gere8t5bUShE3iZgjXOQa5nGlNXsf01ZvOjig8M0Zdjd5s2_q5-2xMq6nQEZdCR3MOQtcM1SqZdLmnmEiTEQ-PwTWTAXAovkbY4i5NAdp9hhpvDneh7zQuOjDqnWyBqxG-qjCcxtRFVEhx9TZRDhsCUbUUiDLCFKMqWz8
注意:此令牌在3600秒(1小时)后过期。如果当前的access_token过期,您始终可以使用上述请求重新生成一个。
为方便起见,请以环境变量的形式将访问令牌存储在终端会话中。
$ export \
TOKEN="Atc|MQEBIEfESLSMKydIgiJPi-fhYvSSyOPXzgNvvT7WaWoBxKVfyCzexE31mmhC5w6rI-uI7kuoIAf4hSxIK33HSXeyO570fEHeb4gere8t5bUShE3iZgjXOQa5nGlNXsf01ZvOjig8M0Zdjd5s2_q5-2xMq6nQEZdCR3MOQtcM1SqZdLmnmEiTEQ-PwTWTAXAovkbY4i5NAdp9hhpvDneh7zQuOjDqnWyBqxG-qjCcxtRFVEhx9TZRDhsCUbUUiDLCFKMqWz8"
应用提交API的所有终端节点都以路径参数的形式包含应用ID。
1. 在开发者控制台上,导航至应用列表。
2. 在列表中找到自己的应用,并单击该应用。这样就会来到应用当前版本部分的第一步。
3. 滚动到页面底部,在其他信息下找到您的应用ID。
4. 复制该值。
API的基本URL为https://developer.amazon.com/api/appstore,API版本为v1。
所有请求终端节点URL的开头如下所示:
https://developer.amazon.com/api/appstore/{apiVersion}/applications/{appId}
因此,与我们的示例应用相关的请求将转到具有以下开头的URL:
https://developer.amazon.com/api/appstore/v1/applications/amzn1.devportal.mobileapp.a486d052fb504c08a80c221db7479ecb
5. 为方便起见,请以环境变量的形式将API根路径存储在终端会话中。
$ export API_ROOT_PATH="https://developer.amazon.com/api/appstore/v1/applications/amzn1.devportal.mobileapp.a486d052fb504c08a80c221db7479ecb"
发送测试请求以验证您的LWA令牌是否有效,以及API路径是否正确。我们将发送一个请求,以获取应用当前活动的Edit的详细信息。我们未预期会存在该项,但至少可以验证我们的API请求是否成功。
查看API参考以获取应用的活动Edit,我们的API请求将为:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits
{}
注意我们使用的是环境变量$TOKEN和$API_ROOT_PATH。在该流程中我们将全程使用这些环境变量。
API请求成功,响应中的{}表示我们的应用没有活动的Edit。
Request is not authorized”(请求未得到授权)
发送API请求时,您可能会收到以下响应:
{"message":"Request is not authorized."}
这可能表示您的LWA访问令牌无效或已过期。另外发送一个请求以获取LWA访问令牌。然后将TOKEN环境变量重新分配至新值。
“API Version not supported”(API版本不受支持)
如果收到HTTP响应代码400,以及errorMessage “API Version not supported”,请确保对API根路径的apiVersion部分使用的是v1。
“No app found with the entered inputs”(使用所输入的内容未找到应用)
如果收到HTTP响应代码404,以及errorMessage“No app found with the entered inputs”,请进行检查以确保已将应用ID正确添加到API根路径。
“Unable to fetch the request scope for uri”(无法获取uri的请求范围)
如果收到的响应消息“Unable to fetch the request scope for uri”,请检查请求URL的其余部分(在API_ROOT_PATH之后)是否到达API参考中列出的有效终端节点。此外,请确保您对该终端节点使用了正确的请求命令(例如GET, POST, PUT或DELETE)。
$ curl \
--request POST \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits
{"id":"amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56","status":"IN_PROGRESS"}
响应包含新创建的Edit的id。这时,如果我们重新发送请求以检索当前活动的Edit,会收到有关此新创建的Edit的信息。
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits
{"id":"amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56","status":"IN_PROGRESS"}
为方便起见,请以新环境变量的形式将Edit ID存储在终端会话中。
$ export \
EDIT_ID="amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56"
更新亚马逊应用通常涉及应用的APK文件管理。要列出应用的APK,请发送以下请求:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks
[{"versionCode":10000,"id":"M8NUQH070UH2I","name":"AAB1"}]
要检索有关特定APK的详细信息,请使用APK ID,与针对RESTful API约定所预期的一样:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/M8NUQH070UH2I
{"versionCode":10000,"id":"M8NUQH070UH2I","name":"AAB1"}
要上传APK以与您的Edit相关联,您的请求将如下所示:
$ curl \
--request POST \
--header "Authorization: Bearer $TOKEN" \
--header "Content-type: application/octet-stream" \
--header "fileName: app-release-02.apk" \
--data-binary @/absolute/path/to/app-release-02.apk \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/upload
{"versionCode":10001,"id":"M4UQXH84SMZ4","name":"APK1"}
响应显示新上传的APK的ID。
您也可以替换APK(使用PUT)或者删除APK(使用DELETE)。但是,这些方法需要您为APK资源添加ETag。在您对资源进行GET之后,将在响应标头获得ETag。例如,要获取刚上传的APK的ETag,请求和响应如下所示:
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/M4UQXH84SMZ4
HTTP/1.1 200 OK
Server: Server
Date: Mon, 06 Jan 2025 22:17:24 GMT
Content-Type: application/json
Content-Length: 55
Connection: keep-alive
x-amz-rid: H9SBRPW0R3WMK95ZVP62
x-amzn-RequestId: b3c3cd98-c5c5-4578-9efc-94e17d8d13df
ETag: 43d8a4205f9c59155cd7a104cc627d9b6694c3f2
Vary: Content-Type,Accept-Encoding,User-Agent
Strict-Transport-Security: max-age=47474747; includeSubDomains; preload
{"versionCode":10001,"id":"M4UQXH84SMZ4","name":"APK1"}
向curl调用添加--include,即会显示响应标头。标头对此APK资源显示的ETag为43d8a4205f9c59155cd7a104cc627d9b6694c3f2。要删除该APK,我们需要在If-match请求标头中加入该值:
$ curl \
--include \
--request DELETE \
--header "Authorization: Bearer $TOKEN" \
--header "If-Match: 43d8a4205f9c59155cd7a104cc627d9b6694c3f2" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/M4UQXH84SMZ4
HTTP/1.1 204 No Content
…
再次检索APK详细信息,即会显示已成功删除它:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/M4UQXH84SMZ4 | json_pp
{
"errors" : [
{
"errorCode" : "error_apk_not_found",
"errorMessage" : "No APK found with the given APK ID."
}
],
"httpCode" : 404,
"message" : "Not Found"
}
如果您的APK文件特别大,则可使用/large/upload终端节点。
每个应用提交都可以包含多种语言版本的产品信息详情。产品信息的形式如下:
{
"language": "string",
"title": "string",
"fullDescription": "string",
"shortDescription": "string",
"recentChanges": "string",
"featureBullets": [
"string"
],
"keywords": [
"string"
]
}
注意:keywords是字符串数组;其中的每个字符串必须是一个没有空格的单词。
您可在此处查看受支持的语言的列表。要查看应用的所有本地化的产品信息,请运行以下命令:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings | json_pp
{
"listings" : {
"en-US" : {
"featureBullets" : [
"Images of coffee"
],
"fullDescription" : "This is a store that sells digital assets for use in websites and other promotional materials.",
"keywords" : [
"digital",
"images",
"assets",
"Coffee"
],
"language" : "en-US",
"recentChanges" : null,
"shortDescription" : "This is a store that sells digital assets for use in websites and other promotional materials.",
"title" : "Digital Assets Store"
}
}
}
上述调用返回应用的所有本地化产品信息,该应用目前只有一个语言版本:en-US。将语言附加到GET终端节点,以检索特定产品信息的详情。
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US
HTTP/1.1 200 OK
…
ETag: 5c8149f2f9f3d9b818e89ec9b797648bd32d7cec
…
{"language":"en-US","title":"Digital Assets Store","fullDescription":"This is a store that sells digital assets for use in websites and other promotional materials.","shortDescription":"This is a store that sells digital assets for use in websites and other promotional materials.","recentChanges":null,"featureBullets":["Images of coffee"],"keywords":["digital","images","assets","Coffee"]}
请注意,我们添加了--include参数来显示响应标头,该标头中包含此本地化产品信息资源的ETag。
$ curl \
--include \
--request PUT \
--header "Authorization: Bearer $TOKEN" \
--header "If-Match: 5c8149f2f9f3d9b818e89ec9b797648bd32d7cec" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US \
--data '{"language":"en-US", "title":"DAS: Digital Assets Store", "fullDescription":"The Digital Assets Store sells images and logos for use in websites and other promotional materials.", "shortDescription":"Promotional/website images and logos for sale.", "recentChanges":"Updated title and descriptions, added keywords", "featureBullets":["Images of coffee"], "keywords":["digital","images","AI-generated","Coffee"]}'
HTTP/1.1 200 OK
…
ETag: 8d531dc2aa6ed59072055cfc83e86c419a7032a9
…
{"language":"en-US","title":"DAS: Digital Assets Store","fullDescription":"The Digital Assets Store sells images and logos for use in websites and other promotional materials.","shortDescription":"Promotional/website images and logos for sale.","recentChanges":"Updated title and descriptions, added keywords","featureBullets":["Images of coffee"],"keywords":["digital","images","Coffee","AI-generated"]}
如果您想为不存在的本地化添加新的产品信息,请首先对产品信息进行GET从响应标头中检索其ETag。响应的正文将为空,但您必须在后续的PUT请求中对空的产品信息使用ETag,以创建新的产品信息。
要删除现有的本地化产品信息,请使用ETag并发送DELETE请求。
每个亚马逊应用都有形式如下的基本详情:
{
"defaultLanguage": "string",
"contactWebsite": "string",
"contactEmail": "string",
"contactPhone": "string"
}
使用应用提交API,您可以通过以下请求对应用的详情进行GET。如果要使用PUT请求修改这些详情,则必须从响应标头中检索ETag。
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/details
…
ETag: 10963098c5cf18378c3d47058b5355d44dd5d050
…
{"defaultLanguage":"en-US","contactWebsite":null,"contactEmail":"amazon_app_developer@example.com","contactPhone":null}
之后,更新应用详情的请求应如下所示:
$ curl \
--include \
--request PUT \
--header "If-Match: 10963098c5cf18378c3d47058b5355d44dd5d050" \
--header "Content-type: application/json" \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/details \
--data '{"defaultLanguage":"en-US","contactWebsite":"https://developer.amazon.com","contactEmail":"appdevboss@example.com","contactPhone":"111-222-3333"}'
HTTP/1.1 200 OK
…
ETag: 0560792b04b84d0893379f79fc5464c03178ba77
…
{"defaultLanguage":"en-US","contactWebsite":"https://developer.amazon.com","contactEmail":"appdevboss@example.com","contactPhone":"111-222-3333"}
要查看为APK指定的不同目标设备,请发送以下请求,并确保APK ID位于请求路径中:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/apks/M8NUQH070UH2I/targeting \
| json_pp
{
"amazonDevices" : [
{
"id" : "amzn1.appstore.device.1S3STLD1YMVDD",
"name" : "Funai 4K - Fire TV F560 Series",
"reason" : {},
"status" : "NOT_TARGETING"
},
{
"id" : "amzn1.appstore.device.2NHA4WR6DZVME",
"name" : "Fire TV 2-Series",
"reason" : {},
"status" : "NOT_TARGETING"
},
{
"id" : "amzn1.appstore.device.D8MCACTJ5P8M",
"name" : "Fire HD 10 (2023)",
"reason" : {},
"status" : "TARGETING"
},
…
{
"id" : "amzn1.appstore.device.F5BFMITYX6KI",
"name" : "Galaxy S4",
"reason" : {
"details" : [
"android:minSdkVersion = '24'; device requires '21'"
],
"reason" : "The device is incompatible with manifest."
},
"status" : "DISABLED"
}
],
"otherAndroidDevices" : "TARGETING"
}
生成的JSON中的设备列表范围很广,每个设备的status指示指定的APK是否适用。要修改APK的设备目标选择信息,请从上述请求的响应标头中获取ETag,然后使用更新的JSON正文发送后续PUT请求。
您应用的每个本地化的产品信息也有相关的图像和视频。不同图像的终端节点以本地化产品信息路径开头,然后是imageType。
您可在此处查看可用的imageType值的列表。例如,要检索有关en-US产品信息的large-icons的信息,请发送以下请求:
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US/large-icons
HTTP/1.1 200 OK
…
ETag: 8d531dc2aa6ed59072055cfc83e86c419a7032a9
…
{"images":[{"id":"amzn1.dex.asset.69c2f76ae9604091a4dd2e10f8ec9a50"}]}
要删除现有图像,请发送DELETE请求,将图像资产ID附加到路径中。别忘了在请求标头中包含ETag。
$ curl \
--request DELETE \
--header "If-Match: 8d531dc2aa6ed59072055cfc83e86c419a7032a9" \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US/large-icons/amzn1.dex.asset.69c2f76ae9604091a4dd2e10f8ec9a50
API具有终端节点来删除特定imageType的所有图像或删除单个特定图像。
要上传新图像,请使用application/octet-stream内容发送POST请求。例如:
$ curl \
--request POST \
--header "Authorization: Bearer $TOKEN" \
--header "Content-type: application/octet-stream" \
--data-binary @/absolute/path/to/image-file.png \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US/large-icons/upload
{"image":{"id":"amzn1.dex.asset.5e90a58830e048a796aef9db6ebf6a02"}}
视频的工作原理类似,只是没有不同类型的视频。
要检索有关特定本地化产品信息的所有视频的信息,请发送以下GET请求:
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/listings/en-US/videos
HTTP/1.1 200 OK
…
ETag: ee763ba20a0fc41c263ad5d9547cab1f1b021015
…
{"videos":[]}
要上传视频,请向同一终端节点路径发送POST请求,其中将ETag包含在If-Match标头中。与图像类似,有一个终端节点可以删除产品信息的所有视频,或者根据特定视频的资产ID删除该特定视频。
提交Edit时,默认情况下,审阅和发布过程将立即开始。但是,要为Edit设置未来的发布日期,可使用/availability终端节点。要查看当前的发布日期设置,请发送以下请求:
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/availability
HTTP/1.1 200 OK
…
ETag: ee763ba20a0fc41c263ad5d9547cab1f1b021015
…
{"publishingDate":{"dateTime":null,"zoneId":null}}
要修改可用设置,可在PUT请求中使用来自上个请求的ETag:
$ curl \
--request PUT \
--header "If-Match: ee763ba20a0fc41c263ad5d9547cab1f1b021015" \
--header "Content-type: application/json" \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/availability \
--data '{"publishingDate":{"dateTime":"2025-03-01T12:00:00","zoneId":"US/Pacific"}}'
{"publishingDate":{"dateTime":"2025-03-01T12:00:00","zoneId":"US/Pacific"}}
在活动的Edit中进行所有必要的更新后,您就可以提交Edit。在发送POST请求以提交Edit之前,请检索当前Edit资源的ETag:
$ curl \
--include \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits
…
ETag: 437b8a79adec568ce90e5d3c275808a36fdb5869
…
{"id":"amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56","status":"IN_PROGRESS"}
使用ETag提交您的Edit:
$ curl \
--request POST \
--header "If-Match: 437b8a79adec568ce90e5d3c275808a36fdb5869" \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/$EDIT_ID/commit
{"id":"amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56"}
在提交Edit之后,验证状态是否已更改:
$ curl \
--request GET \
--header "Authorization: Bearer $TOKEN" \
--url $API_ROOT_PATH/edits/
{"id":"amzn1.devportal.apprelease.a81b826e3e3743ea8a7886ac77f52c56","status":"SUBMITTED"}
在开发者控制台中,您将看到您的应用现在有一个基于您提交的Edit的即将推出的版本。
很好!您已成功使用应用提交API,处理了通过API请求而非开发者控制台用户界面更新应用的所有步骤。
应用提交API让开发者更方便地简化应用提交流程。将您的代码集成到现有CI/CD管道中可以让您的应用提交流程实现自动化并保持一致性,从而不再需要手动干预。
有关更多信息,可访问以下资源: