> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developer.icepanel.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developer.icepanel.io/_mcp/server.

# Versions

IcePanel uses a versioning system to let you maintain a live working model while also capturing point-in-time snapshots for communication and history.

---

## The `latest` version

Every [landscape](/core-concepts/landscapes) has a special version with the ID `latest`. This is the live version where you make changes through the IcePanel UI or the API.

Use `latest` in any version-scoped endpoint:

```
GET /landscapes/{landscapeId}/versions/latest/model/objects
POST /landscapes/{landscapeId}/versions/latest/model/objects
```

---

## Version snapshots

A version snapshot is an immutable copy of the model at a point in time. Snapshots are useful for:

* Marking a release or milestone
* Sharing a stable view of the architecture with stakeholders
* Reverting to a known-good state

Create a snapshot from the current state of `latest`:

### Request

POST [https://api.icepanel.io/v1/landscapes/\{landscapeId}/versions](https://api.icepanel.io/v1/landscapes/\{landscapeId}/versions)

```curl
curl -X POST https://api.icepanel.io/v1/landscapes/landscapeId/versions \
     -H "X-API-Key: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "modelHandleId": "string",
  "name": "string",
  "notes": "string"
}'
```

```typescript
import { IcePanelClient } from "@icepanel/sdk";

async function main() {
    const client = new IcePanelClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.versions.create({
        landscapeId: "landscapeId",
        body: {
            modelHandleId: "string",
            name: "string",
            notes: "string",
        },
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.core.OptionalNullable;
import com.icepanel.types.VersionCreateRequest;
import com.icepanel.types.VersionRequired;

public class Example {
    public static void main(String[] args) {
        IcePanelClient client = IcePanelClient
            .builder()
            .apiKey("YOUR_API_KEY_HERE")
            .build();

        client.versions().create(
            VersionCreateRequest
                .builder()
                .landscapeId("landscapeId")
                .body(
                    VersionRequired
                        .builder()
                        .name("string")
                        .notes("string")
                        .modelHandleId(
                            OptionalNullable.of("string")
                        )
                        .build()
                )
                .build()
        );
    }
}
```

```python
import requests

url = "https://api.icepanel.io/v1/landscapes/landscapeId/versions"

payload = {
    "modelHandleId": "string",
    "name": "string",
    "notes": "string"
}
headers = {
    "X-API-Key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.icepanel.io/v1/landscapes/landscapeId/versions"

	payload := strings.NewReader("{\n  \"modelHandleId\": \"string\",\n  \"name\": \"string\",\n  \"notes\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-Key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```csharp
using RestSharp;

var client = new RestClient("https://api.icepanel.io/v1/landscapes/landscapeId/versions");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-Key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"modelHandleId\": \"string\",\n  \"name\": \"string\",\n  \"notes\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

Required fields:

| Field           | Description                                         |
| --------------- | --------------------------------------------------- |
| `name`          | Version name, e.g. `v2.4.0` or `Q3 2025`            |
| `notes`         | Description of what changed in this version         |
| `modelHandleId` | The `handleId` of the root model object to snapshot |

Once created, a snapshot version is read-only. Its ID is a system-generated string (not `latest`).

List all versions for a landscape:

### Request

GET [https://api.icepanel.io/v1/landscapes/\{landscapeId}/versions](https://api.icepanel.io/v1/landscapes/\{landscapeId}/versions)

```curl
curl https://api.icepanel.io/v1/landscapes/landscapeId/versions \
     -H "X-API-Key: <apiKey>"
```

```typescript
import { IcePanelClient } from "@icepanel/sdk";

async function main() {
    const client = new IcePanelClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.versions.list({
        landscapeId: "landscapeId",
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.types.VersionsListRequest;

public class Example {
    public static void main(String[] args) {
        IcePanelClient client = IcePanelClient
            .builder()
            .apiKey("YOUR_API_KEY_HERE")
            .build();

        client.versions().list(
            VersionsListRequest
                .builder()
                .landscapeId("landscapeId")
                .build()
        );
    }
}
```

```python
import requests

url = "https://api.icepanel.io/v1/landscapes/landscapeId/versions"

headers = {"X-API-Key": "<apiKey>"}

response = requests.get(url, headers=headers)

print(response.json())
```

```go
package main

import (
	"fmt"
	"net/http"
	"io"
)

func main() {

	url := "https://api.icepanel.io/v1/landscapes/landscapeId/versions"

	req, _ := http.NewRequest("GET", url, nil)

	req.Header.Add("X-API-Key", "<apiKey>")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```csharp
using RestSharp;

var client = new RestClient("https://api.icepanel.io/v1/landscapes/landscapeId/versions");
var request = new RestRequest(Method.GET);
request.AddHeader("X-API-Key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

---

## Version reverts

Roll back a landscape to the state captured in a previous snapshot:

### Request

POST [https://api.icepanel.io/v1/landscapes/\{landscapeId}/version/reverts](https://api.icepanel.io/v1/landscapes/\{landscapeId}/version/reverts)

```curl
curl -X POST https://api.icepanel.io/v1/landscapes/landscapeId/version/reverts \
     -H "X-API-Key: <apiKey>" \
     -H "Content-Type: application/json" \
     -d '{
  "notes": "string",
  "versionId": "string"
}'
```

```typescript
import { IcePanelClient } from "@icepanel/sdk";

async function main() {
    const client = new IcePanelClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.versions.reverts.create({
        landscapeId: "landscapeId",
        body: {
            notes: "string",
            versionId: "string",
        },
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.types.VersionRevertRequired;
import com.icepanel.versions.types.VersionRevertCreateRequest;

public class Example {
    public static void main(String[] args) {
        IcePanelClient client = IcePanelClient
            .builder()
            .apiKey("YOUR_API_KEY_HERE")
            .build();

        client.versions().reverts().create(
            VersionRevertCreateRequest
                .builder()
                .landscapeId("landscapeId")
                .body(
                    VersionRevertRequired
                        .builder()
                        .notes("string")
                        .versionId("string")
                        .build()
                )
                .build()
        );
    }
}
```

```python
import requests

url = "https://api.icepanel.io/v1/landscapes/landscapeId/version/reverts"

payload = {
    "notes": "string",
    "versionId": "string"
}
headers = {
    "X-API-Key": "<apiKey>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.icepanel.io/v1/landscapes/landscapeId/version/reverts"

	payload := strings.NewReader("{\n  \"notes\": \"string\",\n  \"versionId\": \"string\"\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("X-API-Key", "<apiKey>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```csharp
using RestSharp;

var client = new RestClient("https://api.icepanel.io/v1/landscapes/landscapeId/version/reverts");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-Key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"notes\": \"string\",\n  \"versionId\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

Required fields:

| Field       | Description               |
| ----------- | ------------------------- |
| `versionId` | The snapshot to revert to |
| `notes`     | Reason for the revert     |

A revert creates a new entry in the revert history and replaces the `latest` version with the snapshot state. The snapshot itself is not modified.

---

## Related concepts

* [Landscapes](/core-concepts/landscapes)
* [Model Objects](/core-concepts/model-objects)