> 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.

# Landscapes

A landscape is the primary workspace in IcePanel. It holds a complete C4 architecture model including all objects, connections, diagrams, flows, and versions.

---

## What a landscape contains

Each landscape is versioned. All models like objects, connections, diagrams, flows, and domains live inside a [version](/core-concepts/versions) of a landscape.

When you create a landscape, IcePanel automatically creates an initial `latest` version that you can modify immediately.

Create a landscape:

### Request

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

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

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

async function main() {
    const client = new IcePanelClient({
        apiKey: "YOUR_API_KEY_HERE",
    });
    await client.organizations.landscapes.create({
        organizationId: "organizationId",
        name: "string",
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.organizations.types.OrganizationLandscapeCreateRequest;

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

        client.organizations().landscapes().create(
            OrganizationLandscapeCreateRequest
                .builder()
                .organizationId("organizationId")
                .name("string")
                .build()
        );
    }
}
```

```python
import requests

url = "https://api.icepanel.io/v1/organizations/organizationId/landscapes"

payload = { "name": "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/organizations/organizationId/landscapes"

	payload := strings.NewReader("{\n  \"name\": \"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/organizations/organizationId/landscapes");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-Key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

The response returns both the `landscape` and the initial `version` objects.

List all landscapes in your organization:

### Request

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

```curl
curl https://api.icepanel.io/v1/organizations/organizationId/landscapes \
     -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.organizations.landscapes.list({
        organizationId: "organizationId",
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.organizations.types.OrganizationLandscapesListRequest;

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

        client.organizations().landscapes().list(
            OrganizationLandscapesListRequest
                .builder()
                .organizationId("organizationId")
                .build()
        );
    }
}
```

```python
import requests

url = "https://api.icepanel.io/v1/organizations/organizationId/landscapes"

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/organizations/organizationId/landscapes"

	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/organizations/organizationId/landscapes");
var request = new RestRequest(Method.GET);
request.AddHeader("X-API-Key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

---

## URL patterns

Landscape endpoints are available in two forms.

**Organization-scoped** (includes org context, useful when you have the org ID in scope):

```
GET /organizations/{organizationId}/landscapes/{landscapeId}
```

**Landscape-scoped** (shorter, useful when you already know the landscape ID):

```
GET /landscapes/{landscapeId}
```

All version-scoped resources (model objects, diagrams, flows, etc.) use only the landscape-scoped pattern:

```
GET /landscapes/{landscapeId}/versions/{versionId}/model/objects
```

You can also specify `latest` as a shorthand for getting the latest version:

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

---

## Duplicate vs copy

IcePanel provides two operations for replicating a landscape:

| Operation     | Description                                                                                                                                                             |
| ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| **Duplicate** | Creates a full copy of the landscape within the same organization, including all versions and model content                                                             |
| **Copy**      | Copies the model content of a specific version into a different target landscape. This is useful for merging two models or seeding a new landscape from an existing one |

Duplicate a landscape:

### Request

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

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

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

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

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.types.LandscapeDuplicateRequest;
import com.icepanel.types.LandscapeRequired;

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

        client.landscapes().duplicate(
            LandscapeDuplicateRequest
                .builder()
                .landscapeId("landscapeId")
                .body(
                    LandscapeRequired
                        .builder()
                        .name("string")
                        .build()
                )
                .build()
        );
    }
}
```

```python
import requests

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

payload = { "name": "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/duplicate"

	payload := strings.NewReader("{\n  \"name\": \"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/duplicate");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-Key", "<apiKey>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"name\": \"string\"\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

Copy to another landscape:

### Request

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

```curl
curl -X POST "https://api.icepanel.io/v1/landscapes/landscapeId/copy?targetLandscapeId=targetLandscapeId" \
     -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.landscapes.copy({
        landscapeId: "landscapeId",
        targetLandscapeId: "targetLandscapeId",
    });
}
main();

```

```java
package com.example.usage;

import com.icepanel.IcePanelClient;
import com.icepanel.types.LandscapeCopyRequest;

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

        client.landscapes().copy(
            LandscapeCopyRequest
                .builder()
                .landscapeId("landscapeId")
                .targetLandscapeId("targetLandscapeId")
                .build()
        );
    }
}
```

```python
import requests

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

querystring = {"targetLandscapeId":"targetLandscapeId"}

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

response = requests.post(url, headers=headers, params=querystring)

print(response.json())
```

```go
package main

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

func main() {

	url := "https://api.icepanel.io/v1/landscapes/landscapeId/copy?targetLandscapeId=targetLandscapeId"

	req, _ := http.NewRequest("POST", 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/copy?targetLandscapeId=targetLandscapeId");
var request = new RestRequest(Method.POST);
request.AddHeader("X-API-Key", "<apiKey>");
IRestResponse response = client.Execute(request);
```

---

## Related concepts

* [Versions](/core-concepts/versions)
* [Model Objects](/core-concepts/model-objects)
* [Diagrams](/core-concepts/diagrams)