---
title: Adding a Preview Version when the Last Version was Preview
llmstxt: true
---

When the last api-version in your TypeSpec spec is a preview, adding a new preview version is simply replacing the latest preview version with a new preview version.

## The Simplest Case: No Stable api-versions

If your spec is in preview and has not ever had a stable api-version, then there is no need to have versioning decoration in your TypeSpec at all:

- Change the api-version to match the new api-version
  ```diff lang=tsp
  enum Versions {
    @previewVersion
  - `2025-12-01-preview`
  + `2026-01-01-preview`
  }
  ```
- Remove any versioning decorators
- Make any API changes for the new preview, there is no need to use versioning decoration for this.
- Update the example folder name to match the new api-version

  ```bash
  > mv examples/2025-12-01-preview examples/2026-01-01-preview
  ```

- Update the `api-version` in examples to match the new api-version (search and replace api-version in the examples folder)

  ```diff lang=json
  {
    "title": "Create a Widget",
    "operationId": "Widgets_Create",
    "parameters": {
  -   "api-version": "2025-12-01-preview",
  +   "api-version": "2026-01-01-preview",
    }
  }
  ```

- If you **do not need** to retain the OpenAPI for older previews (see [Should I Retain the OpenAPI for an Old Preview API](./01-about-versioning.md#should-i-retain-the-openapi-for-an-old-preview-api-arm-only) if you are not sure).
  - Remove the associated OpenAPI file and examples

    ```bash
    > rm -r 2025-12-01-preview
    ```

  - Remove any references to the old version from README.md

- Update the README.md to include the new api-version

:::tip
If you wish to remove the OpenAPI files for the old preview version, do so in a **separate follow-up PR** after this PR merges. See [Should I Retain the OpenAPI for an Old Preview API](./01-about-versioning.md#should-i-retain-the-openapi-for-an-old-preview-api-arm-only).
:::

## The General Case: One or more Stable Versions Exist

If there are stable versions before the latest preview version, then you will need to adapt the latest preview version and its decoration for the new preview version.

This includes the following steps:

### Making Changes to your TypeSpec spec

- Rename the latest preview version to match the new preview version, in all instances in the spec
  - In VS Code, highlight the version name and select `rename symbol` from the context menu to rename the version throughout your spec
  - In any editor, search and replace the latest preview version in the spec with the new preview version
- Update the version value of this version to match the new api-version string, for example:

  ```diff lang=tsp
  enum Versions {
    @previewVersion
  - `2025-12-01-preview`,
  + `2026-01-01-preview`,
  }
  ```

- The new preview version should already be the _last version_ of the versions enum, also ensure it is decorated with `@previewVersion`
- Update any mention in documentation of the old api-version to use the new api-version

- Make changes to the API description based on how the API has changed from the last preview version to the new preview version (if it has changed)
  - If any type that was introduced in the latest preview is _not_ in the new preview, simply delete the type

    ```diff lang=tsp
    - @added(Versions.`2026-01-01-preview`)
    - model Foo {}
    ```

  - If any type was removed in the latest preview but **appears** in the new preview, remove the decorator

    ```diff lang=tsp
    - @removed(Versions.`2026-01-01-preview`)
      model Bar {}
    ```

  - Similarly, if there is any change from the latest preview that does not apply to the new preview version, reverse the decorator.

    ```diff lang=tsp
    - @renamedFrom(Versions.`2026-01-01-preview`, "oldProp")
    - newProp: string;
    + oldProp: string;
    ```

    ```diff lang=tsp
    - @typeChangedFrom(Versions.`2026-01-01-preview`, string)
    - changedProp: int32;
    + changedProp: string;
    ```

    ```diff lang=tsp
    - @madeOptional(Versions.`2026-01-01-preview`)
    - requiredProp?: string;
    + requiredProp: string;
    ```

    ```diff lang=tsp
    - @madeRequired(Versions.`2026-01-01-preview`)
    - requiredProp: string;
    + requiredProp?: string;
    ```

  - If a property uses the `@removed`/`@added`/`@renamedFrom` pattern to change decoration or a default value in the latest preview (see [Adding Decoration to an Existing Type](./06-evolving-apis.md#adding-decoration-to-an-existing-type)), reverse the pattern by removing both the old and new properties and restoring the original property. For example, if a property added a default value in preview:

    ```diff lang=tsp
      model Employee {
    -   @removed(Versions.`2026-01-01-preview`)
    -   @renamedFrom(Versions.`2026-01-01-preview`, "level")
    -   oldLevel: int32;
    -
    -   @added(Versions.`2026-01-01-preview`)
    -   level: int32 = 1;
    +   level: int32;
      }
    ```

    Here, `level` had a default value of `1` added in the preview. To reverse this, remove both properties (the renamed "old" version and the "new" version with the default) and restore the original property without the default.

  - If an operation uses the `@removed`/`@added`/`@renamedFrom` pattern to convert from synchronous to asynchronous in the latest preview, reverse the pattern by removing both operations and restoring the original synchronous operation. For example (ARM):

    ```diff lang=tsp
      @armResourceOperations
      interface Employees {
    -   @removed(Versions.`2026-01-01-preview`)
    -   @renamedFrom(Versions.`2026-01-01-preview`, "createOrUpdate")
    -   @sharedRoute
    -   createOrUpdateV1 is ArmResourceCreateOrReplaceSync<Employee>;
    -
    -   @added(Versions.`2026-01-01-preview`)
    -   @sharedRoute
    -   createOrUpdate is ArmResourceCreateOrReplaceAsync<Employee>;
    +   createOrUpdate is ArmResourceCreateOrReplaceSync<Employee>;
      }
    ```

    Similarly for data-plane:

    ```diff lang=tsp
      interface Widgets {
    -   @removed(Versions.`2026-01-01-preview`)
    -   @renamedFrom(Versions.`2026-01-01-preview`, "createOrReplaceWidget")
    -   @sharedRoute
    -   createOrReplaceWidgetV1 is Operations.ResourceCreateOrReplace<Widget>;
    -
    -   @added(Versions.`2026-01-01-preview`)
    -   getWidgetOperationStatus is Operations.GetResourceOperationStatus<Widget, never>;
    -
    -   @added(Versions.`2026-01-01-preview`)
    -   @sharedRoute
    -   @pollingOperation(Widgets.getWidgetOperationStatus)
    -   createOrReplaceWidget is Operations.LongRunningResourceCreateOrReplace<Widget>;
    +   createOrReplaceWidget is Operations.ResourceCreateOrReplace<Widget>;
      }
    ```

  - If any other types are removed in the new preview (unlikely, because these would be breaking changes from the previous stable and require a breaking change review) mark these with an `@removed` decorator referencing the new version

    ```diff lang=tsp
    + @removed(Versions.`2026-01-01-preview`)
      model Bar {}
    ```

  - If any types are added, renamed, or otherwise modified in the new version, mark them with the appropriate versioning decorator.

- Change the name of the `examples` version folder for the latest preview to match the new preview version

  ```bash
  > mv examples/2025-12-01-preview examples/2026-01-01-preview
  ```

- Ensure that examples use the correct api-version (search and replace the api-version for all examples in the folder)

  ```diff lang=json
  {
    "title": "Create a Widget",
    "operationId": "Widgets_Create",
    "parameters": {
  -   "api-version": "2025-12-01-preview",
  +   "api-version": "2026-01-01-preview",
    }
  }
  ```

- Add and modify examples to match the API changes

### Preparing a PR into the azure-rest-api-specs repo

- Navigate to the root directory of the repo in your local fork or clone

  ```bash
  C:\repos\azure-rest-api-specs\specifications\myRp > cd \repos\azure-rest-api-specs
  C:\repos\azure-rest-api-specs >
  ```

- Pull the latest version from the repo

  ```bash
  C:\repos\azure-rest-api-specs > git fetch upstream main
  C:\repos\azure-rest-api-specs > git pull upstream main
  ```

- Reinstall dependencies

  ```bash
  C:\repos\azure-rest-api-specs > npm ci
  ```

- Compile your spec

  ```bash
  C:\repos\azure-rest-api-specs > cd specification\myRpShortname\resource-manager\Microsoft.MyRP\MyService
  C:\repos\azure-rest-api-specs\specification\myRpShortname\resource-manager\Microsoft.MyRP\MyService > npx tsp compile .
  ```

- update README.md to include a new entry for the new preview version and make it the default tag.

:::tip
If you wish to remove the OpenAPI files for the old preview version, do so in a **separate follow-up PR** after this PR merges. See [Should I Retain the OpenAPI for an Old Preview API](./01-about-versioning.md#should-i-retain-the-openapi-for-an-old-preview-api-arm-only).
:::

- If you _do not_ need the older preview version (see [Should I Retain the OpenAPI for an Old Preview API](./01-about-versioning.md#should-i-retain-the-openapi-for-an-old-preview-api-arm-only) if you are not sure), in a separate PR after this PR is merged, remove the OpenAPI directory for that version and update the `README.md` file to remove all references to the old preview version files.

  ```bash
  C:\repos\azure-rest-api-specs\specification\myRpShortname\resource-manager\Microsoft.MyRP\  > rm -r 2025-12-01-preview
  ```
