--- title: "Schedule terminal actions to deploy apps" description: "Use the Management API to schedule actions on terminals, specifically installing and uninstalling Android apps and certificates." url: "https://docs.adyen.com/point-of-sale/android-terminals/deploy-apps/terminal-actions-api" source_url: "https://docs.adyen.com/point-of-sale/android-terminals/deploy-apps/terminal-actions-api.md" canonical: "https://docs.adyen.com/point-of-sale/android-terminals/deploy-apps/terminal-actions-api" last_modified: "2024-04-03T13:59:00+02:00" language: "en" --- # Schedule terminal actions to deploy apps Use the Management API to schedule actions on terminals, specifically installing and uninstalling Android apps and certificates. [View source](/point-of-sale/android-terminals/deploy-apps/terminal-actions-api.md) Terminal actions are operations that need to be carried out on payment terminals, and that can be planned for a certain date and time. Most of those actions are planned by Adyen, like updating to a release, or obtaining logs. Some actions can be planned by you. Here we describe how you can use our **Management API** to automate terminal actions to deploy apps and certificates on Android payment terminals. ## Requirements Before you begin, take into account the following requirements and limitations. | Requirement | Description | | ------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | **Integration type** | A [Terminal API integration](/point-of-sale/design-your-integration/terminal-api) with payment terminals or a [standalone solution](/point-of-sale/standalone). | | **[API credentials](/development-resources/api-credentials)** | You must have an API credential with an API key and the following [roles](/development-resources/api-credentials#api-permissions):- Management API—Terminal actions read - Management API—Terminal actions read and write - Management API—Terminal settings read If you have a Terminal API integration with [cloud-based communications](/point-of-sale/design-your-integration/choose-your-architecture#cloud-communications), you can use the existing API key that you use for Terminal API requests. | | **Hardware** | Android payment terminals. | | **Limitations** | Requests to live Management API endpoints related to scheduling terminal actions are subject to [rate limits](/point-of-sale/automating-terminal-management#rate-limits-in-the-live-environment). | ## When planned actions take effect Terminal actions are changes in the configuration of the terminal. The terminal receives configuration changes when it makes a [maintenance call](/point-of-sale/managing-terminals/maintain-performance) and implements the changes when it reboots at the [restart hour](/point-of-sale/managing-terminals/maintain-performance#rebooting-at-the-restart-hour) (at 06:00 AM by default).\ To ensure this process succeeds, we recommend that you keep your terminals turned on and connected to the network overnight. In the case of [Android terminal actions](#android-actions), the terminal does not wait until the restart hour. * If you planned the Android action without a date and time, the action is implemented with the next maintenance call. If WebSockets are enabled, the action is implemented immediately. * If you planned the Android action for a specific date and time, the action is implemented with the first maintenance call after that date/time in the time zone of the terminal. If WebSockets are enabled, the action is implemented at the exact date and time that you specified. If the action involves an Android app that is already installed on the terminal and that happens to be open at the time of the action, the app closes. ## Android terminal actions *Android terminal actions* are related to the deployment of apps that you want to run on your Android terminals. For example, a POS app. To run such an app, you need to install it on the terminal. Maybe you also need to remove an old version that you no longer want to use. Some apps need a digital certificate. For example, a certificate to protect network communications between a POS app and the back end of that app. Such a certificate needs to be installed on the terminal, and replaced with a new one before the validity period of the certificate expires. To sum up, Android terminal actions you can plan are: * Install a new app or app version. * Uninstall an old app or app version. * Install a new certificate. * Uninstall an expired certificate. These actions are part of a larger process where you: 1. Make sure that the app meets the [requirements](/point-of-sale/android-terminals/app-requirements). 2. [Upload the app](/point-of-sale/android-terminals/deploy-apps/upload#upload-your-app) in your Customer Area. We then sign the app and convert it so that the terminal can handle the app. 3. If the app requires a certificate, [upload the certificate](/point-of-sale/android-terminals/deploy-apps/upload#upload-cert) as well, so that we can sign it. 4. Plan terminal actions to install or uninstall apps and certificates. You can plan actions [in your Customer Area](/point-of-sale/android-terminals/deploy-apps/schedule), but here we describe how to plan actions by making API calls to: 1. [Get the IDs of the apps or certificates](#get-android-apps-and-certs) that have been uploaded. 2. [Get the IDs of the terminals](#get-terminal-ids) that you want to apply the action to. 3. [Plan an Android terminal action](#plan-android-action). ## 1. Get Android app and certificate IDs When planning an Android terminal action, you need to provide the ID of the Android app or certificate you want to install or uninstall. To get those IDs, check which apps and certificates have been uploaded: 1. Make sure that you know the ID of your company. If you do not know this ID, make a GET [/companies](https://docs.adyen.com/api-explorer/Management/latest/get/companies) request. 2. Check what Android apps and optionally what Android certificates are available. ### Tab: Get Android apps Get a list of Android apps that have been uploaded, by making a GET [/companies/{companyId}/androidApps](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps) request.\ These are the query parameters to filter the paginated response: * [pageNumber](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#query-pageNumber): returns the apps shown on the specified page. * [pageSize](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#query-pageSize): the number of apps to have on a page. The default is 20, the maximum is 100. **Get list of uploaded apps** #### curl ```bash curl https://management-test.adyen.com/v3/companies/COMPANY_ID/androidApps \ -H 'x-API-key: ADYEN_API_KEY' \ -X GET ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.management.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Make the request AndroidFilesCompanyLevelApi service = new AndroidFilesCompanyLevelApi(client); AndroidAppsResponse response = service.listAndroidApps("companyId", 1, 1, "String", 1, null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Service\Management\AndroidFilesCompanyLevelApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('pageNumber' => 'integer', 'pageSize' => 'integer', 'packageName' => 'string', 'versionCode' => 'integer'); // Make the request $service = new AndroidFilesCompanyLevelApi($client); $response = $service->listAndroidApps('companyId', $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v14.3.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Service.Management; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Make the request var service = new AndroidFilesCompanyLevelService(client); var response = service.ListAndroidApps("companyId", pageNumber: 1, pageSize: 1, packageName: "string", versionCode: 1); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, ManagementAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.AndroidFilesCompanyLevelApi.listAndroidApps("companyId", 1, 1, "string", 1); ``` #### Go ```go // Adyen Go API Library v9.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/management" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Make the request service := client.Management() req := service.AndroidFilesCompanyLevelApi.ListAndroidAppsInput("companyId") req = req.PageNumber(1).PageSize(1).PackageName("string").VersionCode(1)res, httpRes, err := service.AndroidFilesCompanyLevelApi.ListAndroidApps(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "pageNumber" : "integer", "pageSize" : "integer", "packageName" : "string", "versionCode" : "integer" } result = adyen.management.android_files_company_level_api.list_android_apps(companyId="companyId", query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v9.2.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment query_params = { :pageNumber => 'integer', :pageSize => 'integer', :packageName => 'string', :versionCode => 'integer' } result = adyen.management.android_files_company_level_api.list_android_apps('companyId', query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, ManagementAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.AndroidFilesCompanyLevelApi.listAndroidApps("companyId", 1, 1, "string", 1); ``` The response returns the following details of all apps that have been [uploaded](/point-of-sale/android-terminals/deploy-apps/upload#upload-your-app) to Adyen and are in the **ready** status: | Response parameter | Description | | ------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | | [id](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-id) | The unique, Adyen-generated identifier of the app. Starts with **ANDA**. | | [packageName](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-packageName) | The package name of the app. For example, **com.your\_company.posapp**. | | [versionCode](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-versionCode) | The internal version number of the app. | | [description](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-description) | The description that was entered in the Customer Area when uploading the app. The description is not shown on the terminal. | | [label](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-label) | The app name that is shown on the terminal. | | [versionName](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-versionName) | The app version number that is shown on the terminal. | | [status](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidApps#responses-200-data-status) | The status of the app: **ready**. | **Response** ```json { "androidApps": [ { "id": "ANDA422LZ223223K5F694GCCF732K8", "packageName": "com.your_company.posapp", "versionCode": 7700203, "description": "POS2", "label": "POS app", "versionName": "7.7", "status": "ready" }, { "id": "ANDA422LZ223223K5F694FWCF738PL", "packageName": "com.your_company.posapp", "versionCode": 7602003, "description": "POS1", "label": "POS app", "versionName": "7.6", "status": "ready" } ] } ``` ### Tab: Get Android certificates Get a list of Android certificates that have been uploaded, by making a GET [/companies/{companyId}/androidCertificates](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates) request.\ These are the query parameters to filter the paginated response: * [pageNumber](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#query-pageNumber): returns the certificates shown on the specified page. * [pageSize](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#query-pageSize): the number of certificates to have on a page. The default is 20, the maximum is 100. **Get list of uploaded certificates** #### curl ```bash curl https://management-test.adyen.com/v3/companies/COMPANY_ID/androidCertificates \ -H 'x-API-key: ADYEN_API_KEY' \ -X GET ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.management.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Make the request AndroidFilesCompanyLevelApi service = new AndroidFilesCompanyLevelApi(client); AndroidCertificatesResponse response = service.listAndroidCertificates("companyId", 1, 1, "String", null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Service\Management\AndroidFilesCompanyLevelApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('pageNumber' => 'integer', 'pageSize' => 'integer', 'certificateName' => 'string'); // Make the request $service = new AndroidFilesCompanyLevelApi($client); $response = $service->listAndroidCertificates('companyId', $requestOptions); ``` #### C\# ```cs // Adyen .net API Library v14.3.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Service.Management; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Make the request var service = new AndroidFilesCompanyLevelService(client); var response = service.ListAndroidCertificates("companyId", pageNumber: 1, pageSize: 1, certificateName: "string"); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, ManagementAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.AndroidFilesCompanyLevelApi.listAndroidCertificates("companyId", 1, 1, "string"); ``` #### Go ```go // Adyen Go API Library v9.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/management" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Make the request service := client.Management() req := service.AndroidFilesCompanyLevelApi.ListAndroidCertificatesInput("companyId") req = req.PageNumber(1).PageSize(1).CertificateName("string")res, httpRes, err := service.AndroidFilesCompanyLevelApi.ListAndroidCertificates(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "pageNumber" : "integer", "pageSize" : "integer", "certificateName" : "string" } result = adyen.management.android_files_company_level_api.list_android_certificates(companyId="companyId", query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v9.2.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment query_params = { :pageNumber => 'integer', :pageSize => 'integer', :certificateName => 'string' } result = adyen.management.android_files_company_level_api.list_android_certificates('companyId', query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, ManagementAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.AndroidFilesCompanyLevelApi.listAndroidCertificates("companyId", 1, 1, "string"); ``` The response returns the following details of all certificates that have been [uploaded](/point-of-sale/android-terminals/deploy-apps/upload#upload-cert) to Adyen and are in the **ready** status: | Response parameter | Description | | --------------------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------- | | [id](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-id) | The unique, Adyen-generated identifier of the certificate. Starts with **ANDC**. | | [name](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-name) | The file name of the certificate. For example, **mycert**. | | [extension](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-extension) | The file format of the certificate, as indicated by the file extension. For example, **.crt** or **.pem**. | | [description](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-description) | The description that was entered in the Customer Area when uploading the certificate. | | [status](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-status) | The status of the certificate: **ready** | | [notBefore](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-notBefore) | The date when this certificate starts to be valid. | | [notAfter](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/androidCertificates#responses-200-data-notAfter) | The date when this certificate stops to be valid. | **Response** ```json { "androidCertificates": [ { "id": "ANDC422LZ223223K5F78NVN9SL4VPH", "name": "mycert", "extension": ".crt", "description": "", "status": "ready", "notBefore": "2008-04-20T00:00:00+02:00", "notAfter": "2038-04-12T00:00:00+02:00" }, { "id": "ANDC533MA33433L689OWO0TM5WQI", "name": "mynewcert", "extension": ".pem", "description": "", "status": "ready", "notBefore": "20018-04-20T00:00:00+02:00", "notAfter": "2048-04-12T00:00:00+02:00" } ] } ``` 3. From the response, save the `id` of the Android app or certificate that you want to install or uninstall. ## 2. Get terminal IDs When planning an Android terminal action, you need to provide the IDs of the terminals that you want to apply an action to. To create a list of terminals: 1. Make a GET [/terminals](https://docs.adyen.com/api-explorer/Management/latest/get/terminals) request using query parameters to restrict the list to terminals that match specific conditions. You can specify multiple values for a single query parameter like this: `/terminals?countryCodes=NL,FR`. These are the query parameters to filter the paginated response: | Query parameter | Required | Description | | ---------------------------------------------------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [searchQuery](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-searchQuery) | | Returns terminals with an ID that contains the specified string.If you use this query parameter, other query parameters are ignored. | | [countries](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-countries) | | Returns terminals located in the specified countries/regions. Format: the two-letter [ISO-3166-1 alpha-2](https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2) country code. Exception: **QZ** (Kosovo). | | [merchantIds](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-merchantIds) | | Returns terminals that belong to the merchant accounts specified by their unique ID. For a list of merchant account IDs, make a GET request to [/companies/{companyId}/merchants](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/merchants). | | [storeIds](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-storeIds) | | Returns terminals that are assigned to the stores specified by their unique store ID. For a list of store IDs, make a [GET `/stores`](/point-of-sale/design-your-integration/determine-account-structure/automate-store-management#get-all-stores) request. | | [brandModels](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-brandModels) | | Returns terminals of the specified models in the format *brand.model*. For example, **Castles.S1F2**. For a list of brand models, make a [GET `/terminalModels`](/point-of-sale/automating-terminal-management/order-terminals-api#get-product-id) request and use the `id` from the response. | | [pageNumber](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-pageNumber) | | Returns the terminals shown on the specified page. | | [pageSize](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#query-pageSize) | | The number of terminals to have on a page. The default is 20, the maximum is 100. | The following example shows how to create a list of all **S1E** and **S1F2** Android terminals for a specific merchant account. **Get terminals** #### curl ```bash curl https://management-test.adyen.com/v3/terminals?brandmodel=Castles.S1E,Castles.S1F2&merchantId=ADYEN_MERCHANT_ACCOUNT \ -H 'x-API-key: ADYEN_API_KEY' \ -X GET ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.service.management.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Make the request TerminalsTerminalLevelApi service = new TerminalsTerminalLevelApi(client); ListTerminalsResponse response = service.listTerminals("String", "String", "String", "String", "String", "String", 1, 1, null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Service\Management\TerminalsTerminalLevelApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); $requestOptions['queryParams'] = array('searchQuery' => 'string', 'otpQuery' => 'string', 'countries' => 'string', 'merchantIds' => 'string', 'storeIds' => 'string', 'brandModels' => 'string', 'pageNumber' => 'integer', 'pageSize' => 'integer'); // Make the request $service = new TerminalsTerminalLevelApi($client); $response = $service->listTerminals($requestOptions); ``` #### C\# ```cs // Adyen .net API Library v14.3.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Service.Management; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Make the request var service = new TerminalsTerminalLevelService(client); var response = service.ListTerminals(searchQuery: "string", otpQuery: "string", countries: "string", merchantIds: "string", storeIds: "string", brandModels: "string", pageNumber: 1, pageSize: 1); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, ManagementAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalsTerminalLevelApi.listTerminals("string", "string", "string", "string", "string", "string", 1, 1); ``` #### Go ```go // Adyen Go API Library v9.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/management" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Make the request service := client.Management() req := service.TerminalsTerminalLevelApi.ListTerminalsInput() req = req.SearchQuery("string").OtpQuery("string").Countries("string").MerchantIds("string").StoreIds("string").BrandModels("string").PageNumber(1).PageSize(1)res, httpRes, err := service.TerminalsTerminalLevelApi.ListTerminals(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. query_parameters = { "searchQuery" : "string", "otpQuery" : "string", "countries" : "string", "merchantIds" : "string", "storeIds" : "string", "brandModels" : "string", "pageNumber" : "integer", "pageSize" : "integer" } result = adyen.management.terminals_terminal_level_api.list_terminals(query_parameters=query_parameters) ``` #### Ruby ```rb # Adyen Ruby API Library v9.2.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment query_params = { :searchQuery => 'string', :otpQuery => 'string', :countries => 'string', :merchantIds => 'string', :storeIds => 'string', :brandModels => 'string', :pageNumber => 'integer', :pageSize => 'integer' } result = adyen.management.terminals_terminal_level_api.list_terminals(query_params: query_params) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, ManagementAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalsTerminalLevelApi.listTerminals("string", "string", "string", "string", "string", "string", 1, 1); ``` For each terminal, notice in the response: * [id](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#responses-200-data-id): the unique terminal ID. * [status](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#responses-200-data): indicates when the terminal was last online, whether the terminal is being reassigned, or whether the terminal is turned off. If the terminal was last online more that a week ago, it is also shown as turned off. * [assigned](https://docs.adyen.com/api-explorer/Management/latest/get/terminals#responses-200-data-assigned): **true** indicates the terminal is assigned to a store, or to a merchant account representing a store. **false** indicates the terminal is in [inventory](/point-of-sale/automating-terminal-management/assign-terminals-api#inventory-and-in-store). **Response** ```json { "terminals": [ { "id": "S1E-000150183300032", "status": "SwitchedOff", "assigned": true, "bluetoothMac": "a4:60:11:83:0e:00", "companyAccount": "TestCompany", "deviceModel": "S1E", "ethernetMac": "64:5a:ed:f5:68:55", "firmwareVersion": "Castles_Android 1.79.4", "iccid": "6006491286999921374", "lastActivityDateTime": "2022-08-05T14:48:10+02:00", "lastTransactionDateTime": "2022-08-05T14:32:10+02:00", "serialNumber": "000150183300032", "city": "Amsterdam", "countryCode": "NL", "storeStatus": "Active", "wifiIp": "198.51.100.1", "wifiMac": "C4:6E:00:16:A1:01", "wifiSsid": "GUEST" }, { "id": "S1E-000150183300033", "status": "OnlineToday", "assigned": true, "bluetoothMac": "a4:60:11:83:0e:00", "companyAccount": "TestCompany", "deviceModel": "S1E", "ethernetMac": "64:5a:ed:f5:68:55", "firmwareVersion": "Castles_Android 1.79.4", "iccid": "6006491286999921374", "lastActivityDateTime": "2022-08-09T12:44:11+02:00", "lastTransactionDateTime": "2022-07-27T11:35:44+02:00", "serialNumber": "000150183300033", "city": "Amsterdam", "countryCode": "NL", "storeStatus": "Active", "wifiIp": "198.51.100.1", "wifiMac": "C4:6E:00:16:A1:01", "wifiSsid": "GUEST" }, { "id": "S1F2-000150183300034", "status": "onlineLast1Day", "assigned": true, "bluetoothMac": "a4:60:11:83:0e:00", "companyAccount": "TestCompany", "deviceModel": "S1F2", "ethernetMac": "64:5a:ed:f5:68:55", "firmwareVersion": "Castles_Android 1.79.4", "iccid": "6006491286999921374", "lastActivityDateTime": "2022-08-08T14:48:10+02:00", "lastTransactionDateTime": "2022-07-27T11:56:59+02:00", "serialNumber": "000150183300034", "city": "Amsterdam", "countryCode": "NL", "storeStatus": "Active", "wifiIp": "198.51.100.1", "wifiMac": "C4:6E:00:16:A1:01", "wifiSsid": "GUEST" } ] } ``` 2. Extract the unique terminal IDs from the response. ## 3. Schedule an Android terminal action When planning terminal actions, be aware of the following restrictions: * You can schedule one action at a time. For example, to install two different apps you have to make two API requests. * The maximum number of terminals in a request is **100**. For example, to apply an action to 250 terminals, you have to divide the terminals over three API requests. * If there is an error with one or more terminal IDs in the request, the action is scheduled for none of the terminals. You need to fix the error and try again. To plan an Android terminal action: 1. Make a POST [/terminals/scheduleActions](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions) request, specifying: | Parameter | Required | Type | Description | | --------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [terminalIds](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#request-terminalIds) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | String array | A list of unique IDs of the terminals to apply the action to. See [2. Get terminal IDs](#get-terminal-ids). Maximum length: 100 IDs. | | [storeId](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#request-storeId) | | String | The unique ID of the store that the terminals are assigned to. If you do not know this ID, make a GET request to [/stores](https://docs.adyen.com/api-explorer/Management/latest/get/stores). The request fails if the [terminalIds](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#request-terminalIds) do not belong to this store. | | [scheduledAt](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#request-scheduledAt) | | String | The date and time when the action should happen. Format: [RFC 3339](https://www.rfc-editor.org/rfc/rfc3339), but without the **Z** before the time offset. For example, **2021-11-15T12:16:21+0100** The terminal installs or removes the app with the first [maintenance call](#when-actions-take-effect) after the specified date and time in the time zone of the terminal. An empty value causes the action to happen as soon as possible: at the next maintenance call. | | [actionDetails](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#request-actionDetails) | ![-white\_check\_mark-](/user/data/smileys/emoji/white_check_mark.png "-white_check_mark-") | String object | This is where you specify the action and the app or certificate ID. See [1. Get Android app and certificate IDs](#get-android-apps-and-certs) . For an Android app action, this object must contain:- `appId`: The unique identifier of the app. - `type`: The type of action. Possible values: **InstallAndroidApp** or **UninstallAndroidApp**. For an Android certificate action, this object must contain:- `certificateId`: The unique identifier of the certificate. - `type`: The type of action. Allowed values: **InstallAndroidCertificate** or **UninstallAndroidCertificate** | The following examples show how to install an app, and how to uninstall a certificate. **Install an app** #### curl ```bash curl https://management-test.adyen.com/v3/terminals/scheduleActions \ -H 'content-type: application/json' \ -H 'x-API-key: ADYEN_API_KEY' \ -X POST \ -d '{ "terminalIds": [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], "storeId": "", "scheduledAt": "2021-12-12T20:21:22-0100", "actionDetails" : { "type" : "InstallAndroidApp", "appId" : "ANDA422LZ223223K5F694GCCF732K8" } }' ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.management.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.management.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Request objects InstallAndroidAppDetails installAndroidAppDetails = new InstallAndroidAppDetails() .appId("ANDA422LZ223223K5F694GCCF732K8") .type(InstallAndroidAppDetails.TypeEnum.INSTALLANDROIDAPP); ScheduleTerminalActionsRequest scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest() .actionDetails(new ScheduleTerminalActionsRequestActionDetails(installAndroidAppDetails)) .terminalIds(Arrays.asList("S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034")) .storeId("") .scheduledAt("2021-12-12T20:21:22-0100"); // Make the request TerminalActionsTerminalLevelApi service = new TerminalActionsTerminalLevelApi(client); ScheduleTerminalActionsResponse response = service.createTerminalAction(scheduleTerminalActionsRequest, null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Model\Management\ScheduleTerminalActionsRequestActionDetails; use Adyen\Model\Management\ScheduleTerminalActionsRequest; use Adyen\Service\Management\TerminalActionsTerminalLevelApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); // Request objects $scheduleTerminalActionsRequestActionDetails = new ScheduleTerminalActionsRequestActionDetails(); $scheduleTerminalActionsRequestActionDetails ->setAppId("ANDA422LZ223223K5F694GCCF732K8") ->setType("InstallAndroidApp"); $scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest(); $scheduleTerminalActionsRequest ->setActionDetails($scheduleTerminalActionsRequestActionDetails) ->setTerminalIds(array("S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034")) ->setStoreId("") ->setScheduledAt("2021-12-12T20:21:22-0100"); // Make the request $service = new TerminalActionsTerminalLevelApi($client); $response = $service->createTerminalAction($scheduleTerminalActionsRequest); ``` #### C\# ```cs // Adyen .net API Library v14.3.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Management; using Adyen.Service.Management; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Fill in your request objects InstallAndroidAppDetails installAndroidAppDetails = new InstallAndroidAppDetails { AppId = "ANDA422LZ223223K5F694GCCF732K8", Type = InstallAndroidAppDetails.TypeEnum.InstallAndroidApp }; ScheduleTerminalActionsRequest scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest { ActionDetails = new ScheduleTerminalActionsRequestActionDetails(installAndroidAppDetails), TerminalIds = { "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" }, StoreId = "", ScheduledAt = "2021-12-12T20:21:22-0100" }; // Make the request var service = new TerminalActionsTerminalLevelService(client); var response = service.CreateTerminalAction(scheduleTerminalActionsRequest); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, ManagementAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object const scheduleTerminalActionsRequest = { terminalIds: [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], storeId: "", scheduledAt: "2021-12-12T20:21:22-0100", actionDetails: { type: "InstallAndroidApp", appId: "ANDA422LZ223223K5F694GCCF732K8" } } // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalActionsTerminalLevelApi.createTerminalAction(scheduleTerminalActionsRequest); ``` #### Go ```go // Adyen Go API Library v9.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/management" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Fill in your request objects installAndroidAppDetails := management.InstallAndroidAppDetails{ AppId: common.PtrString("ANDA422LZ223223K5F694GCCF732K8"), Type: common.PtrString("InstallAndroidApp"), } scheduleTerminalActionsRequest := management.ScheduleTerminalActionsRequest{ ActionDetails: management.InstallAndroidAppDetailsAsScheduleTerminalActionsRequestActionDetails(&installAndroidAppDetails), TerminalIds: []string{ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034", }, StoreId: common.PtrString(""), ScheduledAt: common.PtrString("2021-12-12T20:21:22-0100"), } // Make the request service := client.Management() req := service.TerminalActionsTerminalLevelApi.CreateTerminalActionInput().ScheduleTerminalActionsRequest(scheduleTerminalActionsRequest) res, httpRes, err := service.TerminalActionsTerminalLevelApi.CreateTerminalAction(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. json_request = { "terminalIds": [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], "storeId": "", "scheduledAt": "2021-12-12T20:21:22-0100", "actionDetails": { "type": "InstallAndroidApp", "appId": "ANDA422LZ223223K5F694GCCF732K8" } } result = adyen.management.terminal_actions_terminal_level_api.create_terminal_action(request=json_request) ``` #### Ruby ```rb # Adyen Ruby API Library v9.2.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment request_body = { :terminalIds => [ 'S1E-000150183300032', 'S1E-000150183300033', 'S1F2-000150183300034' ], :storeId => '', :scheduledAt => '2021-12-12T20:21:22-0100', :actionDetails => { :type => 'InstallAndroidApp', :appId => 'ANDA422LZ223223K5F694GCCF732K8' } } result = adyen.management.terminal_actions_terminal_level_api.create_terminal_action(request_body) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, ManagementAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request objects const installAndroidAppDetails: Types.management.InstallAndroidAppDetails = { appId: "ANDA422LZ223223K5F694GCCF732K8", type: Types.management.InstallAndroidAppDetails.TypeEnum.InstallAndroidApp }; const scheduleTerminalActionsRequest: Types.management.ScheduleTerminalActionsRequest = { actionDetails: installAndroidAppDetails, terminalIds: ["S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034"], storeId: "", scheduledAt: "2021-12-12T20:21:22-0100" }; // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalActionsTerminalLevelApi.createTerminalAction(scheduleTerminalActionsRequest); ``` **Uninstall a certificate** #### curl ```bash curl https://management-test.adyen.com/v3/terminals/scheduleActions \ -H 'content-type: application/json' \ -H 'x-API-key: ADYEN_API_KEY' \ -X POST \ -d '{ "terminalIds": [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], "storeId": "", "scheduledAt": "2021-12-12T20:21:22-0100", "actionDetails" : { "type" : "UninstallAndroidCertificate", "certificateId" : "ANDC422LZ223223K5F78NVN9SL4VPH" } }' ``` #### Java ```java // Adyen Java API Library v25.0.0 import com.adyen.Client; import com.adyen.enums.Environment; import com.adyen.model.management.*; import java.time.OffsetDateTime; import java.util.*; import com.adyen.service.management.*; Client client = new Client("ADYEN_API_KEY", Environment.TEST); // Request objects UninstallAndroidCertificateDetails uninstallAndroidCertificateDetails = new UninstallAndroidCertificateDetails() .certificateId("ANDC422LZ223223K5F78NVN9SL4VPH") .type(UninstallAndroidCertificateDetails.TypeEnum.UNINSTALLANDROIDCERTIFICATE); ScheduleTerminalActionsRequest scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest() .actionDetails(new ScheduleTerminalActionsRequestActionDetails(uninstallAndroidCertificateDetails)) .terminalIds(Arrays.asList("S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034")) .storeId("") .scheduledAt("2021-12-12T20:21:22-0100"); // Make the request TerminalActionsTerminalLevelApi service = new TerminalActionsTerminalLevelApi(client); ScheduleTerminalActionsResponse response = service.createTerminalAction(scheduleTerminalActionsRequest, null); ``` #### PHP ```php // Adyen PHP API Library v17.4.0 use Adyen\Client; use Adyen\Environment; use Adyen\Model\Management\ScheduleTerminalActionsRequestActionDetails; use Adyen\Model\Management\ScheduleTerminalActionsRequest; use Adyen\Service\Management\TerminalActionsTerminalLevelApi; $client = new Client(); $client->setXApiKey("ADYEN_API_KEY"); $client->setEnvironment(Environment::TEST); // Request objects $scheduleTerminalActionsRequestActionDetails = new ScheduleTerminalActionsRequestActionDetails(); $scheduleTerminalActionsRequestActionDetails ->setCertificateId("ANDC422LZ223223K5F78NVN9SL4VPH") ->setType("UninstallAndroidCertificate"); $scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest(); $scheduleTerminalActionsRequest ->setActionDetails($scheduleTerminalActionsRequestActionDetails) ->setTerminalIds(array("S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034")) ->setStoreId("") ->setScheduledAt("2021-12-12T20:21:22-0100"); // Make the request $service = new TerminalActionsTerminalLevelApi($client); $response = $service->createTerminalAction($scheduleTerminalActionsRequest); ``` #### C\# ```cs // Adyen .net API Library v14.3.0 using Adyen; using Environment = Adyen.Model.Environment; using Adyen.Model; using Adyen.Model.Management; using Adyen.Service.Management; var config = new Config() { XApiKey = "ADYEN_API_KEY", Environment = Environment.Test }; var client = new Client(config); // Fill in your request objects UninstallAndroidCertificateDetails uninstallAndroidCertificateDetails = new UninstallAndroidCertificateDetails { CertificateId = "ANDC422LZ223223K5F78NVN9SL4VPH", Type = UninstallAndroidCertificateDetails.TypeEnum.UninstallAndroidCertificate }; ScheduleTerminalActionsRequest scheduleTerminalActionsRequest = new ScheduleTerminalActionsRequest { ActionDetails = new ScheduleTerminalActionsRequestActionDetails(uninstallAndroidCertificateDetails), TerminalIds = { "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" }, StoreId = "", ScheduledAt = "2021-12-12T20:21:22-0100" }; // Make the request var service = new TerminalActionsTerminalLevelService(client); var response = service.CreateTerminalAction(scheduleTerminalActionsRequest); ``` #### NodeJS (JavaScript) ```js // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use const { Client, ManagementAPI } = require('@adyen/api-library'); // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request object const scheduleTerminalActionsRequest = { terminalIds: [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], storeId: "", scheduledAt: "2021-12-12T20:21:22-0100", actionDetails: { type: "UninstallAndroidCertificate", certificateId: "ANDC422LZ223223K5F78NVN9SL4VPH" } } // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalActionsTerminalLevelApi.createTerminalAction(scheduleTerminalActionsRequest); ``` #### Go ```go // Adyen Go API Library v9.2.0 import ( "context" "github.com/adyen/adyen-go-api-library/v9/src/common" "github.com/adyen/adyen-go-api-library/v9/src/adyen" "github.com/adyen/adyen-go-api-library/v9/src/management" ) client := adyen.NewClient(&common.Config{ ApiKey: "ADYEN_API_KEY", Environment: common.TestEnv, }) // Fill in your request objects uninstallAndroidCertificateDetails := management.UninstallAndroidCertificateDetails{ CertificateId: common.PtrString("ANDC422LZ223223K5F78NVN9SL4VPH"), Type: common.PtrString("UninstallAndroidCertificate"), } scheduleTerminalActionsRequest := management.ScheduleTerminalActionsRequest{ ActionDetails: management.UninstallAndroidCertificateDetailsAsScheduleTerminalActionsRequestActionDetails(&uninstallAndroidCertificateDetails), TerminalIds: []string{ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034", }, StoreId: common.PtrString(""), ScheduledAt: common.PtrString("2021-12-12T20:21:22-0100"), } // Make the request service := client.Management() req := service.TerminalActionsTerminalLevelApi.CreateTerminalActionInput().ScheduleTerminalActionsRequest(scheduleTerminalActionsRequest) res, httpRes, err := service.TerminalActionsTerminalLevelApi.CreateTerminalAction(context.Background(), req) ``` #### Python ```py # Adyen Python API Library v12.2.0 import Adyen adyen = Adyen.Adyen() adyen.client.xapikey = "ADYEN_API_KEY" adyen.client.platform = "test" # The environment to use library in. json_request = { "terminalIds": [ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], "storeId": "", "scheduledAt": "2021-12-12T20:21:22-0100", "actionDetails": { "type": "UninstallAndroidCertificate", "certificateId": "ANDC422LZ223223K5F78NVN9SL4VPH" } } result = adyen.management.terminal_actions_terminal_level_api.create_terminal_action(request=json_request) ``` #### Ruby ```rb # Adyen Ruby API Library v9.2.0 require "adyen-ruby-api-library" adyen = Adyen::Client.new adyen.api_key = 'ADYEN_API_KEY' adyen.env = :test # Set to "live" for live environment request_body = { :terminalIds => [ 'S1E-000150183300032', 'S1E-000150183300033', 'S1F2-000150183300034' ], :storeId => '', :scheduledAt => '2021-12-12T20:21:22-0100', :actionDetails => { :type => 'UninstallAndroidCertificate', :certificateId => 'ANDC422LZ223223K5F78NVN9SL4VPH' } } result = adyen.management.terminal_actions_terminal_level_api.create_terminal_action(request_body) ``` #### NodeJS (TypeScript) ```ts // Adyen Node API Library v16.2.0 // Require the parts of the module you want to use import { Client, ManagementAPI, Types } from "@adyen/api-library"; // Initialize the client object const client = new Client({apiKey: "ADYEN_API_KEY", environment: "TEST"}); // Create the request objects const uninstallAndroidCertificateDetails: Types.management.UninstallAndroidCertificateDetails = { certificateId: "ANDC422LZ223223K5F78NVN9SL4VPH", type: Types.management.UninstallAndroidCertificateDetails.TypeEnum.UninstallAndroidCertificate }; const scheduleTerminalActionsRequest: Types.management.ScheduleTerminalActionsRequest = { actionDetails: uninstallAndroidCertificateDetails, terminalIds: ["S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034"], storeId: "", scheduledAt: "2021-12-12T20:21:22-0100" }; // Make the request const managementAPI = new ManagementAPI(client); const response = managementAPI.TerminalActionsTerminalLevelApi.createTerminalAction(scheduleTerminalActionsRequest); ``` We first validate the list of terminals. If the list is correct, we try to send the action details to the terminals. 2. If you receive a **422** validation [error response](/errors), check the `invalidFields` array for the details, fix the errors, and send the planning request again. For each error, the `InvalidField.message` explains what is wrong: * `InvalidTerminal`: The terminal ID is incorrect. * `CompanyHasNoPermissionToThisTerminal`: The terminal belongs to a company that the API credential that was used for the request doesn't have access to. * `TerminalIsNotFromStore`: The terminal is not assigned to the store that was specified in the request. The following example shows validating the list of terminals failed because two of the three terminal IDs are incorrect. **Response—Errors in list of terminals** ```json { "type": "https://docs.adyen.com/errors/validation", "title": "Invalid parameters", "status": 422, "invalidFields": [ { "InvalidField": { "name": "terminalIds", "value": "S1E-000150183300030", "message": "InvalidTerminal" } }, { "InvalidField": { "name": "terminalIds", "value": "S1E-000150183300031", "message": "InvalidTerminal" } } ], "errorCode": "33_008" } ``` 3. If there are no errors with the validation of the terminal IDs, check whether the action was planned: * [totalScheduled](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#responses-200-totalScheduled): The number of terminals for which planning the action succeeded. This doesn't mean the action has happened yet. * [totalErrors](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#responses-200-totalErrors): The number of terminals for which planning the action failed. For example, due to connection problems. * [items](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions#responses-200-items): A list with the unique `terminalId` and the unique action `id` for each terminal that the action was scheduled for. The action `id` starts with **TRAC**. You can use it to [retrieve the details](#terminal-action-details) of an action. For example, whether the action was carried out successfully. **Response—no errors** ```json { "actionDetails":{ "type":"InstallAndroidApp", "appId":"ANDA422LZ223223K5F694GCCF732K8" }, "scheduledAt":"2021-12-12T20:21:22-0100", "storeId":"", "items":[ { "id":"TRAC422T2223223K5GFMQHM6WQ4KB6", "terminalId":"S1E-000150183300032" }, { "id":"TRAC4224X22338VQ5GD4CQJCQT5PC2", "terminalId":"S1E-000150183300033" }, { "id":"TRAC4224Z223223K5GD89RLBWQ6CWT", "terminalId":"S1F2-000150183300034" } ], "terminalIds":[ "S1E-000150183300032", "S1E-000150183300033", "S1F2-000150183300034" ], "terminalsWithErrors": {}, "totalScheduled":3, "totalErrors":0 } ``` ## Get terminal action details After the terminal action is planned, you can retrieve the details of that action to check if the action has been carried out. This is only possible for terminal actions that you planned, not for actions that were planned by us. To get details of a terminal action: 1. Make a GET [/companies/{companyId}/terminalActions/{actionId}](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)) request specifying the `id` of the planned terminal action from the [/terminals/scheduleActions](https://docs.adyen.com/api-explorer/Management/latest/post/terminals/scheduleActions) response. **Get action details by ID** ```bash curl https://management-test.adyen.com/v3/companies/terminalActions/TRAC4224Z223223K5GD89RLBWQ6CWT \ -H 'x-API-key: ADYEN_API_KEY' \ -X GET ``` 2. In the response, see the `status` to learn if the action has been carried out. These are the full response details: | Response parameter | Description | | ------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | | [actionType](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-actionType) | The type of terminal action: **InstallAndroidApp**, **UninstallAndroidApp**, **InstallAndroidCertificate**, or **UninstallAndroidCertificate**. | | [config](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-config) | Technical information about the terminal action. | | [confirmedAt](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-confirmedAt) | The date and time when the terminal returns the status of the action. For example, whether the action succeeded, failed, or was cancelled. | | [id](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-id) | The unique identifier of the terminal action. | | [result](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-result) | The result message in case the `status` of the action is **successful**, **failed**, or **cancelled**. For example, **Version apk0 installed** or **Failed**. | | [scheduledAt](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-scheduledAt) | The date and time when you scheduled the action to happen. | | [status](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-status) | The status of the terminal action: **pending**, **successful**, **failed**, or **cancelled**. | | [terminalId](https://docs.adyen.com/api-explorer/Management/latest/get/companies/\(companyId\)/terminalActions/\(actionId\)#responses-200-terminalId) | The unique identifier of the terminal that the action applies to. | **Response — Android certificate is installed** ```json { "actionType":"InstallAndroidCertificate", "config":"{\"certificates\":\"5dff6b...\"}", "id": "TRAC4224Z221223K4GD5855BJZ24M5", "confirmedAt":"2022-06-27T17:44:54+0200", "result":"Ok", "scheduledAt":"2022-06-27T15:44:07+0200", "status":"successful", "terminalId":"S1F2-000150183300034" } ``` **Response — Install Android app is pending** ```json { "actionType": "InstallAndroidApp", "config": "{\"apps\":\"5dff6...\"}", "id": "TRAC4224Z223223K5GD89RLBWQ6CWT", "scheduledAt": "2022-07-21T16:08:55+02:00", "status": "pending", "terminalId": "S1E-000150183300033" } ``` ## See also * [Specifications and testing of apps for Android terminals](/point-of-sale/android-terminals/app-requirements) * [Upload apps and certificates](/point-of-sale/android-terminals/deploy-apps/upload) * [Deploy apps based on profiles](/point-of-sale/android-terminals/deploy-apps/profiles) * [Manage app deployment using the Customer Area](/point-of-sale/android-terminals/deploy-apps/schedule)