Manage AUT environments and custom fields with the API
Choose an application under test (AUT), manage its environments and project
association, then define a custom field and set its value on a test case.
Build your integration in a non-production account and project.
1. Set up authentication and permissions
Use your tenant host, https://<tenant>.katalon.io, without a trailing slash.
Authenticate with HTTP Basic: empty username, API key as the password. See
Authenticate with the v2 API.
Keep the key in a secret store and do not enable shell tracing (set -x).
Send x-account-id (account UUID) and x-project-id (numeric project ID)
on every request in this guide. The account must own the target records and
the project must be accessible. Definitions are account-scoped; the project
header does not make them project-specific. It selects the manual picker's
project and is required for association writes. Optional x-organization-id
takes a numeric organization ID consistent with that context.
Your API key uses its owner's permissions; headers do not grant access.
| Operation | Required permission |
|---|---|
| Manual AUT/environment picker | Execution:Read |
| List/read AUTs, environments, associations; TrueTest enrichment | Aut:Read |
| Create AUT or project association | Aut:Create |
| Update AUT/association; create, update or archive environment | Aut:Update |
| Archive AUT or unlink association | Aut:Delete |
| List/read definitions or check capacity | CustomField:Read |
| Create / update / archive definition | CustomField:Create / CustomField:Update / CustomField:Delete |
| Update an existing test case's values | TestCase:Update plus repository access |
| Read an existing test case's values | TestCase:Read |
Set KATALON_API_HOST, KATALON_API_KEY, KATALON_ACCOUNT_ID, and
KATALON_PROJECT_ID from your existing setup. This Bash helper passes the key
to curl through standard input, not process arguments. Escape " and \
in the key as \" and \\ for curl's configuration format.
katalon_request() {
: "${KATALON_API_KEY:?Missing API key}"
printf 'user = ":%s"\n' "${KATALON_API_KEY}" |
curl --config - --silent --show-error --fail-with-body \
--header "x-account-id: ${KATALON_ACCOUNT_ID:?Missing account UUID}" \
--header "x-project-id: ${KATALON_PROJECT_ID:?Missing project ID}" \
"$@"
}2. Find a selectable AUT and environment
Start with the manual execution picker, GET /v2/admin/manual/auts, to find
available AUT and environment IDs. This request does not start a run.
katalon_request --get "${KATALON_API_HOST}/v2/admin/manual/auts" \
--data-urlencode 'query={"filters":[],"sorts":[{"field":"id","desc":false}],"offset":0,"limit":50}'The response contains data and total. Each AUT has an id, name, and
environments with id, name, and url. Save the AUT and environment IDs
separately. The picker shows project-associated AUTs in this context. TrueTest
readiness and tracking can hide environments from the picker. Use the lists
below for a full inventory.
All Admin lists here use JSON in the query parameter, not ?id=123 or
page/size. Use offset, limit (at most 50 returned per page), and stable
sorts to page through results; total is the matching count.
3. Choose or create an AUT, then manage environments
List AUTs with GET /v2/admin/auts using the same query shape. Choose an
existing AUT or create one:
katalon_request --request POST "${KATALON_API_HOST}/v2/admin/auts" \
--header 'Content-Type: application/json' \
--data '{"name":"Sample application","type":"WEB_APPLICATION","isDefault":"false"}'Create returns 200 with {"data":{...}}; save data.id as AUT_ID.
AUT creation names are nonblank, at most 30 characters. AUT and environment
write inputs use strings "true"/"false" for isDefault, not JSON booleans.
List that AUT's environments:
katalon_request --get "${KATALON_API_HOST}/v2/admin/environments" \
--data-urlencode 'query={"filters":[{"field":"autId","operator":"EQ","value":'"${AUT_ID:?Missing AUT ID}"'}],"offset":0,"limit":50}'Create an environment with an application endpoint, without embedded credentials
or secret query parameters. Replace 123 with your AUT_ID. The create input's
autId is a string:
katalon_request --request POST "${KATALON_API_HOST}/v2/admin/environments" \
--header 'Content-Type: application/json' \
--data '{"name":"Staging","value":"https://example.com","autId":"123","isDefault":"false"}'Save returned data.id as ENVIRONMENT_ID. On both POST and PUT, environment
names must be nonblank and at most 30 characters. Longer names return 400
environment.name.exceed.max-length. value is nonblank, at most 255 characters.
Creation also contacts TrueTest, even when the parent AUT is not TrueTest-enabled;
a new environment can already have a TrueTest counterpart that blocks its DELETE.
| Lifecycle operation | Method and path | Input / behavior |
|---|---|---|
| Update AUT | PUT /v2/admin/auts/{AUT_ID} | Include name and all intended optional settings; omission clears description/type and resets default. For an already TrueTest-enabled AUT, preserve truetestEnabled:"true"; this API cannot disable TrueTest. |
| Update environment | PUT /v2/admin/environments/{ENVIRONMENT_ID} | Include nonblank name (at most 30 characters) and full value, for example {"name":"Staging updated","value":"https://example.com","isDefault":"false"}. Omitted description/label are cleared and default resets. Do not send autId; updates cannot reparent it. |
| Archive environment | DELETE /v2/admin/environments/{ENVIRONMENT_ID} | Conditional archive; TrueTest restrictions apply (see cleanup below). |
| Archive AUT | DELETE /v2/admin/auts/{AUT_ID} | Conditional archive; not allowed for a TrueTest-enabled AUT. |
These PUTs are not sparse patches. Setting an AUT as default clears other
account AUT defaults; an environment default clears other defaults in its AUT.
Environment writes omit advanced TrueTest configuration, so an update may not
keep those settings.
Updates return 200 with data; successful archives return 204 with no body.
Read any known Admin ID
For AUTs, environments, project associations and custom-field definitions, filter
the corresponding collection by numeric id:
katalon_request --get "${KATALON_API_HOST}/v2/admin/environments" \
--data-urlencode 'query={"filters":[{"field":"id","operator":"EQ","value":'"${ENVIRONMENT_ID:?Missing environment ID}"'}],"offset":0,"limit":1}'The response remains {"data":[...],"total":1}, or an empty list if unavailable.
There is no ordinary GET /auts/{id}, /environments/{id},
/aut-projects/{id}, or /custom-fields/{id} detail route.
GET /v2/admin/auts/truetest/{AUT_ID} and
GET /v2/admin/environments/{ENVIRONMENT_ID}/truetest are separate TrueTest
enrichment reads, not replacements: inspect their success flag even on 200.
4. Link the AUT to a project and configure its repository
List GET /v2/admin/aut-projects with both an autId and a projectId
filter. The association list is account-scoped, not narrowed by the project
header. The query has this shape, where 123 is your AUT and 789 is your
context project:
{"filters":[{"field":"autId","operator":"EQ","value":123},{"field":"projectId","operator":"EQ","value":789}],"offset":0,"limit":50}katalon_request --get "${KATALON_API_HOST}/v2/admin/aut-projects" \
--data-urlencode 'query={"filters":[{"field":"autId","operator":"EQ","value":'"${AUT_ID}"'},{"field":"projectId","operator":"EQ","value":'"${KATALON_PROJECT_ID}"'}],"offset":0,"limit":50}'If no active link exists, create one. Here autId is a JSON number; the
project comes from x-project-id, not the body:
katalon_request --request POST "${KATALON_API_HOST}/v2/admin/aut-projects" \
--header 'Content-Type: application/json' \
--data "{\"autId\":${AUT_ID}}"Save returned data.id as AUT_PROJECT_LINK_ID, distinct from both AUT and
project IDs. Duplicate active links are rejected rather than recreated.
For a link without a configured script repository, attach one. Save the
repository ID as REPO_ID. The body has this shape, where 789 is your
context project and 321 is the repository:
{"truetestExtras":{"repoConfigs":{"projectId":789,"testProjectId":321}}}katalon_request --request PUT \
"${KATALON_API_HOST}/v2/admin/aut-projects/${AUT_PROJECT_LINK_ID:?Missing link ID}" \
--header 'Content-Type: application/json' \
--data "{\"truetestExtras\":{\"repoConfigs\":{\"projectId\":${KATALON_PROJECT_ID},\"testProjectId\":${REPO_ID:?Missing repository ID}}}}"projectId must match the selected link and request's project context.
testProjectId must be an existing, accessible repository ID in that
project, not a URL, AUT ID or link ID. See repository discovery in
Manage test cases and suites
and Know which ID is which.
This attaches a repository once; it cannot replace a different repository already
configured. It also marks the referenced repository as autonomous. Do not send
an empty object or arbitrary extras.
Success is 200 with data; the response need not echo this configuration.
The project must not already have an active TrueTest association with a different
AUT. Creating the local link does not guarantee repository attachment will succeed.
5. Define and maintain a test-case custom field
List definitions with GET /v2/admin/custom-fields. Read a known numeric
definition ID using the collection's id EQ query from step 3.
Check capacity
before creating:
katalon_request "${KATALON_API_HOST}/v2/admin/custom-fields/validate"204 means capacity is available, with no body. This does not validate a candidate
definition or reserve capacity; limits vary by account. Create a TEXT definition:
katalon_request --request POST "${KATALON_API_HOST}/v2/admin/custom-fields" \
--header 'Content-Type: application/json' \
--data '{"fieldName":"review_note","fieldKey":"review_note","fieldType":"TEXT","objectTypes":["TEST_CASE"],"displayLabel":"Review note","isRequired":false}'Creation returns 200 with data; save numeric data.id as
CUSTOM_FIELD_DEFINITION_ID. Names, keys and labels
must be nonblank; the key must be unique among active account definitions and
cannot be testing_framework. Labels are at most 50 characters.
To change the label, PUT /v2/admin/custom-fields/{CUSTOM_FIELD_DEFINITION_ID}:
{"displayLabel":"Review note (updated)","objectTypes":["TEST_CASE"]}Include the existing objectTypes: omission clears that scope. The field key
cannot be changed here. Omit fieldOptions unless editing options; a supplied
list replaces the full option list, and [] removes all options. Include
every retained option's numeric id; assignments below instead use its UUID.
Changing a type or removing options is not a safe automatic migration of values.
6. Set a value on an existing test case
New definitions and options must be synchronized to Test Management before
assignment. Synchronization is asynchronous and has no guaranteed propagation
time. Assigning a definition that is not yet available returns a validation
error. Use an existing case and its repository in the same project. CREATE does
not save custom-field values: create the case with the
test-management guide
first, then set values with UPDATE.
Send the following JSON with Content-Type: application/json to the existing
POST /v2/tm/repositories/test-entities?async=false&publishStrategy=NORMAL.
Replace 321 with your REPO_ID, 654 with the test-case ID, and 987 with
your CUSTOM_FIELD_DEFINITION_ID, the ID returned by
POST /v2/admin/custom-fields:
[{"testProjectId":321,"testEntities":[{"action":"UPDATE","resource":"TEST_CASE","data":{"id":654,"customizableFields":[{"definitionId":987,"values":[{"textValue":"Ready for review"}]}]}}]}]The property is data.customizableFields, not customFieldValues.
The operation returns a Test Management result array, not an Admin data envelope.
Use the value property matching your definition's type:
| Supported type | Example values |
|---|---|
TEXT | [{"textValue":"Ready for review"}] |
NUMBER | [{"numberValue":1}] |
CHECKBOX | [{"booleanValue":false}] |
DATE | [{"dateValue":"2026-10-23"}] |
DROPDOWN_SINGLE | [{"optionValueUuid":"11111111-1111-4111-8111-111111111111"}] |
DROPDOWN_MULTIPLE | One {"optionValueUuid":"..."} object per selected option |
For dropdowns, use actual fieldOptions[].uuid values returned by Admin, not
numeric option IDs or labels. Submit one value for a single-valued field.
Read the assigned value
Use List custom-field values with the case's project context.
Requires the TestCase:Read permission.
Set TEST_CASE_ID to the case you updated:
katalon_request --get \
--data-urlencode "q=entityId==${TEST_CASE_ID:?Missing test case ID} and entityType==TEST_CASE" \
"${KATALON_API_HOST}/v2/tm/customizable-fields"Use textual and, not a semicolon, between comparisons.
--data-urlencode encodes spaces and comparisons; a semicolon can return a 400 missing-selector error.
The response contains a content array of typed values, such as:
{"content":[{"definitionId":987,"definitionType":"TEXT","textValue":"Ready for review"}],"totalElements":1,"totalPages":1,"pageable":{"pageNumber":0,"pageSize":100}}Match definitionId and its typed value to your UPDATE.
Dropdown values use optionValueUuid, not labels or numeric option IDs.
GET /v2/tm/test-cases/{id} returns the Feature Area and Test Type system fields, not these account custom-field values.
See Read assigned custom-field values for selectors and pages.
Admin also defines TAG and URL types.
Nonempty values for these types are not supported end to end through this flow.
7. Clear values and archive only when allowed
To clear the selected case's field, repeat the UPDATE with
{"definitionId":987,"values":[]} inside customizableFields.
An outer customizableFields:[] is a no-op, not a clear-all operation.
Repeat the value-list read to confirm that no value items remain for the selected field.
If no other fields have values, the response contains content: [].
| Cleanup | Request / restriction |
|---|---|
| Archive definition | DELETE /v2/admin/custom-fields/{CUSTOM_FIELD_DEFINITION_ID}. Clear its value links on all using entities first; in-use definitions are rejected. This archives the definition, not the case. |
| Unlink project | DELETE /v2/admin/aut-projects/{AUT_PROJECT_LINK_ID}. Archives the association and requests downstream unlink; an active TrueTest association can reject it. |
| Archive environment | DELETE /v2/admin/environments/{ENVIRONMENT_ID}. Even a just-created environment can return 400 cannot.delete.env.enabled.truetest when its TrueTest counterpart is found. This does not delete that counterpart. |
| Archive AUT last | DELETE /v2/admin/auts/{AUT_ID}. Rejected for TrueTest-enabled AUTs; when allowed, also archives associated active environments and links. |
Successful DELETEs return 204 without a body. Some archives are rejected, as
shown above. When AUT deletion is allowed, it archives the AUT's environments
and links too, even if direct environment deletion was blocked.
Do not delete a whole AUT unless you intend that cascade. Writes can affect TrueTest as well as
local records, and a failed write is not always rolled back. Inspect errors
before retrying. To verify an archive, filter the collection by ID and expect
empty data.
Updated 17 days ago