Skip to main content
Prisme.ai workspaces can be synchronized with external Git repositories, enabling collaborative workflows between the platform and standard Git tooling. Changes made on either side are merged transparently using Git’s built-in merge capabilities.

Repository Configuration

Configure version control in your workspace source code:
repositories:
  github:
    name: My GitHub Repository
    type: git
    mode: read-write
    config:
      url: https://github.com/YourUser/your-repository.git
      branch: main
      auth:
        user: 'your git user'
        password: '{{secret.gitPassword}}'
Different authentication methods are supported:
  • Username/Password: For basic authentication
  • Personal Access Tokens: For services like GitHub which forbid user password usage from CLI, instead they let you generate a Personal Access Token you will use exactly like a password
  • SSH Keys: For secure key-based authentication, see below example.
You can configure multiple repositories with different access modes:
  • read-write (default): Both push and pull operations
  • read-only: Only pull operations
  • write-only: Only push operations

Sub-directory (dirpath)

By default, workspace files are stored at the root of the Git repository. Use the dirpath option to store them in a sub-directory instead:
repositories:
  github:
    name: My GitHub Repository
    type: git
    mode: read-write
    config:
      url: https://github.com/YourUser/your-repository.git
      branch: main
      dirpath: "workspaces/myapp"
      auth:
        user: 'your git user'
        password: '{{secret.gitPassword}}'
This is useful when a single Git repository hosts multiple workspaces or includes non-workspace files alongside workspace content.

Platform-wide Repositories

Administrators can configure shared repositories available to all workspaces through environment variables, without requiring each workspace to configure its own credentials. Each workspace’s files are stored in a sub-directory named after its slug. Platform repositories support two types:
  • git (default): a remote Git repository accessed via HTTPS or SSH
  • filesystem: a local directory on disk, typically embedded in the Docker image.
The filesystem type is reserved for platform repositories configured by administrators. Workspaces cannot configure filesystem-type repositories through the API or workspace settings.
Platform repositories can also configure a custom DIRPATH to store workspace directories under a specific base path within the repository. In that case, each workspace’s files are stored under {dirpath}/{workspaceSlug}. See the self-hosting environment variables documentation for configuration details.

Using Secrets in Version Control

You can use secrets inside the repository config section:
config:
  auth:
    password: '{{secret.gitPassword}}'

Typical Collaboration Workflow

When working with an external Git repository, the platform uses an intermediate branch (named prismeai/{workspaceSlug}/{targetBranch}) to manage synchronization. This branch acts as a buffer zone where merges happen before affecting either side. A typical workflow looks like this:
  1. Developers A work on the platform — editing automations, pages, and configuration through the UI
  2. Other team members work in Git — editing YAML files directly in their IDE, committing to the target branch
  3. Pull — imports remote Git changes into the workspace. The platform first saves its own state (edited by developers A) to the intermediate branch, then merges the target branch in. If there are no conflicts, the merge result is imported transparently
  4. Push — exports the workspace state to Git. The platform commits to the intermediate branch, then merges it into the target branch
Because both sides’ changes are saved to Git before merging, Git can detect conflicts and perform automatic merges when changes don’t overlap.
The intermediate branch (prismeai/{workspaceSlug}/{branch}) is managed automatically by the platform. Never modify it manually unless you are resolving a merge conflict (see below).

Push and Pull Operations

Once a repository is configured:
  • Push: Save the current workspace state to the repository
  • Pull: Update the workspace from the repository
A native repository named “Prismeai” is always available for saving versions to the platform’s storage. However, these versions are lost if the workspace is deleted, unlike with external Git repositories.

What’s Versioned

Versioning saves the workspace’s static configuration, including security roles, automations, pages, blocks, and apps, but not dynamic data like events, collections, or uploaded files.

Included in Versioning

Workspace components that are saved and deployed:

  • Pages and their configurations
  • Blocks and custom components
  • Automations and workflows
  • Security roles and permissions
  • App configurations
  • Workspace settings

Not Included in Versioning

Data that remains specific to each environment:

  • Events and their history
  • Collection data
  • Crawled documents
  • Uploaded files
  • User-specific settings
  • Runtime state

Automatic Platform State Save on Pull

When you pull, the platform automatically saves the current workspace state to the intermediate Git branch before merging remote changes. This ensures that any local modifications made through the UI are preserved in Git history and can be detected as conflicts if they overlap with remote changes. This automatic save is skipped in two cases:
  • Discard local changes: when you explicitly choose to discard local changes (available as a UI option), the pull overwrites the workspace entirely with the remote content
  • After a merge conflict resolution: when a previous pull resulted in a merge conflict (which is resolved manually in Git), the next pull skips saving to avoid overwriting the resolution

