Update Plan (Appium2)
This endpoint updates an existing Appium2 test plan.
Most fields are optional. Only non-null fields are copied to the existing plan. However, mobile app fields should be handled carefully: if androidMobileApp or iosMobileApp is sent as null or omitted, the related mobile app selection may be cleared by the current backend flow.
Endpoint Information
- URL: {gateway-url}/plans/{planId}
- Method: PUT
- Authentication: Required (Bearer Token)
Request Headers
Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer token used for authentication. Example: Bearer <your_access_token> |
Content-Type | Yes | Must be application/json. |
X-Company-Id | Yes | The company ID used by the gateway to authorize and route the request. |
Path Variables
Parameter | Type | Required | Description |
|---|---|---|---|
planId | Long | Yes | The ID of the test plan. Must be a positive number. |
Request Body
{
"planName": "Updated Appium2 Test Plan",
"groupPlan": false,
"description": "Updated description for the Appium2 test plan.",
"type": "APPIUM",
"enabled": true,
"deleted": false,
"planParallelTestLimit": 5,
"projectId": 913,
"userId": 1,
"failedTestRetryCount": 2,
"maxExecutionTime": 3600,
"testRunType": "CROSS",
"screenShotType": "YES",
"videoEnabled": true,
"uninstallApp": false,
"clearAppData": false,
"androidMobileApp": 134,
"iosMobileApp": null,
"isSigned": true,
"alertsEnabled": true,
"testDispatchMethodType": "ONE_BY_ONE",
"forceSave": false
}Request Body Parameters
Field | Type | Required | Description |
|---|---|---|---|
planName | String | No | Updated name of the test plan. |
groupPlan | Boolean | No | Indicates whether the plan is a group plan. |
description | String | No | Updated description of the test plan. |
type | String | No | Plan type. For Appium2 plans, send APPIUM. |
enabled | Boolean | No | Indicates whether the plan is enabled. |
deleted | Boolean | No | Indicates whether the plan is marked as deleted. |
planParallelTestLimit | Integer | No | Maximum parallel test limit for this plan. |
period | Object | No | Period configuration to update together with the plan, if needed. |
projectId | Long | No | Project ID related to the plan. |
userId | Long | No | User ID related to the plan. |
failedTestRetryCount | Integer | No | Number of retries for failed tests. |
maxExecutionTime | Integer | No | Maximum execution time in seconds. |
testRunType | String | No | Test run mode. Supported values: CROSS, SEQUENCE. |
screenShotType | String | No | Screenshot behavior. Supported values: YES, NO, ONLY_FAILURE. |
videoEnabled | Boolean | No | Indicates whether video recording is enabled. |
uninstallApp | Boolean | No | Indicates whether the mobile app should be uninstalled after execution. |
clearAppData | Boolean | No | Indicates whether app data should be cleared before execution. |
androidMobileApp | Long | No | Android mobile app ID. Send the current ID again if you want to keep the selected Android app. |
iosMobileApp | Long | No | iOS mobile app ID. Send the current ID again if you want to keep the selected iOS app. |
isSigned | Boolean | No | Indicates whether the selected iOS app is signed. |
alertsEnabled | Boolean | No | Indicates whether alerts are enabled for this plan. |
parentId | Long | No | Parent plan ID, if this is a child plan. |
planEnvironmentsRequest | Array of objects | No | Appium2 environment list to upsert together with the plan. |
testDispatchMethodType | String | No | Dispatch strategy. Supported values: ONE_BY_ONE, ALL_IN_ONE. |
forceSave | Boolean | No | If true, skips Appium2 environment registration validation while updating planEnvironmentsRequest. |
Important Notes
- This endpoint updates the plan using PUT.
- Most null fields are ignored during update.
- androidMobileApp and iosMobileApp are exceptions in practice: send the current app ID again if the app selection should be preserved.
- For Appium2 group plans, the number of selected environments cannot be greater than planParallelTestLimit.
- If testDispatchMethodType is ALL_IN_ONE, planParallelTestLimit must not be greater than 1, failedTestRetryCount must be 0, and only one environment is allowed.
- If planEnvironmentsRequest is provided and forceSave is not true, environments are validated against registered healthy DevicePark devices.
Response Body
{
"data": {
"id": 316,
"planName": "Updated Appium2 Test Plan",
"groupPlan": false,
"description": "Updated description for the Appium2 test plan.",
"enabled": true,
"deleted": false,
"planParallelTestLimit": 5,
"periodId": 318,
"projectId": 913,
"projectName": "Demo",
"projectTestFramework": "APPIUM2",
"userId": 1,
"companyId": 2,
"failedTestRetryCount": 2,
"maxExecutionTime": 3600,
"testRunType": "CROSS",
"screenShotType": "YES",
"videoEnabled": true,
"uninstallApp": false,
"clearAppData": false,
"iosMobileApp": null,
"androidMobileApp": {
"id": 134,
"mobileAppName": "Demo.apk",
"mobileAppHash": "Demo",
"mobileAppMetadata": "{}",
"operatingSystem": "ANDROID",
"createdAt": "2026-08-18T12:08:41.165927056Z"
},
"isSigned": true,
"testFileType": "APPIUM_GAUGE",
"testRunnerTool": "MAVEN",
"testDispatchMethodType": "ONE_BY_ONE",
"alertsEnabled": true,
"gridType": "TESTINIUM_ENTERPRISE",
"isParent": false,
"parentId": null
}
}Response Fields
Field | Type | Description |
|---|---|---|
data | Object | Updated test plan payload. |
data.id | Long | Unique identifier of the test plan. |
data.planName | String | Name of the test plan. |
data.groupPlan | Boolean | Indicates whether the plan is a group plan. |
data.description | String | Description of the test plan. |
data.enabled | Boolean | Indicates whether the plan is enabled. |
data.deleted | Boolean | Indicates whether the plan is marked as deleted. |
data.planParallelTestLimit | Integer | Maximum parallel test limit for this plan. |
data.periodId | Long | ID of the period configuration. |
data.projectId | Long | ID of the project that owns the plan. |
data.projectName | String | Name of the project. |
data.projectTestFramework | String | Project framework. For Appium2 plans, this value is APPIUM2. |
data.userId | Long | ID of the user associated with the plan. |
data.companyId | Long | ID of the company that owns the plan. |
data.failedTestRetryCount | Integer | Number of retries for failed tests. |
data.maxExecutionTime | Integer | Maximum execution time in seconds. |
data.testRunType | String | Test run mode. |
data.screenShotType | String | Screenshot behavior. |
data.videoEnabled | Boolean | Indicates whether video recording is enabled. |
data.uninstallApp | Boolean | Indicates whether the mobile app should be uninstalled after execution. |
data.clearAppData | Boolean | Indicates whether app data should be cleared before execution. |
data.iosMobileApp | Object | Selected iOS mobile app summary, if available. |
data.androidMobileApp | Object | Selected Android mobile app summary, if available. |
data.isSigned | Boolean | Indicates whether the selected iOS app is signed. |
data.testFileType | String | Type of test files used by the project. |
data.testRunnerTool | String | Test runner tool used by the project. |
data.testDispatchMethodType | String | Dispatch strategy. |
data.alertsEnabled | Boolean | Indicates whether alerts are enabled for this plan. |
data.gridType | String | Grid type used for execution. |
data.isParent | Boolean | Indicates whether this plan is a parent plan. |
data.parentId | Long | Parent plan ID, if this is a child plan. |
Error Response Format
{
"instance": "/plans/999999",
"status": 404,
"title": "Not Found",
"type": "https://errors.testinium.com/exception",
"timestamp": "2026-08-18T12:08:41.165927056Z",
"errorType": "EXCEPTION",
"errors": {
"code": 10003,
"message": "Plan with id 999999 not found!"
}
}HTTP Error Codes
HTTP Code | Error Message | Description |
|---|---|---|
400 | Bad Request | Request body is invalid, malformed, contains invalid enum values, or Appium2 validation failed. |
401 | Unauthorized | Authentication is missing or invalid. |
403 | Forbidden | User does not have permission for this operation or company. |
404 | Not Found | Plan or selected mobile app was not found. |
405 | Method Not Allowed | The endpoint was called with an unsupported HTTP method. |
422 | Unprocessable Entity | Appium2 environment registration confirmation is required. |
500 | Internal Server Error | An unexpected error occurred on the server side. |
503 | Service Unavailable | Project service or another downstream service is unavailable. |
Application Error Codes
Code | HTTP Status | Source | Description |
|---|---|---|---|
10003 | 404 | Project | Test plan not found. |
10008 | 422 | Project | One or more Appium2 environments are not registered. |
10009 | 404 | Project | Mobile app not found. |
10012 | 400 | Project | For Appium2 group plans, environment count cannot be greater than planParallelTestLimit. |
10001 | 401 | Gateway | Authentication is required. |
10002 | 401 | Gateway | Token is invalid or cannot be verified. |
10003 | 403 | Gateway | Authorization failed for the requested resource. |
10004 | 400 | Gateway | A required header, such as X-Company-Id, is missing or invalid. |
10008 | 503 | Gateway | Routed service is unavailable. |
10007 | 503 | Common | Downstream service is unavailable. |
20005 | 400 | Common Validation | Request body or path variable validation failed. |
20007 | 400 | Common Validation | Invalid enum value. |
20008 | 400 | Common Validation | Path variable type is invalid. |
20009 | 405 | Common Validation | HTTP method is not supported. |
Example Request
curl --location --request PUT '{gateway-url}/plans/{planId}' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer <your_access_token>' \
--header 'X-Company-Id: <company_id>' \
--data '{
"planName": "Updated Appium2 Test Plan",
"groupPlan": false,
"description": "Updated description for the Appium2 test plan.",
"type": "APPIUM",
"enabled": true,
"deleted": false,
"planParallelTestLimit": 5,
"projectId": 913,
"userId": 1,
"failedTestRetryCount": 2,
"maxExecutionTime": 3600,
"testRunType": "CROSS",
"screenShotType": "YES",
"videoEnabled": true,
"uninstallApp": false,
"clearAppData": false,
"androidMobileApp": 134,
"iosMobileApp": null,
"isSigned": true,
"alertsEnabled": true,
"testDispatchMethodType": "ONE_BY_ONE",
"forceSave": false
}'