Overview
This topic describes the best practices for managing miniapps in Superapp in the following scenarios:
Search for miniapps.
Display miniapps in recommended booths.
Add miniapps to favorites.
Obtain recently used miniapps.
Scenarios
Search for specific miniapps or fetch all miniapps on a client
Introduction
This section describes how to quickly search for specific miniapps or fetch all miniapps on a client.
Solution details
Application Open Platform provides ready-to-use API operations that used to search for miniapps on clients, and offers container API operations for miniapps. If you want to fetch all miniapps, you can directly call a specific API operation without the need to specify a keyword.

API reference
You can call an API operation to search for specific miniapps. For more information, see "Search for specific miniapps" in the SDK Open APIs section of this topic.
You can call an API operation to fetch the data of all miniapps. For more information, see "Fetch all miniapps" in the SDK Open APIs section of this topic.
Display miniapps in recommended booths
Introduction
This section describes how to use the fixed recommended booths for miniapps in Superapp to facilitate the inbound marketing of specific miniapps.
Solution details
In Superapp, the logic used to display the recommended booths for miniapps is automatically implemented. You can use the booth management service of Superapp to integrate the Application Open Platform API to find online apps.

API reference
You can call API operations in the booth management service to display miniapps in recommended booths. For more information, see "Query the miniapps on a client" and "Query the metadata of published miniapps" in the SuperApp Channel Management Open APIs section of this topic.
Add miniapps to favorites
Introduction
This section describes how to add miniapps to your favorites. This way, you can quickly start the miniapps.
Solution details
When you integrate containers, implement the service provider interfaces (SPIs) that are used to add miniapps to favorites.

API reference
You can call an API operation on a client to add a miniapp to favorites. For more information, see "Add a miniapp to favorites" in the SDK Open APIs section of this topic.
You can call an API operation on a server to query the metadata of miniapps. For more information, see "Query the metadata of published miniapps" in the SuperApp Channel Management Open APIs section of this topic.
Obtain recently used miniapps
Introduction
This section describes how to obtain the list of recently used miniapps.
Solution details
Integrate container miniapps to enable event SPIs.