Push Requires an Up-to-date Workspace

Before pushing, the platform checks whether the workspace is synchronized with the remote branch. If there are remote commits that haven’t been pulled yet, the push is rejected with a message asking you to pull first. This prevents accidentally overwriting remote changes that haven’t been reviewed.

Dirty Tracking

The platform tracks whether a workspace has unsaved changes relative to its Git repository. Two fields are maintained on each workspace:
  • dirty: Set to true whenever workspace content is updated (automations, pages, config, etc.), and reset to false after a successful push to a Git repository.
  • lastPush: Records details of the last successful push, including createdAt (timestamp), createdBy (user ID), version (version name), and repositoryId.
These fields are returned in the GET /workspaces API response. You can also filter workspaces by their dirty state using the dirty query parameter:
GET /v2/workspaces?dirty=true
This returns only workspaces that have unpushed changes, which is useful for identifying workspaces that need to be synchronized with their Git repository.

Merge Conflicts

When a pull detects conflicting changes between the platform state and the remote branch, the operation stops and the workspace is locked with a merge_conflict reason. This lock does not expire and prevents any further versioning operations until the conflict is resolved. To resolve a merge conflict:
  1. In your Git client, checkout the intermediate branch, merge the target branch, and resolve the conflicts:
    git checkout main
    git pull
    git checkout prismeai/myapp/main
    git pull
    git merge --no-ff main
    # Resolve conflicts in your editor
    git commit
    git push
    
  2. Back on the platform, pull again. The platform detects that a merge conflict was previously active, skips saving local state (to not overwrite your resolution), and imports the resolved content.
Alternatively, if you want to discard the conflicting state entirely, you can clear the lock via the API (see Write Lock below) and pull with “discard local changes” enabled.

Write Lock

Versioning operations (pull, push, import) acquire an exclusive write lock on the workspace to prevent concurrent operations from corrupting data. The lock is automatically released when the operation completes. If an operation fails or takes too long, the lock expires after 30 minutes (configurable via WORKSPACE_WRITE_LOCK_TIMEOUT_MINUTES). Exception: merge conflict locks never expire and require explicit resolution through API or pull. You can manage the lock manually through the API:
  • Set a lock: POST /v2/workspaces/{workspaceId}/writeLock with an optional reason field
  • Clear a lock: DELETE /v2/workspaces/{workspaceId}/writeLock
Both endpoints require the ManageSecurity permission on the workspace. Clearing a lock is useful to recover from stuck operations or to dismiss a merge conflict without resolving it in Git.

Progress Notifications

During pull and push operations, the platform emits real-time progress events (workspaces.versions.progress) that are displayed as notifications in the UI. These notifications show the current step of the operation (checkout, pull, write, merge, push, import) along with a live timer for long-running steps. If an operation fails, an error notification is displayed. Progress events are also available in the workspace event stream for programmatic monitoring.

Excluding Files from Import

When pulling from a repository, you can exclude specific parts of your workspace from being overwritten:
repositories:
  github:
    name: My GitHub Repository
    type: git
    mode: read-write
    config:
      url: https://github.com/YourUser/your-repository.git
      branch: main
    pull:
      exclude:
        - path: 'index'  # Don't override workspace config
        - path: 'security'  # Don't override security files
        - path: 'pages/custom'  # Don't override 'custom' page
This is useful for preserving local customizations while still getting updates from the shared repository.

Import Results

After each archive import or repository pull, a workspaces.imported event is emitted with details:
{
 "files": [
  "index",
  "security",
  "pages/test.yml"
 ],
 "deleted": [
  "automations/removedAutomation.yml"
 ],
 "version": {
  "name": "latest",
  "repository": {
   "id": "yourRepositoryId"
  }
 },
 "errors": [
  {
   "msg": "Could not rename workspace slug from {oldSlug} to {newSlug} as it is already used by workspaceId zlkpbRF",
   "err": "SlugAlreadyInUse",
   "conflictingWorkspaceId": "..."
  }
 ]
}
This event provides a complete record of what changed during the import.

Self-Signed TLS

When trying to authenticate using user/password method against a repository with a self-signed HTTPS certificate, you can receive the following error:
  SSL certificate problem: self-signed certificate in certificate chain
This is an infrastructure issue which needs to be solved within prismeai-workspaces deployment, by mounting a copy of the /etc/ssl/certs/ca-certificates.crt file at the same address and adding the git server certificate to it.

