diff --git a/fern/concepts/diagrams.mdx b/fern/concepts/diagrams.mdx new file mode 100644 index 0000000..5783b18 --- /dev/null +++ b/fern/concepts/diagrams.mdx @@ -0,0 +1,23 @@ +# Diagrams + +Diagrams are C4 visualisations of your model. They are views onto the underlying model [objects](/core-concepts/model-objects) and [connections](/core-concepts/model-connections). The model data exists independently of any diagram, and the same object can appear in multiple diagrams. + +--- + +## Diagram types + +Each diagram type maps to a C4 level of abstraction: + +| Type | C4 Level | Description | +| --- | --- | --- | +| `context-diagram` | Level 1 | Shows a `system` in the context of its actors and external systems | +| `app-diagram` | Level 2 | Shows the `app` and `store` containers inside a `system` | +| `component-diagram` | Level 3 | Shows the `component` objects inside an `app` or `store` | + +--- + +## Related concepts + +- [Model Objects](/core-concepts/model-objects) +- [Flows](/core-concepts/flows) +- [Versions](/core-concepts/versions) diff --git a/fern/concepts/domains.mdx b/fern/concepts/domains.mdx new file mode 100644 index 0000000..9253917 --- /dev/null +++ b/fern/concepts/domains.mdx @@ -0,0 +1,34 @@ +# Domains + +Domains are named groupings that organise [model objects](/core-concepts/model-objects) into bounded contexts. They map closely to the Domain-Driven Design (DDD). + +--- + +## What a domain is + +Every model object in a version belongs to exactly one domain. Domains provide a way to segment a large architecture either by business unit (e.g., `Payments`) or by team ownership (e.g., `platform`). + +--- + +## Creating domains + +Create a domain in a version: + + + +--- + +## Filtering model objects by domain + +Use the `GET` endpoint with query parameter `?filter[domainId]={domainId}` to filter objects. + + + +This is useful for extracting a bounded-context slice of the architecture for reports or external tools. + +--- + +## Related concepts + +- [Model Objects](/core-concepts/model-objects) +- [Model Connections](/core-concepts/model-connections) diff --git a/fern/concepts/flows.mdx b/fern/concepts/flows.mdx new file mode 100644 index 0000000..2048e07 --- /dev/null +++ b/fern/concepts/flows.mdx @@ -0,0 +1,19 @@ +# Flows + +Flows are step-by-step sequences that trace a path through your architecture model. Useful for documenting user journeys, request paths, data flows, or any scenario where ordering and directionality matter. + +--- + +## What a flow is + +A flow lives inside a [diagram](/core-concepts/diagrams) and consists of an ordered list of **steps**. Each step identifies a model [object](/core-concepts/model-objects) or [connection](/core-concepts/model-connections) that participates at that point in the sequence. When viewing a flow in the IcePanel UI, the relevant objects and connections are highlighted in order. + +Flows are distinct from model connections: a connection represents a static relationship between two objects, while a flow represents a dynamic sequence that may traverse many objects and connections. + +--- + +## Related concepts + +- [Model Objects](/core-concepts/model-objects) +- [Model Connections](/core-concepts/model-connections) +- [Diagrams](/core-concepts/diagrams) diff --git a/fern/concepts/landscapes.mdx b/fern/concepts/landscapes.mdx new file mode 100644 index 0000000..fd73a31 --- /dev/null +++ b/fern/concepts/landscapes.mdx @@ -0,0 +1,75 @@ +# 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: + + + +The response returns both the `landscape` and the initial `version` objects. + +List all landscapes in your organization: + + + +--- + +## 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: + + + +Copy to another landscape: + + + +--- + +## Related concepts + +- [Versions](/core-concepts/versions) +- [Model Objects](/core-concepts/model-objects) +- [Diagrams](/core-concepts/diagrams) diff --git a/fern/concepts/model-connections.mdx b/fern/concepts/model-connections.mdx new file mode 100644 index 0000000..710643f --- /dev/null +++ b/fern/concepts/model-connections.mdx @@ -0,0 +1,47 @@ +# Model Connections + +Model connections are the edges of the model objects in your architecture. They represent relationships, dependencies, API calls, data flows, or any meaningful interaction between two model objects. + +--- + +## Creating connections + + + +--- + +## Filtering connections + +The `GET /model/connections` endpoint supports filtering: + +| Query parameter | Description | +| --- | --- | +| `filter[originId]` | Connections starting from a specific object | +| `filter[targetId]` | Connections ending at a specific object | +| `filter[viaId]` | Connections passing through a specific object | +| `filter[direction]` | `outgoing` or `bidirectional` | +| `filter[status]` | Status lifecycle value | +| `filter[tagIds][]` | One or more tag IDs | +| `filter[technologyIds][]` | One or more technology IDs | +| `filter[labels][key]` | Label key-value pair | +| `filter[name]` | Partial name match | +| `filter[linked]` | `true` to return only connections with at least one link | + +--- + +## Status lifecycle + +Connections share the same four-state lifecycle as [model objects](/core-concepts/model-objects): + +| Status | Description | +| --- | --- | +| `live` | Active dependency or relationship | +| `future` | Planned but not yet implemented | +| `deprecated` | In use but being phased out | +| `removed` | Retired, kept for historical reference | + +--- + +## Related concepts + +- [Model Objects](/core-concepts/model-objects) diff --git a/fern/concepts/model-objects.mdx b/fern/concepts/model-objects.mdx new file mode 100644 index 0000000..bd32e8c --- /dev/null +++ b/fern/concepts/model-objects.mdx @@ -0,0 +1,93 @@ +# Model Objects + +Model objects are the nodes in your architecture graph. They represent the actors, systems, services, and components that make up your software architecture. + +--- + +## Object types + +IcePanel uses the C4 model's levels of abstraction. Each object type maps to a C4 level: + +| Type | C4 Level | Description | +| --- | --- | --- | +| `root` | — | The root node of every [domain](/core-concepts/domains). There is exactly one per domain. All top-level systems and actors are children of the root. | +| `actor` | Level 1 | A person or external role that interacts with your architecture (e.g. "Customer", "Admin") | +| `system` | Level 1 | A top-level software system (e.g. "IcePanel") | +| `group` | Level 1 | A visual grouping (e.g. "Worker Pool", "Subnet") | +| `app` | Level 2 | A deployable unit (container) inside a system: a service, web app, mobile app, or queue | +| `store` | Level 2 | A persistent data store inside a system: a database, blob store, or cache | +| `component` | Level 3 | An internal building block inside an `app` or `store` | + +--- + +## The parent–child hierarchy + +Model objects form a tree. Every object except `root` has a `parentId` pointing to its parent: + +``` +root +├── actor: Customer +├── system: Payment Service +│ ├── app: API Gateway +│ │ ├── component: Auth Middleware +│ │ └── component: Rate Limiter +│ ├── app: Payment Processor +│ └── store: Transactions DB +└── system: Auth Platform (external) +``` + +--- + +## Creating objects + +To create a new object, specify the `landscapeId` and either the `versionId` or `latest`: + + +--- + +## Filtering objects + +To find the root object (required as `parentId` when creating top-level objects), use the query parameter `?filter[type]=root` + + + +The `GET /model/objects` endpoint supports the following filters: + +| Query parameter | Description | +| --- | --- | +| `filter[type]` | Object type | +| `filter[status]` | Status lifecycle value | +| `filter[parentId]` | Direct parent ID | +| `filter[domainId]` | Domain ID | +| `filter[external]` | `true` / `false` | +| `filter[tagIds][]` | One or more tag IDs | +| `filter[teamIds][]` | One or more team IDs | +| `filter[technologyIds][]` | One or more technology IDs | +| `filter[labels][key]` | Label key-value pair | +| `filter[name]` | Partial name match | +| `filter[linked]` | `true` to return only objects with at least one link | + +--- + +## Status lifecycle + +Objects and connections share a four-state lifecycle representing their architectural status: + +``` +live → deprecated → removed → future +``` + +| Status | Description | +| --- | --- | +| `live` | Current, active element | +| `future` | Planned but not yet built | +| `deprecated` | Still in use but being phased out | +| `removed` | Retired, kept for historical reference | + +Use the `filter[status]` query parameter to retrieve only objects with a given status. + +--- + +## Related concepts + +- [Model Connections](/core-concepts/model-connections) diff --git a/fern/concepts/organizations.mdx b/fern/concepts/organizations.mdx new file mode 100644 index 0000000..1574f10 --- /dev/null +++ b/fern/concepts/organizations.mdx @@ -0,0 +1,16 @@ +# Organizations + +An organization is the top-level model in IcePanel. It owns all landscapes, manages billing, and controls who has access. + +--- + +Every API key and every landscape belongs to exactly one organization. The `organizationId` is the first path parameter you'll need for most operations. + + + +--- + +## Related concepts + +- [Landscapes](/core-concepts/landscapes) +- [Versions](/core-concepts/versions) diff --git a/fern/concepts/overview.mdx b/fern/concepts/overview.mdx new file mode 100644 index 0000000..292b064 --- /dev/null +++ b/fern/concepts/overview.mdx @@ -0,0 +1,98 @@ +--- +title: Core Concepts +description: Understand the IcePanel data model before building integrations +--- + +The IcePanel API is built around a set of concepts called the **Data Model** that you'll see throughout every endpoint. + +--- + +## Key concepts + +**[Organization](/core-concepts/organizations)** +The top-level model for access control. All landscapes and users belong to an organization. + +**[Landscape](/core-concepts/landscapes)** +A self-contained model workspace (like a repository). An organization can have multiple landscapes for different products or teams. + +**[Version](/core-concepts/versions)** +A snapshot of a landscape's model. The `latest` version is the live editable version. Numbered versions are immutable snapshots created at meaningful points in time. All model data is scoped to a version. + +**[Domain](/core-concepts/domains)** +A bounded context that groups related model objects. Every model object belongs to exactly one domain. + +**[Model (Object)](/core-concepts/model-objects)** +A node in the architecture graph. Can be a `system`, `app`, `component`, `store`, `actor`, `group`, or `root`. Objects form a parent–child hierarchy and can carry tags, technology associations, and custom labels. + +**[Model (Connection)](/core-concepts/model-connections)** +A defined relationship between two model objects. Represents a dependency, data flow, or API call. + +**[Diagram](/core-concepts/diagrams)** +A view onto the model. The underlying model objects and connections exist independently of any diagram. + +**[Flow](/core-concepts/flows)** +A step-by-step sequence that traces a path through model objects and connections. Useful for documenting user journeys, request paths, or data flows. + +--- + +## Data Model hierarchy + +``` +Organization +├── Team +└── Landscape + └── Version + ├── Domain + ├── Model (Object) + │ └── Model Objects Children (Recursive) + ├── Model (Connection) + ├── Flow + ├── Comment + ├── Draft + └── Share Link +``` + +Everything beneath a version is **version-scoped**. When you read or write model objects, connections, diagrams, flows, tags, or domains, you always specify both a `landscapeId` and a `versionId`: + +``` +/landscapes/{landscapeId}/versions/{versionId}/model/objects +/landscapes/{landscapeId}/versions/{versionId}/diagrams +/landscapes/{landscapeId}/versions/{versionId}/flows +``` + +Use `latest` to select the live editable version. Use a version ID (e.g. `xqD4yXmqukb1LKaMAAUL`) to select an immutable snapshot. + +--- + +## What to learn next + + + + Where all landscapes and users belong to an organization. + + + Your C4 model workspace. Create, duplicate, and manage landscapes across your organization. + + + Snapshots and the live `latest` version. Understand how version scoping works across the API. + + + Bounded contexts that group model objects. + + diff --git a/fern/concepts/versions.mdx b/fern/concepts/versions.mdx new file mode 100644 index 0000000..bb2c7d8 --- /dev/null +++ b/fern/concepts/versions.mdx @@ -0,0 +1,68 @@ +# 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`: + + + +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: + + + +--- + +## Version reverts + +Roll back a landscape to the state captured in a previous snapshot: + + + +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) diff --git a/fern/docs.yml b/fern/docs.yml index 7794091..4cc5cde 100644 --- a/fern/docs.yml +++ b/fern/docs.yml @@ -11,7 +11,7 @@ default-language: typescript experimental: ai-examples: false -logo: +logo: href: / dark: assets/logo-dark.svg light: assets/logo-light.svg @@ -22,13 +22,13 @@ colors: light: "#346DDB" dark: "#346DDB" background: - light: "#f3f4f6" + light: "#f3f4f6" dark: "#1b1d20" typography: headingsFont: name: IBM Plex Sans - paths: + paths: - path: fonts/IBMPlexSans-Bold.ttf weight: 700 style: normal @@ -37,29 +37,75 @@ typography: path: fonts/IBMPlexSans-Regular.ttf style: normal +tabs: + developer_guide: + display-name: Developer Guide + icon: book + core_concepts: + display-name: Core Concepts + icon: sitemap + api_reference: + display-name: API Reference + icon: puzzle + navigation: - - section: Introduction - contents: - - page: Getting Started - path: ./introduction/getting-started.mdx - - page: Guides - path: ./introduction/guides.mdx - - page: Use Cases - path: ./introduction/use-cases.mdx - - page: Rate Limits - path: ./introduction/rate-limits.mdx - - api: API Reference - snippets: - typescript: '@icepanel/sdk' - java: 'com.icepanel:sdk' - audiences: - - public + - tab: developer_guide + layout: + - section: Getting Started + contents: + - page: Introduction + path: ./introduction/what-is-icepanel.mdx + - page: Quickstart + path: ./introduction/quickstart.mdx + - page: Rate limits + path: ./introduction/rate-limits.mdx + + - section: How-to Guides + contents: + - page: Create model objects + path: ./guides/create-objects.mdx + - page: Export objects and relationships + path: ./guides/export-objects.mdx + - page: Update model descriptions + path: ./guides/update-descriptions.mdx + - page: Create landscape versions + path: ./guides/create-versions.mdx + + - tab: core_concepts + layout: + - page: Overview + path: ./concepts/overview.mdx + - page: Organizations + path: ./concepts/organizations.mdx + - page: Landscapes + path: ./concepts/landscapes.mdx + - page: Versions + path: ./concepts/versions.mdx + - page: Domains + path: ./concepts/domains.mdx + - page: Model Objects + path: ./concepts/model-objects.mdx + - page: Model Connections + path: ./concepts/model-connections.mdx + - page: Diagrams + path: ./concepts/diagrams.mdx + - page: Flows + path: ./concepts/flows.mdx + + - tab: api_reference + layout: + - api: API Reference + snippets: + typescript: '@icepanel/sdk' + java: 'com.icepanel:sdk' + audiences: + - public -navbar-links: +navbar-links: - type: filled text: "Sign up" href: "https://app.icepanel.io/user/sign-up" - - type: minimal + - type: minimal text: "Log in" href: "https://app.icepanel.io" diff --git a/fern/guides/create-objects.mdx b/fern/guides/create-objects.mdx new file mode 100644 index 0000000..0530671 --- /dev/null +++ b/fern/guides/create-objects.mdx @@ -0,0 +1,60 @@ +--- +title: Create model objects +description: Add new objects to your landscape. +--- + +This guide shows how to create new objects in your landscape model. Useful for automatically filling out your model from another source. + +## Prerequisites + +- [IcePanel account](https://app.icepanel.io/user/sign-up) +- [API key](https://app.icepanel.io) + +```bash +export ICEPANEL_API_KEY='your-api-key' +export ICEPANEL_ORGANIZATION_ID='your-organization-id' +``` + +## Steps + + + + Get all landscapes in your organization and select a landscape ID: + + + + Note the `id` of the landscape: + + ```bash + export ICEPANEL_LANDSCAPE_ID='your-landscape-id' + ``` + + + + Call a `GET` request with query parameter `?filter[type]=root` to find the root model object. Your landscape may have multiple root model objects if you use domains. + + + + Note the `id` from the response. This is the `parentId` for any top-level objects you create. + + + + Create a new model object as a child of the root: + + + + + +Below is a list of different objects you can create. + +### Object types + +| Type | Description | +| --- | --- | +| `root` | A root object of a landscape. | +| `system` | A top-level system or bounded context | +| `app` | An application or service within a system | +| `component` | A component within an app | +| `store` | A data store (database, queue, cache) | +| `actor` | An external user, team, or system | +| `group` | A logical grouping within a diagram | diff --git a/fern/guides/create-versions.mdx b/fern/guides/create-versions.mdx new file mode 100644 index 0000000..851b5ab --- /dev/null +++ b/fern/guides/create-versions.mdx @@ -0,0 +1,33 @@ +# Create landscape versions + +Version your landscape and create a snapshot in time on your version timeline. This can be run automatically as part of a build or release pipeline. + +## Prerequisites + +- [IcePanel account](https://app.icepanel.io/user/sign-up) +- [API key](https://app.icepanel.io) + +```bash +export ICEPANEL_API_KEY='your-api-key' +export ICEPANEL_ORGANIZATION_ID='your-organization-id' +``` + +## Steps + + + + Get all landscapes in your organization and select a landscape ID: + + + + Note the `id` of the landscape: + + ```bash + export ICEPANEL_LANDSCAPE_ID='your-landscape-id' + ``` + + + + + + \ No newline at end of file diff --git a/fern/guides/export-objects.mdx b/fern/guides/export-objects.mdx new file mode 100644 index 0000000..e25249a --- /dev/null +++ b/fern/guides/export-objects.mdx @@ -0,0 +1,47 @@ +# Export objects and relationships + +This guide shows how to export IcePanel model objects and relationships. Useful for scenarios like identifying a service's dependencies and ownership during incident response. + +IcePanel supports two formats: +1. **CSV** for importing spreadsheets (does not support [Flows](/core-concepts/flows)). +2. **JSON** for build pipelines, scripts, and automation (supports [Flows](/core-concepts/flows)). + +## Prerequisites + +- [IcePanel account](https://app.icepanel.io/user/sign-up) +- [API key](https://app.icepanel.io) + +```bash +export ICEPANEL_API_KEY='your-api-key' +export ICEPANEL_ORGANIZATION_ID='your-organization-id' +``` + +## Export as CSV + + + + Get all landscapes in your organization and select a landscape ID: + + + + Note the `id` of the landscape: + + ```bash + export ICEPANEL_LANDSCAPE_ID='your-landscape-id' + ``` + + + + + + + + + + + +## Export as JSON + +Export the whole model as JSON which can be easily used as part of a build pipeline, script or automation. This also includes flows which the CSV export does not. + + diff --git a/fern/guides/update-descriptions.mdx b/fern/guides/update-descriptions.mdx new file mode 100644 index 0000000..1a89d8d --- /dev/null +++ b/fern/guides/update-descriptions.mdx @@ -0,0 +1,43 @@ +# Update descriptions with Markdown + +Use the existing Markdown documentation stored in a code repository to populate the descriptions of your IcePanel model objects and connections. This can be automatically updated as part of a build pipeline. + +## Prerequisites + +- [IcePanel account](https://app.icepanel.io/user/sign-up) +- [API key](https://app.icepanel.io) + +```bash +export ICEPANEL_API_KEY='your-api-key' +export ICEPANEL_ORGANIZATION_ID='your-organization-id' +``` + +## Steps + + + + Get all landscapes in your organization and select a landscape ID: + + + + Note the `id` of the landscape: + + ```bash + export ICEPANEL_LANDSCAPE_ID='your-landscape-id' + ``` + + + + List all model objects in a landscape: + + + + Note the `id` of the object you want to update. + + + + Patch the model object with your Markdown description. Replace `modelObjectId` with the object's `id`. + + + + \ No newline at end of file diff --git a/fern/introduction/getting-started.mdx b/fern/introduction/getting-started.mdx deleted file mode 100644 index e686a38..0000000 --- a/fern/introduction/getting-started.mdx +++ /dev/null @@ -1,19 +0,0 @@ -# Introduction - -The IcePanel REST API is publicly accessible to write automated scripts or custom integrations with external tools. - -Our [OpenAPI 3.1](https://swagger.io/specification/) specification can be found at [api.icepanel.io](https://api.icepanel.io/) and opened by importing it into [Postman](https://learning.postman.com/docs/integrations/available-integrations/working-with-openAPI/). - -# Authentication - -First, generate an API key on your organization management screen. Make sure to copy your key and set the `X-API-Key` HTTP header on any authenticated requests. - -``` -X-API-Key: SH5XAiWtgevC2ZfQym3i:17a9c60035eed62c8f4f195c754ee6972ffc40ce975c5571ec521f463ebefa7f -``` - -# Example - -See the example below for how to request a list of landscapes. - - \ No newline at end of file diff --git a/fern/introduction/guides.mdx b/fern/introduction/guides.mdx deleted file mode 100644 index e5935aa..0000000 --- a/fern/introduction/guides.mdx +++ /dev/null @@ -1,36 +0,0 @@ -## Synchronize IcePanel objects with external resources - -If you have objects in IcePanel that also live in other systems/platforms/cloud providers you may want synchronize properties between these systems. For example you could synchronize external links to a resource from your IcePanel model. - -To do this, we recommend using a script to populate/synchronize properties in IcePanel. - -### Configure labels on the resource - -First, use the labels property to store the identifier of your external resource in the IcePanel object. - -``` -curl -X PATCH https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects/{modelObjectId} \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key {apiKey}' \ - -d '{"labels": {"cloudId": "xxxxxxxxxx"}}' -``` - -Labels are only for use in the IcePanel API and are not available on the UI. - -### Use labels to update the resource - -Once each object has the `cloudId` label assigned you can use that field to reverse lookup the coresponding IcePanel object. - -``` -curl -g 'https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects?filter[labels][cloudId]=xxxxxxxxxx' \ - -H 'X-API-Key {apiKey}' -``` - -Once the object has been retrieved, you can use the update endpoint to upsert the link URL to the resource, optionally specifying a friendly name for the UI. - -``` -curl -X PATCH https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects/{modelObjectId} \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key {apiKey}' \ - -d '{"links": {"$add": { "xxxxxxxxxx": { "customName": "Cloud Resource", "url": "https://console.cloud.google.com/run" } } } }' -``` diff --git a/fern/introduction/quickstart.mdx b/fern/introduction/quickstart.mdx new file mode 100644 index 0000000..4e7bfe2 --- /dev/null +++ b/fern/introduction/quickstart.mdx @@ -0,0 +1,414 @@ +--- +title: Quickstart +description: Make your first API call to IcePanel +--- + +In this example, we'll walk through IcePanel's data model by listing landscapes, viewing model objects, and finding their model connections. + +## Prerequisites + +- [IcePanel account](https://app.icepanel.io/user/sign-up) +- [API key](https://app.icepanel.io) + +## Call the API + + + + Go to **Profile settings** -> **API keys** -> **Create API key** and create a new key. + + + For future sessions, store it in a `~/.zshrc` or `~/.bashrc` + ```bash + export ICEPANEL_API_KEY='your-api-key' + ``` + Then run `source ~/.zshrc` (or `~/.bashrc`) to apply immediately. + + + + + This is the top-level model for access control. Landscapes and users belong to an organization. + + + ```typescript title="TypeScript" + import { IcePanelClient } from "@icepanel/sdk"; + + async function main() { + const client = new IcePanelClient({ + apiKey: "your-api-key", + apiVersion: "v1", + }); + const response = await client.organizations.list({}); + console.log(response); + } + main(); + ``` + + ```bash title="cURL" + curl "https://api.icepanel.io/v1/organizations" \ + -H "X-API-Key: $ICEPANEL_API_KEY" + ``` + + ```python title="Python" + import requests + + url = "https://api.icepanel.io/v1/organizations" + headers = {"X-API-Key": "your-api-key"} + response = requests.get(url, headers=headers) + print(response.json()) + ``` + + ```csharp title="C#" + using RestSharp; + + var client = new RestClient("https://api.icepanel.io/v1/organizations"); + var request = new RestRequest(); + request.AddHeader("X-API-Key", "your-api-key"); + RestResponse response = client.Execute(request); + Console.WriteLine(response.Content); + ``` + + ```go title="Go" + package main + + import ( + "fmt" + "net/http" + "io" + ) + + func main() { + url := "https://api.icepanel.io/v1/organizations" + + req, _ := http.NewRequest("GET", url, nil) + req.Header.Add("X-API-Key", "your-api-key") + + res, _ := http.DefaultClient.Do(req) + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(string(body)) + } + ``` + + ```java title="Java" + package com.example.usage; + + import com.icepanel.IcePanelClient; + import com.icepanel.types.OrganizationsListRequest; + + public class Example { + public static void main(String[] args) { + IcePanelClient client = IcePanelClient + .builder() + .apiKey("your-api-key") + .build(); + + var response = client.organizations().list( + OrganizationsListRequest.builder().build() + ); + System.out.println(response); + } + } + ``` + + + Note the `id` field. This is your `organizationId`. + + + + A workspace within an organization (like a repository). + + + ```typescript title="TypeScript" + import { IcePanelClient } from "@icepanel/sdk"; + + async function main() { + const client = new IcePanelClient({ + apiKey: "your-api-key", + apiVersion: "v1", + }); + const response = await client.organizations.landscapes.list({ + organizationId: "organizationId" + }); + console.log(response); + } + main(); + ``` + + ```bash title="cURL" + curl "https://api.icepanel.io/v1/organizations/$ICEPANEL_ORGANIZATION_ID/landscapes" \ + -H "X-API-Key: $ICEPANEL_API_KEY" + ``` + + ```python title="Python" + import requests + + url = "https://api.icepanel.io/v1/organizations/organizationId/landscapes" + headers = {"X-API-Key": "your-api-key"} + response = requests.get(url, headers=headers) + print(response.json()) + ``` + + ```csharp title="C#" + using RestSharp; + + var client = new RestClient("https://api.icepanel.io/v1/organizations/organizationId/landscapes"); + var request = new RestRequest(); + request.AddHeader("X-API-Key", "your-api-key"); + RestResponse response = client.Execute(request); + Console.WriteLine(response.Content); + ``` + + ```go title="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", "your-api-key") + + res, _ := http.DefaultClient.Do(req) + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(string(body)) + } + ``` + + ```java title="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") + .build(); + + var response = client.organizations().landscapes().list( + OrganizationLandscapesListRequest.builder() + .organizationId("organizationId") + .build() + ); + System.out.println(response); + } + } + ``` + + + Note the `id` field. This is your `landscapeId`. + + + + An object within your landscape. It can be a `system`, `app`, `component`, `store`, `actor`, `group`, or `root`. + + + ```typescript title="TypeScript" + import { IcePanelClient } from "@icepanel/sdk"; + + async function main() { + const client = new IcePanelClient({ + apiKey: "your-api-key", + apiVersion: "v1", + }); + const response = await client.model.objects.list({ + landscapeId: "landscapeId", + versionId: "latest" + }); + console.log(response); + } + main(); + ``` + + ```bash title="cURL" + curl "https://api.icepanel.io/v1/landscapes/$ICEPANEL_LANDSCAPE_ID/versions/latest/model/objects" \ + -H "X-API-Key: $ICEPANEL_API_KEY" + ``` + + ```python title="Python" + import requests + + url = "https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/objects" + headers = {"X-API-Key": "your-api-key"} + response = requests.get(url, headers=headers) + print(response.json()) + ``` + + ```csharp title="C#" + using RestSharp; + + var client = new RestClient("https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/objects"); + var request = new RestRequest(); + request.AddHeader("X-API-Key", "your-api-key"); + RestResponse response = client.Execute(request); + Console.WriteLine(response.Content); + ``` + + ```go title="Go" + package main + + import ( + "fmt" + "net/http" + "io" + ) + + func main() { + url := "https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/objects" + + req, _ := http.NewRequest("GET", url, nil) + req.Header.Add("X-API-Key", "your-api-key") + + res, _ := http.DefaultClient.Do(req) + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(string(body)) + } + ``` + + ```java title="Java" + package com.example.usage; + + import com.icepanel.IcePanelClient; + import com.icepanel.model.types.ModelObjectsListRequest; + + public class Example { + public static void main(String[] args) { + IcePanelClient client = IcePanelClient + .builder() + .apiKey("your-api-key") + .build(); + + var response = client.model().objects().list( + ModelObjectsListRequest.builder() + .landscapeId("landscapeId") + .versionId("latest") + .build() + ); + System.out.println(response); + } + } + ``` + + + Note the `id` of any object. This is your `modelObjectId`. + + + + A defined relationship between two model objects. We'll list model connections where `originId = modelObjectId`. + + + ```typescript title="TypeScript" + import { IcePanelClient } from "@icepanel/sdk"; + + async function main() { + const client = new IcePanelClient({ + apiKey: "your-api-key", + apiVersion: "v1", + }); + const response = await client.model.connections.list({ + landscapeId: "landscapeId", + versionId: "latest", + filter: { originId: "modelObjectId" } + }); + console.log(response); + } + main(); + ``` + + ```bash title="cURL" + curl --globoff "https://api.icepanel.io/v1/landscapes/$ICEPANEL_LANDSCAPE_ID/versions/latest/model/connections?filter[originId]=modelObjectId" \ + -H "X-API-Key: $ICEPANEL_API_KEY" + ``` + + ```python title="Python" + import requests + + url = "https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/connections" + params = {"filter[originId]": "modelObjectId"} + headers = {"X-API-Key": "your-api-key"} + response = requests.get(url, headers=headers, params=params) + print(response.json()) + ``` + + ```csharp title="C#" + using RestSharp; + + var client = new RestClient("https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/connections"); + var request = new RestRequest(); + request.AddHeader("X-API-Key", "your-api-key"); + request.AddQueryParameter("filter[originId]", "modelObjectId"); + RestResponse response = client.Execute(request); + Console.WriteLine(response.Content); + ``` + + ```go title="Go" + package main + + import ( + "fmt" + "net/http" + "io" + ) + + func main() { + url := "https://api.icepanel.io/v1/landscapes/landscapeId/versions/latest/model/connections?filter[originId]=modelObjectId" + + req, _ := http.NewRequest("GET", url, nil) + req.Header.Add("X-API-Key", "your-api-key") + + res, _ := http.DefaultClient.Do(req) + defer res.Body.Close() + body, _ := io.ReadAll(res.Body) + + fmt.Println(string(body)) + } + ``` + + ```java title="Java" + package com.example.usage; + + import com.icepanel.IcePanelClient; + import com.icepanel.model.types.ModelConnectionsListRequest; + import com.icepanel.types.ModelConnectionFilter; + + public class Example { + public static void main(String[] args) { + IcePanelClient client = IcePanelClient + .builder() + .apiKey("your-api-key") + .build(); + + var response = client.model().connections().list( + ModelConnectionsListRequest.builder() + .landscapeId("landscapeId") + .versionId("latest") + .filter(ModelConnectionFilter.builder() + .originId(ModelConnectionFilter.OriginId.of("modelObjectId")) + .build()) + .build() + ); + System.out.println(response); + } + } + ``` + + + + +## Next steps + +- [Create model objects](/developer-guide/how-to-guides/create-model-objects) Add new objects to your landscape. +- [Core Concepts](/core-concepts/overview) Learn the IcePanel data model +- [API Reference](/api-reference) Explore the IcePanel REST API diff --git a/fern/introduction/rate-limits.mdx b/fern/introduction/rate-limits.mdx index 2a6a422..6a95ba6 100644 --- a/fern/introduction/rate-limits.mdx +++ b/fern/introduction/rate-limits.mdx @@ -1,7 +1,23 @@ -We apply the following rate limits to our REST API which are the same for all environments. +# Rate limits -| Endpoints | Methods | Limit | -| -------- | -------- | ------- | +We apply the following rate limits to our REST API. Limits are the same for all environments. + +| Endpoints | Methods | Limit | +| --- | --- | --- | | `/user/*` | `POST` | 10 per minute | -| `/*` | `GET` `HEAD` | 2,400 per minute | +| `/*` | `GET` `HEAD` | 2,400 per minute | | `/*` | `POST` `PUT` `PATCH` `DELETE` | 60 per minute | + +--- + +## Handling rate limit errors + +When you exceed a limit, the API returns a `429 Too Many Requests` response with a JSON error body: + +```json +{ + "message": "Too Many Requests" +} +``` + +Check the `Retry-After` response header to see how many seconds to wait before retrying. diff --git a/fern/introduction/use-cases.mdx b/fern/introduction/use-cases.mdx deleted file mode 100644 index 814f67d..0000000 --- a/fern/introduction/use-cases.mdx +++ /dev/null @@ -1,67 +0,0 @@ -## Export objects and relationships - -The object and relationship data that IcePanel stores as part of the model has great uses. For example informing an incident response team about up and downstream dependencies of a service as well as which team owns the service. - -Export objects and connections in CSV format which is great for importing to spreadsheets. - -``` -curl https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects/export/csv - -curl https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/connections/export/csv -``` - -Export the whole model as JSON which can be easily used as part of a build pipeline, script or automation. This also includes flows which the CSV export does not. - -``` -curl https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/export/json -``` - -## Update model descriptions with Markdown - -Use the existing Markdown documentation stored in a code repository to populate the descriptions of your IcePanel model objects and connections. This can be automatically updated as part of a build pipeline. - -First fetch a list of the model objects that exist in your landscape and find the identifier to update. - -``` -curl https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects -``` - -Then patch the model object identifier with your Markdown description. - -``` -curl -X PATCH https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects/{modelObjectId} \ - -H 'X-API-Key {apiKey}' \ - -d '{"description": "# Heading\nbody"}' -``` - -## Create model objects - -Create objects in your model, great for automatically filling out your model from another source. - -First use a `GET` request to find the root model object, your landscape may have multiple root model objects if you use domains. - -``` -curl -g 'https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects?filter[type]=root' \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key {apiKey}' -``` - -Once you've found the root model object pass the id to the `parentId` property of `POST` request to create a model objects inside it. - -``` -curl -X POST https://api.icepanel.io/v1/landscapes/{landscapeId}/versions/latest/model/objects \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key {apiKey}' \ - -d '{"name": "New system", "type": "system", "parentId": "{parentId}"}' -``` - -## Create a version of your landscape - -Version your landscape and create a snapshot in time on your version timeline. This can be run automatically as part of a build or release pipeline. - -``` -curl -X POST https://api.icepanel.io/v1/landscapes/{landscapeId}/versions \ - -H 'Content-Type: application/json' \ - -H 'X-API-Key {apiKey}' \ - -d '{"name": "1.0", "notes": "Version 1.0", "modelHandleId": null}' -``` diff --git a/fern/introduction/what-is-icepanel.mdx b/fern/introduction/what-is-icepanel.mdx new file mode 100644 index 0000000..85870c1 --- /dev/null +++ b/fern/introduction/what-is-icepanel.mdx @@ -0,0 +1,35 @@ +# Introduction + +IcePanel is a collaborative diagramming and modelling tool for software architecture. + +IcePanel is built around the [C4 model](https://c4model.com/). + +Our [OpenAPI 3.1](https://swagger.io/specification/) spec can be found at [api.icepanel.io](https://api.icepanel.io/) and imported into [Postman](https://learning.postman.com/docs/integrations/available-integrations/working-with-openAPI/). + +JSON Schemas for IcePanel data types are available at `/v1/schemas/{schemaName}`, for example [`https://api.icepanel.io/v1/schemas/LandscapeImportData`](https://api.icepanel.io/v1/schemas/LandscapeImportData). These can be used to validate or generate typed data structures against the IcePanel API. + +--- + + + + Make your first API call to IcePanel. + + + Learn more about the IcePanel data model. + + + Use the IcePanel REST API to automate workflows and integrate with external tools. + +