API reference
You can call an API operation on a client to save a miniapp to recents. For more information, see "Save a miniapp to recents" in the SDK Open APIs section of this topic.
You can call an API operation on a server to query the metadata of miniapps. For more information, see "Query the metadata of published miniapps" in the SuperApp Channel Management Open APIs section of this topic.
Open APIs
SuperApp Channel Management Open APIs
The SuperApp Channel Management Open APIs are Channel-level backend service interfaces provided by the Application Open Platform, using the target APP's AccessKey and SecretKey for signing and verification.
Query the miniapps on an App
Path:
/openapi/v1/channel/miniapp/searchMethod: POST
Content-Type: application/json
Body:
{ "after": "0", # The first page starts from "0", and the starting position of the next page refers to the "after" field in the returned result. "limit": 10, # The number of miniapps that you want to query. "keyWord": "demo" # The keyword for the query. }Response:
{ "success":true, "model":{ "after":"64", # The starting position of the next page, if this value equals "-1", indicates the end of the query. "size":2, "data":[ { "id":390, "appId":"1511654371932651552768", "miniappCode":"1511654371932651552768", "publishServicePlanId":"P442675078547163136", "name":"uniapp-hll-0505", "version":"1.0.1", "description":"", "slogan":"11111", "platform":"MiniApp", "framework":"UniApp", "icon":"icon/app/50112037081b4d5e9955f43aae22fb0d.jpeg", "publicIcon":"https://ceph-pre1.emas-poc.com/emas-cdn/publish/intercnn/icon/app/50112037081b4d5e9955f43aae22fb0d.jpeg" }, { "id":64, "appId":"1511608276458218872832", "miniappCode":"1511608276458218872832", "publishServicePlanId":"P396236781277202432", "name":"HllwindVane1129", "version":"0.0.2", "description":"", "slogan":"", "platform":"MiniApp", "framework":"WindVane", "icon":"icon/app/b4d6ff4f9111470c95f4ac2ef1c3079d.jpeg", "publicIcon":"http://cxfe-daily.oss-cn-hangzhou.aliyuncs.com/icon/app/b4d6ff4f9111470c95f4ac2ef1c3079d.jpeg?Expires=1672281817&OSSAccessKeyId=LTAI****************&Signature=ZpoXL%2Bo4UGHAcgIQTMPQc30sQ1c%3D" } ] } }
Query the metadata of published miniapps
Path:
/openapi/v1/channel/miniappMethod: POST
Content-Type: application/json
Body:
{ "miniappCode": "1511654371932651552768" }Response:
{ "success":true, "model":{ "channelCode":"1611606158604452241408", "gmtCreate":1683268112168, "gmtModified":1683350460819, "description":{ "inuseStatus":"ACTIVE", "description":"", "icon":"icon/app/50112037081b4d5e9955f43aae22fb0d.jpeg", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/app/50112037081b4d5e9955f43aae22fb0d.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T092821Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=094773e26ff4ab9ec84e091367670ac007e9b43208bce59fbadd2bece7a3cc46" }, "platform":"MiniApp", "framework":"UniApp", "publishStatus":"ONLINE", "onlineVersion":"1.0.1" } }
Query the category of an app
Path:
/openapi/v1/channel/category/listMethod: POST
Content-Type: application/json
Header: x-locale: zh_CN/en_US (default)
Body:
{}Response:
{ "success":true, "model":[ { "name":"Bills", "channelCode":"1611606158604452241408", "categoryId":1, "status":"ENABLE", "sort":0, "gmtCreate":1690366685363, "gmtModified":1690366685363 }, { "name":"Food & Beverage", "channelCode":"1611606158604452241408", "categoryId":3, "status":"ENABLE", "sort":1, "gmtCreate":1690366685365, "gmtModified":1690366685365 } ] }
Query the miniapps that are bound to an app category
Path:
/openapi/v1/channel/category/miniapp/listMethod: POST
Content-Type: application/json
Body:
{ "categoryId": 1L }Response:
{ "success":true, "model":[ { "name":"third-party-uniapp", "icon":"icon/channel/default_miniapp_icon.png", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/default_miniapp_icon.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T094401Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=e515ba8ade8f66d0473c8c407b5a9b90385f5e6cba1a2b9e885232f3a6969020", "channelCode":"1611606158604452241408", "categoryId":3, "miniappCode":"1511686301389817548800", "channelTagName":"HOTHOTHOTHOTHOTHOTHOTHOTHOT", "publishStatus":"ONLINE", "onlineVersion":"0.0.1", "sort":0, "gmtCreate":1690882000531, "gmtModified":1690882032947 } ] }
Request Header Construction
Request header params
The request header contains the following fields
Field | Required | Code sample |
X-Request-Sign | Yes | X-Request-Sign: **** |
X-Access-Key | Yes | X-Access-Key: 46b1cac78ed94ca4b99ad6de550afb6 |
Content-Type | No | Content-Type: application/json; charset=UTF-8 |
X-Request-Timestamp | Yes | X-Request-Timestamp: 1676904384074 |
Signature generation method
First, obtain the app's accessKey and secretKey from the SuperApp Open Platform.Specify the following properties that are used to construct the content to be signed:
HTTP_URI : e.g.
/openapi/v1/channel/miniapp/searchX-Access-Key: 46b1cac78ed94ca4b99ad6de550a****
X-Request-Timestamp: 1676904384074
HTTP_BODY : The following code provides an example of an HTTP request body:
{ "after": "0", # The first page starts from "0", and the starting position of the next page refers to the "after" field in the returned result. "limit": 10, # The number of miniapps that you want to query. "keyWord": "demo" # The keyword for the query. }
Construct the
content to be signedin the following format based on the preceding information: <HTTP_METHOD> <HTTP_URI>\n<HTTP_BODY>.<Request-Time>.<Access-Key>POST /openapi/v1/channel/miniapp/search { "after": "0", "limit": 10, "keyWord": "demo" }.1676904384074.46b1cac78ed94ca4b99ad6de550a****Use the HmacSHA1 algorithm to generate a signature.
The following code provides an example on how to add a signature to a request:
import org.apache.commons.lang3.StringUtils; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; import java.security.InvalidKeyException; import java.security.NoSuchAlgorithmException; import java.util.Base64; public class SignDemo { private static final char[] HEX = new char[] {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'}; public static String sign(String requestURI, String accessKey, String secretKey, Long requestTime, String requestBody) { String content = String.format("POST %s\n%s.%s.%s", requestURI, requestBody, requestTime, accessKey); String signed = generateSign(content, secretKey, "HmacSHA1"); return Base64.getEncoder().encodeToString(signed.getBytes(StandardCharsets.UTF_8)); } public static String generateSign(String content, String key, String algorithm) { if (!StringUtils.isEmpty(algorithm) && !StringUtils.isEmpty(content) && null != key) { try { SecretKeySpec signinKey = new SecretKeySpec(key.getBytes(), algorithm); Mac mac = Mac.getInstance(algorithm); mac.init(signinKey); byte[] rawHmac = mac.doFinal(content.getBytes()); return convertToHex(rawHmac); } catch (InvalidKeyException | NoSuchAlgorithmException var6) { return ""; } } else { return ""; } } public static String convertToHex(byte[] bytes) { int len = bytes.length; StringBuilder buf = new StringBuilder(len * 2); for (int j = 0; j < len; ++j) { buf.append(HEX[bytes[j] >> 4 & 15]); buf.append(HEX[bytes[j] & 15]); } return buf.toString(); } }Send the request
Add X-Access-Key,X-Request-Timestamp and X-Request-Sign to the request header to construct the following request:
curl -X POST \
https://example.com/openapi/v1/channel/miniapp/search \
-H 'Content-Type: application/json' \
-H 'X-Access-Key: 46b1cac78ed94ca4b99ad6de550afb68' \
-H 'X-Request-Timestamp: 1676904384074' \
-H 'X-Request-Sign: KrwDE9tAPJYBb4cUZU6ALJxGIZgwDXn5UkFPMip09n%2FkYKPhEIII%2Fki2rYY2lPtuKVgMNz%2BtuCU%2FjzRpohDbrOd8zYriiukpGAxBQDIVbatGI7WYOcc9YVQwdCR6ROuRQvr%2FD1AfdhHd6waAASu5Xugow9w1OW7Ti93LTd0tcyEWQYd2S7c3A73sHOJNYl8DC1PjasiBozZ%2FADgb7ONsqHo%2B8fKHsLygX9cuMkQYTGIRBQsvfgICnJhh%2BzXV8AQoecJBTrv6p%xxxx' \
-d '{
"after": "0",
"limit": 10,
"keyWord": "demo"
}'SuperApp Space Management Open APIs
The SuperApp Space Management Open APIs are Space-level backend service interfaces provided by the Application Open Platform, based on the Space administrator account's AccessKey and SecretKey for signing and verification. In most cases, these Open-APIs are used to synchronize relevant data in Application Open Platform space.
Query a specific app or channel
Path:
/openapi/v1/space/channel/queryMethod: POST
Content-Type: application/json
Body:
{ "spaceCode": "1531602854311704010754", "currentPage": 1, "pageSize": 10 }Response:
{ "success":true, "model":{ "total":5, "list":[ { "spaceCode":"1531602854311704010754", "channelCode":"1611608397718512873472", "gmtCreate":1672306873348, "gmtModified":1677137552998, "name":"2test channel by gdm", "icon":"icon/channel/7aa28302a4b44859b397d2438e19d22d.png", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/7aa28302a4b44859b397d2438e19d22d.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T095150Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=f19482bc1e94100672c50846df67cf8668f329503292dbab6bcfb21bb95ee043", "description":"test channel of description", "status":"ONLINE" }, { "spaceCode":"1531602854311704010754", "channelCode":"1611638746437729390592", "gmtCreate":1679542571898, "gmtModified":1684482439359, "name":"jkkjkj", "icon":"icon/channel/db6330e973404d1183fbc9e38f207b7e.jpeg", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/db6330e973404d1183fbc9e38f207b7e.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T095150Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=4b5cf7c56d52a6a812ebd8169ab04b5744f39fea5a076e53e626db92255c4968", "description":"demo", "status":"ONLINE" } ], "pageSize":10, "current":1, "empty":false, "totalPages":1 } }
Query miniapps
Path:
/openapi/v1/space/miniapp/queryMethod: POST
Content-Type: application/json
Body:
{ "spaceCode": "1531602854311704010754", "currentPage": 1, "pageSize": 10 }Response:
{ "success":true, "model":{ "total":45, "list":[ { "spaceCode":"1531602854311704010754", "miniappCode":"1511686305220810936320", "gmtCreate":1690881469335, "gmtModified":1690881469335, "platform":"MiniApp", "framework":"WindVane", "name":"third-party 111", "description":"", "slogan":"", "icon":"icon/channel/default_miniapp_icon.png", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/default_miniapp_icon.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T095456Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=5d121004dd1bfee918ce3504f67fa541104f3556b13d57ff8b27212e99043acb" }, { "spaceCode":"1531602854311704010754", "miniappCode":"1511686243166489821184", "gmtCreate":1690866674445, "gmtModified":1690874095536, "platform":"MiniApp", "framework":"WindVane", "name":"teest", "description":"", "slogan":"", "icon":"icon/channel/default_miniapp_icon.png", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/default_miniapp_icon.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T095456Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=5d121004dd1bfee918ce3504f67fa541104f3556b13d57ff8b27212e99043acb" } ], "pageSize":5, "current":1, "empty":false, "totalPages":9 } }
Query the publishing information of a miniapp
Path:
/openapi/v1/space/miniapp/publishMethod: POST
Content-Type: application/json
Body:
{ "spaceCode": "1531602854311704010754", "currentPage": 1, "pageSize": 10 }Response:
{ "success":true, "model":{ "spaceCode":"1531602854311704010752", "miniappCode":"1511687342586899365888", "gmtCreate":1691128796684, "gmtModified":1691134056419, "platform":"MiniApp", "framework":"WindVane", "name":"WTF0804", "description":"", "slogan":"", "icon":"icon/channel/default_miniapp_icon.png", "iconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/default_miniapp_icon.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T100031Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3600&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=59143f1fff5a849b08e4046590f972f4740f38fe5f899d38deffcfb92061c9db", "publishMiniappInfo":[ { "channelCode":"1611606158604452241408", "channelName":"SuperApp Channel test1", "channelIcon":"icon/channel/393eaa3f7fef4205b34e5817310e6cf2.jpeg", "channelIconPublicUrl":"http://47.103.XXX.XX:7480/intercnn/icon/channel/393eaa3f7fef4205b34e5817310e6cf2.jpeg?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T100031Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=716456ad0355b10475da9afa6b0bc5c976a84d40c21fb1b4b3990cefa15bcab6", "gmtCreate":1691129052113, "gmtModified":1691134073490, "miniappCode":"1511687342586899365888", "onlineVersion":"0.0.5", "publishStatus":"ONLINE", "description":{ "inuseStatus":"ACTIVE", "name":"0.0.5", "description":"", "icon":"icon/channel/default_miniapp_icon.png", "iconPublicUrl":"http://47.103.xxx.xxx:7480/intercnn/icon/channel/default_miniapp_icon.png?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Date=20230804T100031Z&X-Amz-SignedHeaders=host&X-Amz-Expires=3599&X-Amz-Credential=IW2NNNAI0D8J2K8F7BPX%2F20230804%2Fus-east-1%2Fs3%2Faws4_request&X-Amz-Signature=c419ed372b6827aa5ba540f95c4edad4bb8c168a37cb0005f3220922cb4dcd63" } } ] } }
Request Header Construction
SuperApp space management openapi signature uses the accessKey and secretKey of first party's space administrator account. Please contact the SuperApp Open Platform operation team to obtain the corresponding values. The request header params and signature generation method is the same as the "SuperApp Channel Management Open APIs"
SDK Open APIs
Add a miniapp to favorites
Android
ServiceManager.getInstance().registerService(IMiniAppFavoriteService.class.getName(), new IMiniAppFavoriteService() { @Override public void addToFavorites(String appId, ServiceCallback callback) { // Add a miniapp to favorites. The result is returned from a callback. } @Override public void removeFromFavorites(String appId, ServiceCallback callback) { // Remove a miniapp from favorites. The result is returned from a callback. } @Override public boolean isFavorite(String appId) { // Check whether a miniapp is added to favorites. return false; } });iOS
[[EMASServiceManager sharedInstance] registerServiceProtocol:@"EMASMiniAppFavoriteService" IMPClass:@"EMASMiniAppFavoriteServiceImpl" target:nil]; @implementation EMASMiniAppFavoriteServiceImpl - (void)addToFavorites:(NSString*)subAppCode completion:(nonnull EMASFavoriteCompletionBlock)completionBlock{ // Add a miniapp to favorites. The result is returned from a block. } - (void)removeFromFavorites:(NSString*)subAppCode completion:(nonnull EMASFavoriteCompletionBlock)completionBlock{ // Remove a miniapp from favorites. The result is returned from a block. } - (BOOL)isFavorite:(NSString*)subAppCode { // Check whether a miniapp is added to favorites. return NO; } @end
Save a miniapp to recents
Android
IMiniAppService miniAppService = ServiceManager.getInstance().getService(IMiniAppService.class.getName()); if (miniAppService != null) { miniAppService.openMiniApp(mItemView.getContext(), ((MiniAppInfo) data).getAppId(), null, new OnOpenMiniAppListener() { @Override public void onOpenMiniApp() { } @Override public void onOpenSuccess(String appId) { // Save a miniapp to recents when the miniapp is started. } @Override public void onOpenFailed(String appId, int errorCode) { } }); }iOS
id<EMASMiniAppService> miniAppService = [[EMASServiceManager sharedInstance] serviceForProtocol:@"EMASMiniAppService"]; if (miniAppService) { [miniAppService openMiniApp:appId openConfiguration:nil completionBlock:^(int resultCode, NSDictionary * _Nonnull resultDict) { // If the value of resultCode is 200, the miniapp is started. // Save the miniapp to recents. }]; }
Query the metadata of miniapps
NoteIf you want to obtain the real-time metadata of a miniapp from a client, you can call the container API operation.
Android
IMiniAppService miniAppService = ServiceManager.getInstance().getService(IMiniAppService.class.getName()); if (miniAppService != null) { // The appIds parameter specifies the IDs of miniapps whose metadata you want to query. miniAppService.getMiniAppInfos(this, appIds, new OnGetMiniAppsListener() { @Override public void onSuccess(List<MiniAppInfo> miniAppInfos) { // The metadata of the miniapps is returned. } @Override public void onFailed(int errorCode) { } }); }iOS
id<EMASMiniAppService> miniAppService = [[EMASServiceManager sharedInstance] serviceForProtocol:@"EMASMiniAppService"]; if (miniAppService) { // The appIds parameter specifies the IDs of miniapps whose metadata you want to query. [miniAppService getMiniAppInfo:appIds completionBlock:^(int resultCode, NSArray * _Nonnull miniApps) { // If the value of resultCode is 200, miniapp metadata is queried. // The metadata of the miniapps is returned. }]; }
Search for specific miniapps
Android
IMiniAppService miniAppService = ServiceManager.getInstance().getService(IMiniAppService.class.getName()); if (miniAppService != null) { // The keyword for the query. miniAppService.queryMiniApps(this, keyword, new OnQueryMiniAppsListener() { @Override public void onSuccess(List<MiniAppInfo> miniAppInfos, String anchor) { // The search results are returned. By default, a maximum of 10 miniapps can be obtained. The anchor parameter is used to obtain more miniapps. } @Override public void onFailed(int errorCode) { } }); }iOS
id<EMASMiniAppService> miniAppService = [[EMASServiceManager sharedInstance] serviceForProtocol:@"EMASMiniAppService"]; if (miniAppService) { // The keyword parameter specifies the search keyword. The default value of anchor is 0. [miniAppService queryMiniApps:keyword anchor:anchor completionBlock:^(int resultCode, NSArray * _Nonnull miniApps, NSString *anchor) { // If the value of resultCode is 200, the search succeeds. // The search results are returned. By default, a maximum of 10 miniapps can be obtained. The anchor parameter is used to obtain more miniapps. }]; }
Fetch all miniapps
Android
IMiniAppService miniAppService = ServiceManager.getInstance().getService(IMiniAppService.class.getName()); if (miniAppService != null) { // Leave keyword empty. miniAppService.getMiniAppList(this, new OnGetMiniAppsListener() { @Override public void onSuccess(List<MiniAppInfo> miniAppInfos, String anchor) { // A list of miniapps is returned. By default, a maximum of 10 miniapps can be obtained. The anchor parameter is used to obtain more miniapps. } @Override public void onFailed(int errorCode) { } }); }iOS
id<EMASMiniAppService> miniAppService = [[EMASServiceManager sharedInstance] serviceForProtocol:@"EMASMiniAppService"]; if (miniAppService) { // The default value of the anchor parameter is 0. [miniAppService getMiniAppList:anchor completionBlock:^(int resultCode, NSArray * _Nonnull miniApps, NSString *anchor) { // If the value of resultCode is 200, all miniapps are fetched. // A list of miniapps is returned. By default, a maximum of 10 miniapps can be obtained. The anchor parameter is used to obtain more miniapps. }]; }