This document describes Kotlin DSL API. General information about Kotlin DSL can be found in the online documentation.

To get DSL API documentation in the IDE, run the mvn -U dependency:sources command.

To read the documentation without a connection to TeamCity server, download the zip.

How DSL works

When versioned settings in Kotlin format are enabled, TeamCity commits the current settings to the specified settings repository.

When a new commit is detected in a settings repository, TeamCity runs the DSL scripts found in this commit and applies the result to the settings the on TeamCity server or reports errors on the 'Versioned Settings' tab in the administration area of the project.

Kotlin DSL API versions

There are 3 DSL API versions: v10, v2017_2, and v2018_1. The DSL API version corresponds to the minimal TeamCity version where this API is supported, so v10 can be used in TeamCity 10.x, 2017.1.x, 2017.2.x, and newer; v2017_2 can be used in TeamCity 2017.2.x and newer, and so on.

When versioned settings are enabled, TeamCity uses the latest supported DSL API version. You can get settings with the older DSL API version using the 'Download settings in Kotlin format' action in the project administration area.

A settings repository can contain settings in different DSL API versions, but the settings defined by a single settings.kts script should use the same DSL API version (they won't compile otherwise).

Kotlin settings structure

For each project, TeamCity generates a directory called after the project id containing a settings.kts script which defines the project. Build configurations, templates, and VCS roots are defined as Kotlin objects with the TeamCity id as a name, so you can quickly find a Kotlin definition of a TeamCity entity using the 'Navigate to Symbol' action in the IDE.

Most of the classes in the DSL API correspond to the entities in the TeamCity administration UI. The main classes are:

Portable Kotlin settings

TeamCity 2018.1 provides an option to generate portable DSL scripts. When this option is enabled, TeamCity generates a single .teamcity/settings.kts script which defines a project hierarchy. All ids in portable settings are relative to the project where versioned settings were enabled and TeamCity prepends the id of this project to relative ids the during scripts execution. Because of that the same settings repository can be used several times on the same TeamCity server.

Identifiers in Kotlin DSL

TeamCity maintains the state of its entities with the help of identifiers.

Projects, buildTypes, templates, and VCS roots have mandatory id and uuid properties (id is called extId in DSL API v10).

Id is shown in the UI, it is used in URLs and in parameter references. If you change the id, you need to update all the references to it accordingly.

Uuid allows changing the id of the entity and to preserve its state in TeamCity. If you change uuid, TeamCity will treat the entity as a new one and the data associated with the old entity will be lost.

Id and uuid of the entity must be unique among entities of the same kind (buildTypes and templates share the same id namespace). TeamCity detects duplicate ids during DSL execution and reports them as errors. To avoid id collisions, you can use some prefix for all ids in your project. DSL API version v2017_2 supports new entities creation via the UI, in this case TeamCity will assign unique ids to the created entity.

In DSL API version v2018_1 uuid can be omitted, in this case TeamCity infers it from the id. This allows to reuse the same settings on the same TeamCity server. TeamCity treats the change of the id in the entity without uuid as a new entity creation. All data associated with the old entity (e.g. build history, commit graph, investigations) will be lost. To recover from that one can change the id back to the old value. For lost build history TeamCity provides a dedicated action in the build configuration admin area which allows to attach a build history of a deleted build configuration to the current one.

BuildType, template, and project parts (e.g. build steps and project features) also have ids. These ids must be unique within an entity (e.g. within a single buildType).

A build part id is used to disable a part of the build settings (e.g. to disable a build step) and to override some settings inherited from a template. These abilities are important when settings are edited in the UI but less important for Kotlin DSL. Instead of disabling a part of the build, you can simply remove or comment out its Kotlin. Unlike removing a part of the settings in the UI, the change in Kotlin can easily be reverted via the version control system. Templates provide means of reusing settings, but in Kotlin you can achieve the same by defining a base class for your builds or by defining a function which adds commonly used settings.

If your buildType is not based on a template, you can omit all ids in build parts, in this case unique ids will be generated automatically.

If you want to disable a part of the build settings instead of removing it, there are 2 ways to do that in Kotlin DSL:

In template-based buildTypes, build part ids must be specified. A build part with same id as in the template overrides the part of the template settings. To disable a part of the template settings add its id to the set of disabled settings in a buildType.

Project feature ids can be used by TeamCity plugins for locating their settings, so they cannot be omitted in Kotlin DSL and should not be changed. The easiest way to specify them is to switch to v2018_1 DSL API version and to edit project settings in the UI.


TeamCity settings format changes from release to release. Most of the time, TeamCity can automatically convert settings produced by an older DSL version to a newer format. TeamCity uses the configs version specified in the settings.kts to determine which settings transformations should be made. If the version is missing, then settings are treated as up-to-date and no transformations are performed. If some settings were converted, then TeamCity shows a health report explaining how to update the DSL to a newer format. Once all settings are up-to-date, TeamCity shows a report asking to update the configs version in settings.kts. More information regarding upgrading DSL between major releases can be found in the documentation.

Editing settings in UI

If your code uses DSL API version v2017_2+, TeamCity allows editing the settings in the UI. If you didn't change the Kotlin scripts generated by TeamCity, then the settings will be updated in-place. If you made some changes, then TeamCity will generate a so-called UI patch script. For example, if you change a buildType in the UI, the patch script will be located in the <project id>/patches/buildTypes/<buildType uuid>.kts file, or patches/buildTypes/<relative buildType id>.kts in portable DSL settings. To simplify settings maintenance, it is recommended to update your code according to the UI patch script and then remove the UI patch script.

The UI patch script performs one of the following actions:

Existing entities are modified in such a way that changes can be made both in the UI and in Kotlin code. For example, you can change a buildType name in the code and change its description in UI and TeamCity will merge both changes. But if the name is changed both in the UI and in Kotlin code, then the error will be reported and you will have to choose which name to keep. To ensure that UI changes do not silently overwrite settings specified in a regular code, the UI patch script checks that the settings have expected values and only then updates them. For example, a script changing a buildType name looks like this:

changeBuildType("1234") {
    check(name == "Old Name") {
        "Unexpected name: '$name'"
    name = "New Name"

If the buildType with uuid "1234" produced by DSL doesn't have the name "Old Name", then the check will produce an error and the UI patch won't be applied.

Settings validation

The settings using the DSL API version v2017_2+ are validated during DSL execution on the TeamCity server. You can also perform validation locally by running the mvn org.jetbrains.teamcity:teamcity-configs-maven-plugin:generate command. Validation checks that the mandatory properties are specified, for example a build step like this:

buildType {
    steps {
        exec {

will produce a validation error saying that the mandatory path property is not specified. This is similar to the checks performed by TeamCity when you create a new build step in the UI.

You can also extend the validation in a way relevant for your setup. To do that, you need to override the validate() method. For example, the following class adds a custom validation to Git VCS roots:

open class MyGit() : GitVcsRoot() {
    constructor(init: MyGit.() -> Unit): this() {

    override fun validate(consumer: ErrorConsumer) {
        super.validate(consumer) //perform basic validation

        url?.let {
            if (it.startsWith("git://") || it.startsWith("http://")) {
                consumer.consumePropertyError("url", "Insecure protocol, please use https or ssh instead")

        authMethod?.let {
            if (it is AuthMethod.CustomPrivateKey || it is AuthMethod.DefaultPrivateKey) {
                consumer.consumePropertyError("authMethod", "Prohibited authentication method, please use 'uploadedKey' instead")



Defines the settings DSL for TeamCity 10+


Contains build features provided by plugins


Contains build steps provided by plugins


Contains failure conditions provided by plugins


Contains project features provided by plugins


Contains build triggers provided by plugins


Contains VCS roots provided by plugins


Defines the settings DSL for TeamCity 2017.2+


Contains build features provided by plugins


Contains build steps provided by plugins


Contains failure conditions provided by plugins


Contains project features provided by plugins


Contains build triggers provided by plugins


Contains VCS roots provided by plugins


Defines the settings DSL for TeamCity 2018.1+


Contains build features provided by plugins


Contains build steps provided by plugins


Contains failure conditions provided by plugins


Contains project features provided by plugins


Contains build triggers provided by plugins


Contains VCS roots provided by plugins


All Types