Skip to content

Configuration Transfer API

The Configuration Transfer API allows exporting and importing Floh configuration entities as portable JSON documents. This enables environment migration, backup/restore, version-controlled configuration, and AI-driven automation.

Overview

Configuration entities are portable, definition-level objects that describe how your Floh instance is set up — as opposed to transactional data (workflow runs, approvals, audit logs) which represent runtime state.

Exportable Entity Types

Entity Type JSON Key Description
Connectors connectors External system integrations (Authifi, HTTP, etc.)
Projects projects Containers for workflow sets (includes nested workflow sets)
Email Templates emailTemplates Notification email templates
Document Templates documentTemplates Document template metadata (binary files not included)
User Groups userGroups Groups used for approval routing
Organizations organizations Organization hierarchy and memberships
Entitlements entitlements Entitlement definitions linked to connectors
Roles roles Role definitions with linked entitlements
Workflows workflows Workflow definitions (steps, variables, triggers)
Schedules schedules Cron-based scheduled triggers for workflows

Key Design Principles

  • Name-based references: Cross-entity references use names (not UUIDs) for portability across environments
  • Human-editable JSON: The format is designed for manual editing and version control
  • Secrets excluded: Connector secrets (connector_config) are never included in exports
  • Optional sections: Each entity section is optional — export/import only what you need
  • Dependency resolution: Imports process entities in dependency order automatically

Permissions

Permission Granted To Description
config:export admin, resource_manager Export configuration entities
config:import admin Import configuration entities (destructive operation)

Endpoints

GET /api/config/export

Export all (or filtered) configuration entities as a JSON document.

Query Parameters:

Parameter Type Default Description
entities string (all) Comma-separated list of entity types to include

Example Request:

# Export everything
curl -b cookies.txt http://localhost:3000/api/config/export

# Export only workflows, roles, and connectors
curl -b cookies.txt \
  'http://localhost:3000/api/config/export?entities=workflows,roles,connectors'

Example Response:

{
  "version": "1",
  "exportedAt": "2026-03-08T12:00:00.000Z",
  "exportedBy": "admin@example.com",
  "entities": {
    "connectors": [
      {
        "name": "authifi-prod",
        "type": "authifi",
        "description": "Production Authifi instance",
        "version": "1.0.0",
        "configSchema": { "commands": { "addToGroup": { "params": ["groupId", "userId"] } } },
        "enabled": true
      }
    ],
    "projects": [
      {
        "name": "Onboarding",
        "description": "User onboarding workflows",
        "workflowSets": [
          { "name": "Standard", "description": "Standard onboarding flows" }
        ]
      }
    ],
    "workflows": [
      {
        "name": "User Onboarding",
        "description": "Onboard new users with DUA and training",
        "project": "Onboarding",
        "workflowSet": "Standard",
        "category": "user",
        "status": "active",
        "subjectVariable": "user",
        "trigger": { "types": ["manual"] },
        "variables": [
          { "name": "user", "type": "user", "required": true }
        ],
        "steps": [
          { "id": "start", "name": "Start", "type": "start", "config": {}, "transitions": [{ "on": "success", "goto": "send-invite" }] },
          { "id": "send-invite", "name": "Send Invitation", "type": "notification", "config": { "recipientId": "{{user}}" }, "transitions": [{ "on": "success", "goto": "end" }] },
          { "id": "end", "name": "End", "type": "end", "config": {}, "transitions": [] }
        ],
        "onError": "stop",
        "debugLogging": false
      }
    ]
  }
}

POST /api/config/export

Export specific entities selected by name, optionally including their dependencies.

Request Body:

{
  "entities": {
    "workflows": ["User Onboarding"],
    "roles": ["Genome Access Participant"]
  },
  "includeDependencies": true
}

When includeDependencies is true (default), the export automatically includes entities that the selected ones depend on. For example, exporting a workflow will also export its project, and exporting a role will also export its entitlements and their connectors.

Dependency Chain:

