Workspace Declarative API Interface

This article explains how to use the declarative API interface to manage workspaces. For a high-level overview of the declarative API interface, see the declarative API interface article.

Managing Workspaces

The declarative API interface allows you to manage all workspace entities or all entities associated with a specific endpoint at once (for example, the logical data model, analytics layer, or workspace data filters).

The workspace declarative API uses the following endpoints:

  • /api/v1/layout/workspaces manages all workspaces in an organization at once.

  • /api/v1/layout/workspaceDataFilters manages all workspace data filters in an organization.

  • /api/v1/layout/workspaces/{workspace-id} manages the entire declarative model for a specific workspace.

  • /api/v1/layout/workspaces/{workspace-id}/logicalModel manages the logical data model (LDM) for a workspace.

  • /api/v1/layout/workspaces/{workspace-id}/analyticsModel manages the analytics layer for a workspace.

where {workspace-id} is the identifier of the workspace (for example, headquarters).

Beware of Write Operations

  • Declarative API PUT requests fully replace the existing layout for the given endpoint. Always create a backup before making changes.
  • If you update only the logical model, analytical objects that reference removed logical objects become invalid. These relationships cannot be restored automatically.
  • To restore relationships between logical and analytical objects, you must either:
    • Manually fix the analytics layer, or
    • Reapply the entire workspace layout using /api/v1/layout/workspaces/{workspace-id}.

Extended Metadata

This section describes how analytical objects store creation and modification metadata, and how this metadata behaves when layouts are backed up, restored, or migrated.

Author and Editors

Analytical objects (dashboards, visualizations, metrics, dashboard plugins) store metadata about their creation and last modification. By default the declarative analytics layout includes:

  • createdBy
  • createdAt
  • modifiedBy
  • modifiedAt

You can modify or rebuild this metadata using the declarative API.

Backup and Restore

When restoring or migrating layouts, the API respects the metadata values provided in the payload.

When migrating analytics between environments or organizations, it is often useful to exclude author and editor metadata to avoid invalid user references.

You can do this by using the exclude=ACTIVITY_INFO parameter:

curl -H "Authorization: Bearer $API_TOKEN" \
  -X GET \
  $HOST_URL/api/v1/layout/workspaces/headquarters?exclude=ACTIVITY_INFO \
  > workspace-backup.json

When reimported:

  • createdAt reflects the upload time
  • createdBy is set to the user performing the PUT request

See Workspace Objects Life Cycle for details.

Cloning and Migration

When migrating or cloning workspaces, you can use the exclude=ACTIVITY_INFO parameter to omit author and editor metadata. This helps prevent import failures caused by user references that do not exist in the target environment.

Cross-Organization Migration Requires Manual Changes

Workspace declarative layouts are not directly portable between organizations.

When you export a workspace from one organization and import it into another, you must manually update the exported JSON file before running a PUT request. Otherwise, the import may fail or produce an unusable workspace. See Importing a Workspace Into Another Organization below.

Example:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X GET \
  $HOST_URL/api/v1/layout/workspaces/headquarters?exclude=ACTIVITY_INFO > workspace-backup-without-authors.json

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d @workspace-backup-without-authors.json \
  $HOST_URL/api/v1/layout/workspaces/headquarters2

See the Object Authors and Editors section for more details.

Importing a Workspace Into Another Organization

When migrating a workspace between organizations, update the exported JSON layout as follows:

  1. Data source references:

    • Data source IDs are organization-specific.
    • Replace all dataSourceId values with IDs of data sources that already exist in the target organization.
    • The logical model will not import successfully if referenced data sources do not exist.
  2. User and author references:

    • Analytical objects may reference users that do not exist in the target organization.
    • To avoid import errors, use exclude=ACTIVITY_INFO when exporting the workspace layout.
  3. Target workspace must already exist:

    • Create an empty workspace in the target organization before importing the layout.
    • PUT requests to /api/v1/layout/workspaces/{workspace-id} do not create workspaces.
    • The workspace ID must be unique within the target organization.
    • If a workspace with the same ID already exists, the PUT request will overwrite it.
  4. Destructive overwrite:

    • Importing a layout fully replaces the existing workspace content in the target organization.
    • Always back up the target workspace before importing.

Typical workspace migration flow between organizations might look like this:

  1. Export the workspace layout from the source organization.
  2. Create an empty workspace in the target organization.
  3. Ensure all required data sources exist in the target organization.
  4. Update data source IDs and remove user metadata from the exported JSON.
  5. Import the updated layout into the target workspace.