Platform Workspace

Prisme.ai automatically creates a special workspace with the ID platform. This workspace is used for platform-wide operations such as bulk imports and bulk pushes, and serves as a central place to monitor platform-level events. By default, only super admins have access to the Platform workspace. Super admins can share access with other users if needed. The Platform workspace also holds the write lock during bulk import and bulk push operations, ensuring that only one bulk operation can run at a time across the entire cluster. The Platform workspace can also use the standard individual push/pull APIs (POST /workspaces/platform/versions and POST /workspaces/platform/versions/latest/pull) with its own workspace-level repositories. When no platform repository ID is specified (or an unrecognized one is given), these endpoints fall back to the Platform workspace’s own repository configuration, behaving like a regular workspace push/pull.

Workspace Groups

Workspace groups allow organizing workspaces into logical sets for selective bulk imports and bulk pushes. Groups are defined via environment variables:
WORKSPACES_GROUP_{groupName}_LABELS="label1,label2,..."
A workspace belongs to a group if at least one of its labels matches one of the group’s labels. When a workspace is pushed to a platform repository, the groups it belongs to are written to its .import.yml file. During a bulk import, the groups parameter filters which workspaces are imported. Only workspaces whose .import.yml lists at least one of the requested groups will be included. Similarly, during a bulk push, the groups parameter determines which workspaces are pushed based on their labels. See the environment variables documentation for configuration examples.

Bulk import

Bulk import allows importing (or updating) groups of workspaces from a platform repository in a single operation. This is useful for initial deployments, platform upgrades, or keeping a fleet of workspaces synchronized with a reference repository.

Triggering a Bulk Import

A bulk import can be triggered in three ways:
  1. Via API: send a POST request to /v2/workspaces/platform/versions/latest/pull with the repository and groups filter:
{
  "repository": { "id": "yourRepoId" },
  "groups": ["core"],
  "forceReimport": false
}
By default, workspaces already up to date with the repository are skipped. forceReimport: true disable this by forcing all target workspaces reimport.
  1. Trigger the same API from the Platform workspace versioning UI
  2. Automatically at startup: configure the environment variables STARTUP_IMPORT_GROUPS and STARTUP_IMPORT_REPOSITORY to trigger a bulk import each time the workspaces service starts. See the environment variables documentation for details.
The API endpoint requires access to the platform workspace. Non super admins still need access to all corresponding workspaces in order to trigger a bulk import from the Platform workspace.

How It Works

When a bulk import is triggered:
  1. Repository clone (git repos only): the repository is cloned or pulled once. For git repositories, the local clone is then used as a filesystem source for each workspace import, avoiding redundant clones.
  2. Workspace discovery: all top-level directories in the repository are listed. Each directory represents a workspace identified by its slug.
  3. Filtering by group: if a group parameter is provided, only workspaces whose .import.yml includes that group are imported (see Workspace Groups below).
  4. Topological ordering: workspaces are sorted by their dependencies (declared via dependsOn in .import.yml) so that a workspace is always imported after its dependencies.
  5. Skip optimization: for each workspace, the platform checks whether it is already up to date by comparing the version.name from the repository’s .import.yml with the workspace’s lastPull.version in the database. If they match, the workspace is skipped. Can be disabled with forceReimport: true
  6. Import: each workspace is imported sequentially using the standard pull mechanism with discardLocalChanges: true (local changes are always overwritten during bulk imports).

Monitoring Progress

All bulk import events are emitted to the Platform workspace and can be monitored from its Activity view:
EventDescription
workspaces.bulkImport.startedEmitted at the beginning with the list of workspaces to import
workspaces.bulkImport.progressEmitted after each workspace with its status (imported, skipped, or error), file counts, and percentage
workspaces.bulkImport.completedEmitted at the end with the full summary: created, updated, skipped, errors, and total duration
Individual workspace events (workspaces.imported, workspaces.versions.progress) are still emitted as usual for each workspace. If the HTTP request times out (configurable via the timeout query parameter), the response returns { "processing": true } and the final result is available through the workspaces.bulkImport.completed event.

Bulk push

Bulk push allows pushing all dirty workspaces belonging to specific groups to a platform repository in a single operation. This is the counterpart of bulk import: while bulk import pulls workspaces from a repository, bulk push pushes workspaces to a repository.

Triggering a Bulk Push