schedules → workflows → projects
roles → entitlements → connectors

POST /api/config/import/preview

Dry-run an import to see what would be created, updated, or skipped — without making any database changes.

Query Parameters:

Parameter Type Default Description
strategy string upsert Import strategy (see below)

Import Strategies:

Strategy Behavior
upsert Create new entities and update existing ones (default)
create_only Only create new entities; report errors for any that already exist
skip_existing Create new entities; skip any that already exist

Request Body: A configuration JSON document (same format as the export response).

Example:

curl -X POST -b cookies.txt \
  -H 'Content-Type: application/json' \
  -d @config.json \
  'http://localhost:3000/api/config/import/preview?strategy=upsert'

Response:

{
  "status": "completed",
  "summary": {
    "created": 3,
    "updated": 1,
    "skipped": 0,
    "errors": 0
  },
  "details": [
    { "entity": "connector", "name": "authifi-prod", "action": "created" },
    { "entity": "project", "name": "Onboarding", "action": "created" },
    { "entity": "workflow_set", "name": "Onboarding/Standard", "action": "created" },
    { "entity": "workflow", "name": "User Onboarding", "action": "updated" }
  ]
}

POST /api/config/import

Execute an import, applying changes inside a database transaction.

Query Parameters: Same as preview (strategy).

Request Body: A configuration JSON document.

Response: Same format as preview, but changes are persisted to the database.

Import Order (dependency resolution):

  1. Connectors (no dependencies)
  2. Projects with nested workflow sets
  3. Email templates
  4. Document templates (metadata only — skipped if new)
  5. User groups (members resolved by email)
  6. Organizations (parent resolved by name)
  7. Entitlement definitions (connector resolved by name)
  8. Role definitions with entitlement links
  9. Workflow definitions (project + set resolved by name)
  10. Scheduled triggers (workflow resolved by name)

Response Status Values:

Status Meaning
completed All entities processed successfully
completed_with_errors Some entities succeeded, some failed
failed All entities failed

JSON Document Format

The configuration document has this structure:

{
  "version": "1",
  "exportedAt": "2026-03-08T12:00:00Z",
  "exportedBy": "admin@example.com",
  "description": "Optional description",
  "entities": {
    "connectors": [],
    "projects": [],
    "emailTemplates": [],
    "documentTemplates": [],
    "userGroups": [],
    "organizations": [],
    "entitlements": [],
    "roles": [],
    "workflows": [],
    "schedules": []
  }
}

All entity sections are optional. You can create a minimal document with just the entities you want to import:

{
  "version": "1",
  "entities": {
    "workflows": [
      {
        "name": "Simple Approval",
        "description": "A simple approval workflow",
        "project": "Default",
        "workflowSet": "Default",
        "category": "general",
        "status": "draft",
        "subjectVariable": null,
        "trigger": { "types": ["manual"] },
        "variables": [],
        "steps": [
          { "id": "start", "name": "Start", "type": "start", "config": {}, "transitions": [{ "on": "success", "goto": "end" }] },
          { "id": "end", "name": "End", "type": "end", "config": {}, "transitions": [] }
        ],
        "onError": "stop",
        "debugLogging": false
      }
    ]
  }
}

Entity Schema Reference

Connector

Field Type Description
name string Unique connector name
type string Connector type (e.g. authifi, http, ldap)
description string Human-readable description
version string Connector version
configSchema object JSON schema defining the connector's configuration
enabled boolean Whether the connector is active

Project

Field Type Description
name string Unique project name
description string Project description
workflowSets array Nested workflow sets ({ name, description })

Email Template

Field Type Description
name string Unique template name
description string Template description
subjectTemplate string Handlebars subject template
bodyTemplate string Handlebars body template (HTML)
isDefault boolean Whether this is the default template

User Group

Field Type Description
name string Unique group name
description string|null Group description
members string[] Member email addresses

Organization