Example Requests

The examples in this section are not meant to be used without modification. Please modify the examples to match the requirements of your site before using them. In the examples below the workspace ID is headquarters.

Backup a Workspace

The following example retrieves the entire declarative layout for the specified workspace and stores the output in a JSON file named workspace-backup.json:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X GET \
  $HOST_URL/api/v1/layout/workspaces/headquarters > workspace-backup.json

Restore a Workspace

The following example replaces the workspace declarative layout for the specified workspace with a previously retrieved declarative layout:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d @workspace-backup.json \
  $HOST_URL/api/v1/layout/workspaces/headquarters

Clone a Workspace

The following examples copy the layout of the workspace headquarters to a JSON file named workspace-backup.json and overwrite the layout of an existing workspace named headquarters2 with the contents of that file.

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X GET \
  $HOST_URL/api/v1/layout/workspaces/headquarters > workspace-backup.json

To prevent a 404 error, the target workspace of the overwrite (headquarters2 in this example) must first exist before you can issue a PUT request using the workspace {workspace-id}. See Create a Workspace for more information.

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -H "Accept: application/json" \
  -X PUT \
  -d @workspace-backup.json \
  $HOST_URL/api/v1/layout/workspaces/headquarters2

Backup LDM

The following example retrieves the LDM declarative layout for the specified workspace and stores the output in a JSON file named model.json:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" $HOST_URL/api/v1/layout/workspaces/headquarters/logicalModel > model.json

Restore LDM

The following example replaces the LDM declarative layout for the specified workspace with a previously retrieved declarative layout:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X PUT \
  -d @model.json $HOST_URL/api/v1/layout/workspaces/headquarters/logicalModel

Empty a Workspace

The following example removes all objects (logical and analytical objects and data filters) from the specified workspace:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X PUT \
  -d '{
  "ldm": { "datasets": [], "dateInstances": [] },
  "analytics": { "analyticalDashboards": [], "filterContexts": [], "metrics": [], "visualizationObjects": [] }
  }' \
  $HOST_URL/api/v1/layout/workspaces/headquarters

Backup Workspaces

The following example retrieves the workspace declarative layouts for all workspaces associated with the organization hostname and stores the output in a JSON file named all-workspaces-backup.json:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X GET \
  $HOST_URL/api/v1/layout/workspaces > all-workspaces-backup.json

This endpoint exports workspace layouts only. It does not include organization-level entities such as users, data sources, authentication settings, or secrets.

Restore Workspaces

The following example replaces the workspace declarative layout for all workspaces associated with the organization hostname with a previously retrieved declarative layout:

curl -H "Authorization: Bearer YWRtaW46Ym9vdHN0cmFwOmFkbWluMTIz" \
  -H "Content-Type: application/json" \
  -X PUT \
  -d @all-workspaces-backup.json \
  $HOST_URL/api/v1/layout/workspaces

Workspace Layout

The following example shows a truncated declarative layout for workspaces. The workspace headquarters is a parent workspace that propagates all its attributes to the child workspace sub1:

{
  "workspaces": [
    {
      "id": "headquarters",
      "name": "Headquarters",
      "model": {
        "ldm": {
          "datasets": [],
          "dateInstances": [{
            "description": "parent date",
            "granularities": [
              "DAY",
              "WEEK",
              "MONTH",
              "QUARTER",
              "YEAR"
            ],
            "granularitiesFormatting": {
              "titleBase": "",
              "titlePattern": "%granularityTitle (%titleBase)"
            },
            "id": "date.parent",
            "title": "Hierarchy Date"
          }]
        },
        "analytics": {
          "analyticalDashboards": [],
          "filterContexts": [],
          "metrics": [],
          "visualizationObjects": []
        }
      },
      "settings": [
        {
          "id": "timezone",
          "content": {
            "value": "Europe/Prague"
          }
        }
      ]
    },
    {
      "id": "sub1",
      "name": "Subsidiary I.",
      "model": {
        "ldm": {
          "datasets": [],
          "dateInstances": []
        },
        "analytics": {
          "analyticalDashboards": [],
          "filterContexts": [],
          "metrics": [],
          "visualizationObjects": []
        }
      },
      "parent": {
        "id": "headquarters",
        "type": "workspace"
      },
      "settings": [
        {
          "id": "timezone",
          "content": {
            "value": "Europe/Prague"
          }
        }
      ]
    }
  ],
  "workspaceDataFilters": []
}