A bulk push can be triggered in two ways:
  1. Via API: send a POST request to /v2/workspaces/platform/versions with the groups and repository:
{
  "groups": ["core", "extended"],
  "repository": { "id": "yourRepoId" },
  "name": "v2.5.0",
  "description": "February release"
}
  1. Via the UI: from the Platform workspace’s Versions panel, select the groups to push and click “Push”. This triggers the same bulk push API under the hood.
The API endpoint requires access to the platform workspace. A write lock is acquired on the Platform workspace during the operation to prevent concurrent bulk pushes.

Options

ParameterDescription
groupsGroup names to push (must exist in WORKSPACE_GROUPS config)
repository.idPlatform repository ID (defaults to the first available platform repository)
nameVersion name applied to each pushed workspace. Auto-generated if omitted
descriptionVersion description
dryRunWhen true, returns workspace categorization without actually pushing
forceWhen true, also pushes workspaces that are already up to date

How It Works

When a bulk push is triggered:
  1. Group resolution: the requested groups are resolved to workspace labels via the WORKSPACE_GROUPS configuration (same groups used for bulk import).
  2. Workspace discovery: all workspaces matching the resolved labels are fetched and categorized:
    • Dirty workspaces (with local changes since last push) are candidates for push
    • Already pushed workspaces (no local changes) are skipped by default
    • Workspaces with an active merge conflict lock are excluded
    • Workspaces with a push already in progress are skipped
  3. Sequential push: each candidate workspace is pushed sequentially using the standard push mechanism.

Monitoring Progress

All bulk push events are emitted to the Platform workspace and can be monitored from its Activity view:
EventDescription
workspaces.bulkPush.startedEmitted at the beginning with the list of workspaces and their initial status (candidate, mergeConflict, inProgress, alreadyPushed)
workspaces.bulkPush.progressEmitted after each workspace with its status (pushed or error), current/total counts, and percentage
workspaces.bulkPush.completedEmitted at the end with the full summary: pushed, merge conflicts, already pushed, errors, and total duration
Individual workspace push events (workspaces.versions.progress) are still emitted as usual for each workspace.

SSE Streaming

The bulk push API supports Server-Sent Events for real-time progress tracking. Add ?sse=true to the query string to receive a stream of progress events instead of a single JSON response:
curl -X POST "https://api.studio.prisme.ai/v2/workspaces/platform/versions?sse=true" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"groups": ["core"], "repository": {"id": "yourRepoId"}}'
Each SSE event contains the current workspace status, progress percentage, and duration. The final event contains the full completion summary. If SSE is not enabled and the HTTP request times out (configurable via the timeout query parameter, default 15s), the response returns { "processing": true } and the final result is available through the workspaces.bulkPush.completed event.

The .import.yml File

Each workspace in a platform repository contains a .import.yml file at its root. This file is automatically generated when a workspace is pushed to a platform repository and contains metadata used during imports.
# Example .import.yml
workspaceId: "abc123"
version:
  type: export
  name: "v2.4.0"
  exportedAt: "2026-02-15T10:30:00.000Z"
groups:
  - core
  - enterprise
dependsOn:
  - app/securechat
  - app/knowledge
app:
  slug: builder
  name: Builder
checksums:
  automations:
    myAutomation: "sha256:..."
  pages:
    dashboard: "sha256:..."
  imports:
    securechat: "sha256:..."
Key fields:
  • version.name: the version label set at push time, used to detect whether a workspace is already up to date
  • groups: list of group names this workspace belongs to, used for filtering during bulk imports and bulk pushes
  • dependsOn: list of dependencies (referenced as app/{appSlug}), used to determine import order
  • app: if the workspace publishes an app, its slug and name
  • checksums: SHA checksums of individual files, generated at export time
Any manual changes to this file will be overwritten by the next platform push.

Key API endpoints & UI

Here is a small recap for all versioning related APIs :

Archives import/export

  • GET /workspaces/{id}/export - Export workspace
  • POST /workspaces/{id}/import - Import workspace
Both can also be triggered from each workspace settings.
New workspace can also be created & imported from an archive using the three dots menu over “Create a workspace” button.

Workspace git versioning

  • POST /workspaces/{id}/push - Push to repository
  • POST /workspaces/{id}/pull - Pull from repository
Both can also be triggered from each workspace versioning UI after configuring repositories section

Platform versioning

  • POST /workspaces/platform/versions - Bulk push groups of workspaces to a platform repository
  • POST /workspaces/platform/versions/latest/pull - Bulk import groups of workspaces from a platform repository
Both can also be triggered from the Platform workspace versioning UI, after configuring platform repositories and workspace groups.

Next Steps