Field Type Description
name string Unique organization name
address string|null Physical address
website string|null Website URL
domain string|null Email domain
parent string|null Parent organization name
contacts array Contact objects ({ name, email, phone, title })
members array Member objects ({ email, role }) where role is member, signatory, or approver

Entitlement

Field Type Description
name string Unique entitlement name
description string|null Description
connector string Connector name (resolved by name)
provisionConfig object Configuration for provisioning
deprovisionConfig object Configuration for deprovisioning
reconciliationConfig object|null Configuration for reconciliation

Role

Field Type Description
name string Unique role name
description string|null Role description
status string active or inactive
expiresAfterDays number|null Auto-expiry in days
entitlements string[] Linked entitlement names

Workflow

Field Type Description
name string Workflow name
description string Workflow description
project string Project name (resolved by name)
workflowSet string Workflow set name within the project
category string user, group, project, or general
status string draft, active, or deprecated
subjectVariable string|null Variable used for run tracking
trigger object Trigger configuration ({ types: ["manual"|"scheduled"|"webhook"] })
variables array Variable definitions
steps array Step definitions (the workflow graph)
onError string Error strategy: stop, skip, or retry
debugLogging boolean Enable debug logging

Schedule

Field Type Description
workflow string Workflow name (resolved by name)
name string|null Schedule display name
cronExpression string Cron expression (e.g. 0 2 * * *)
timezone string|null IANA timezone (e.g. UTC, America/New_York)
enabled boolean Whether the schedule is active
variables object Variables passed to workflow runs

AI Automation Examples

Export and save to file

curl -s -b cookies.txt http://localhost:3000/api/config/export | jq . > config-backup.json

Import from file with preview first

# Preview
curl -s -X POST -b cookies.txt \
  -H 'Content-Type: application/json' \
  -d @config-backup.json \
  'http://localhost:3000/api/config/import/preview' | jq .

# Apply
curl -s -X POST -b cookies.txt \
  -H 'Content-Type: application/json' \
  -d @config-backup.json \
  'http://localhost:3000/api/config/import?strategy=upsert' | jq .

Create a workflow programmatically

cat <<'EOF' | curl -s -X POST -b cookies.txt \
  -H 'Content-Type: application/json' \
  -d @- \
  'http://localhost:3000/api/config/import?strategy=upsert' | jq .
{
  "version": "1",
  "entities": {
    "workflows": [{
      "name": "Auto-Generated Approval",
      "description": "Created via API",
      "project": "Default",
      "workflowSet": "Default",
      "category": "general",
      "status": "draft",
      "subjectVariable": null,
      "trigger": { "types": ["manual"] },
      "variables": [
        { "name": "approver", "type": "user", "required": true }
      ],
      "steps": [
        { "id": "start", "name": "Start", "type": "start", "config": {}, "transitions": [{ "on": "success", "goto": "approve" }] },
        { "id": "approve", "name": "Get Approval", "type": "approval", "config": { "approvers": ["{{approver}}"] }, "transitions": [{ "on": "success", "goto": "end" }] },
        { "id": "end", "name": "End", "type": "end", "config": {}, "transitions": [] }
      ],
      "onError": "stop",
      "debugLogging": false
    }]
  }
}
EOF

Migrate configuration between environments

# Export from staging
curl -s -b staging-cookies.txt https://staging.example.com/api/config/export > staging-config.json

# Preview on production
curl -s -X POST -b prod-cookies.txt \
  -H 'Content-Type: application/json' \
  -d @staging-config.json \
  'https://prod.example.com/api/config/import/preview'

# Apply on production (create only — don't overwrite existing)
curl -s -X POST -b prod-cookies.txt \
  -H 'Content-Type: application/json' \
  -d @staging-config.json \
  'https://prod.example.com/api/config/import?strategy=create_only'

Audit Trail

All import and export operations are logged in the audit trail:

  • Export: action: "config.exported" with metadata about which entities were exported
  • Import: action: "config.imported" with metadata including the strategy used and a summary of created/updated/skipped/errored counts