Export & Import
Workflows are portable. You can export any workflow as a self-contained JSON bundle and import it into any other Hrida AI Studio deployment — including a different organization, environment, or region. Within a single deployment, Promote to catalog does the same thing in one click, for moving a published workflow between catalogs or spaces (e.g. sandbox → uat → production).
The bundle includes the full graph, every skill used by the workflow (including inherited base skills), and the linked default skill. Knowledge base data is not transferred automatically, but the bundle lists the names of every KB that needs to be re-wired after import.
This page covers exporting/importing a single Hrida workflow as a JSON file. To migrate a whole external Claude Code plugin or skill repository (.zip) — skills, tools, prompts, and agent-orchestrator cookbooks detected automatically from folder structure — see Import Bundle instead.
Exporting a workflow
- Open the workflow in the editor.
- Click the ⋯ (more options) menu in the top-right toolbar.
- Select Export JSON.
- Save the downloaded file. The file name matches the workflow name.
Alternatively, call the REST endpoint directly:
GET /api/v1/agent-workflows/{workflow_id}/export
Authorization: Bearer <token>The response is a WorkflowExportSchema JSON object (see Bundle structure below).
Importing a workflow
- From the Agent Workflows list page, click Import.
- Select the exported
.jsonfile. - Optionally choose a target space.
- Click Import. The workflow is created as a Draft.
Via the REST API:
POST /api/v1/agent-workflows/import
Authorization: Bearer <token>
Content-Type: application/json
{
"name": "Invoice Agent",
"graph": { ... },
"embedded_skills": [ ... ],
"knowledge_base_refs": [ ... ],
"default_skill_original_id": "uuid-from-source-env",
"space_id": "optional-target-space-id"
}After import, go through the normal Draft → Publish lifecycle before using the workflow in production.
Promote to catalog
Promote to catalog… is a one-click version of export + import: it copies a Published workflow straight into another catalog or space as a new draft, without a manual download/upload round-trip. Same remapping rules apply — it's the same mechanism as Skill remapping and Knowledge bases below, just triggered server-side in a single API call.
This is meant for promoting a workflow through environments:
sandbox catalog → (stage → approve) → published
│
POST /{id}/promote
│
uat catalog → new draft → (stage → approve) → published
│
POST /{id}/promote
│
production catalog → new draft → …
Requirements
| Condition | Detail |
|---|---|
| Source workflow status | Must be Published — draft, staged, or rejected workflows can't be promoted |
| Target space access | Caller needs agent_developer, lifecycle_manager, or space_admin on the target space (only checked when a target space is chosen) |
| Source workflow | Left untouched — promoting copies, it never moves or deletes the original |
Using it
- Open a Published workflow and click Promote to catalog… in the header.
- Pick a Target Catalog — leave it on "Current catalog" to promote within the same catalog, or choose another one from the dropdown.
- Pick a Target Space — the list repopulates for whichever catalog you picked. Leave it blank for a platform-wide (space-less) copy.
- Click Promote. You're redirected straight into the new draft's editor.
The dialog only lists catalogs/spaces you have access to; both dropdowns default to "leave blank" so a same-catalog, platform-wide promotion needs no input at all.
What happens
| Step | Result |
|---|---|
| Embedded skills collected | Same logic as export — every skill referenced by the graph, plus the default skill |
| Skills remapped into target | Same name-based dedup and base-skill-chain rules as import |
| Graph rewritten | config.skill_id on every node points at the new, target-environment skill |
| New workflow created | Always a fresh Draft in the target catalog/space, regardless of the source's status |
| Knowledge bases | Not rewired automatically — same manual step as import; re-select local KBs on the promoted copy before staging it |
The new draft then goes through the normal Draft → Publish lifecycle in its target environment.
The REST endpoint accepts a name_override to rename the copy on the way in; the in-editor dialog doesn't expose this yet, so promoting from the UI always keeps the source workflow's name.
Bundle structure
The exported JSON has the following top-level shape:
{
"schema_version": "hrida-workflow/v1",
"name": "Invoice Agent",
"description": "Processes supplier invoices end-to-end",
"version": "2.1.0",
"exported_at": "2026-06-28T10:45:00Z",
"graph": { "nodes": [...], "edges": [...] },
"embedded_skills": [...],
"knowledge_base_refs": [{ "id": "kb-abc", "name": "Finance Docs" }],
"default_skill_original_id": "uuid-of-default-skill"
}graph — node and edge config
The graph is exported verbatim. Every node type carries its complete config object:
| Node type | Config fields exported |
|---|---|
agent / classify / guardrails | skill_id¹, system_prompt, extra_system_prompt, extra_tools, extra_knowledge_ids, llm.{model_id, provider_id, temperature, max_tokens}, execution_mode, review_group, review_timeout_minutes, timeout_action |
file_search | knowledge_ids², query, limit, min_score, output_format |
mcp | server_url³, tool_name, tool_input |
if_else | condition |
while_loop | condition, max_iterations |
user_approval | prompt, review_group |
transform | expression |
set_state | state_key, state_value |
¹ skill_id values are source-environment UUIDs. They are remapped to new UUIDs during import — see Skill remapping below.
² knowledge_ids in node configs travel as-is but reference source-environment KB IDs that may not exist in the target — see Knowledge bases below.
³ server_url in mcp nodes may be environment-specific (e.g. http://localhost:3000) and will need updating after import.
embedded_skills — full skill definitions
Every skill referenced by a graph node is embedded, plus the workflow's default skill (even if not yet wired to any node). For each skill, the bundle includes:
| Field | Included |
|---|---|
name, description | Yes |
system_prompt | Yes |
tools | Yes (list of tool names) |
llm_defaults (model_id, provider_id, temperature, max_tokens) | Yes |
input_schema, output_schema | Yes |
tags, is_global | Yes |
base_skill_original_id | Yes — points to the parent skill within the same bundle |
knowledge_ids | No — cleared to [] (see Knowledge bases) |
| Instance-specific fields | No — id (only original_id is included), status, space_id, catalog_id, created_by, usage_count, version |
Skills are listed in dependency order: a base skill always appears before any skill that inherits from it. This ensures base skills are created first during import.
knowledge_base_refs — informational only
"knowledge_base_refs": [
{ "id": "kb-abc123", "name": "Finance Docs" },
{ "id": "kb-def456", "name": "Product Catalogue" }
]This field lists every knowledge base referenced in the workflow or any embedded skill, by name. It is read-only information — no KB data is transferred. After import, you must recreate or identify matching knowledge bases in the target environment and re-wire them (see Knowledge bases).
default_skill_original_id
The source-environment UUID of the workflow's default skill. During import this UUID is looked up in the skill_id_map built from embedded_skills, and the imported workflow's default_skill_id is set to the newly created local UUID. The blank skill that is auto-created for every new workflow is deleted and replaced with the imported one.
What is not exported
| Field | Reason |
|---|---|
Workflow id, space_id, user_id | Instance-specific; target env assigns new values |
status | Always re-created as draft |
submitted_by, reviewed_by, review_notes | Audit fields reset |
created_at, updated_at | Reset to import timestamp |
Skill status | Re-created as draft |
Skill space_id, catalog_id, created_by | Instance-specific |
Skill usage_count, version, origin_skill_id | Reset |
| API keys, secrets, credentials | Never stored in the graph layer |
| Knowledge base content | Must be recreated manually in the target environment |
Skill remapping
During import, every skill_id UUID in node configs must be translated from the source environment's UUID to the newly created local UUID. The import process builds a skill_id_map as it processes embedded_skills:
source_uuid_A → new_local_uuid_A (created or matched by name)
source_uuid_B → new_local_uuid_B
After all skills are resolved, the importer walks every graph node and rewrites config.skill_id:
node.config.skill_id = skill_id_map[node.config.skill_id]
Name-based deduplication: if a skill with the same name already exists in the target environment, the importer reuses that skill's ID instead of creating a duplicate. This is useful for shared base skills (e.g. "Finance Base") that are already present in the target.
Base skill chains: skills are embedded in dependency order. When creating a skill whose base_skill_original_id is already in the map, the importer sets the new base_skill_id to the mapped local UUID, preserving the full inheritance chain.
Knowledge bases
Knowledge base UUIDs from the source environment are not valid in the target. The import process handles this in two ways:
In embedded skills: knowledge_ids is explicitly cleared to [] during import. The skill is created without KB references.
In node configs: knowledge_ids values travel verbatim in the graph. They won't cause errors at import time, but at runtime the file_search node or agent node will search with those IDs and return empty results if they don't exist in the target.
To re-wire knowledge bases after import:
- Check
knowledge_base_refsin the bundle for the names of KBs that need to exist. - Create or locate matching knowledge bases in the target environment.
- Open each affected node (and each skill in the Skills editor) and re-select the correct local KB.
- Save and re-test the workflow.
Concrete example
Source environment
A workflow "Invoice Agent" with:
- Default skill:
"Invoice Agent [a1b2c3]"(system prompt:"You process supplier invoices…", tools:["sql_query"]) - An
agentnode wired to"Finance Base"skill - A
file_searchnode referencing KBkb-abc123("Finance Docs")
Exported bundle
{
"schema_version": "hrida-workflow/v1",
"name": "Invoice Agent",
"graph": {
"nodes": [
{ "id": "start", "type": "start", ... },
{ "id": "node-1", "type": "agent",
"config": { "skill_id": "uuid-finance-base" } },
{ "id": "node-2", "type": "file_search",
"config": { "knowledge_ids": ["kb-abc123"], "limit": 5 } },
{ "id": "end-1", "type": "end", ... }
],
"edges": [...]
},
"embedded_skills": [
{
"original_id": "uuid-finance-base",
"name": "Finance Base",
"system_prompt": "You are a finance expert…",
"tools": [],
"knowledge_ids": []
},
{
"original_id": "uuid-invoice-skill",
"name": "Invoice Agent [a1b2c3]",
"system_prompt": "You process supplier invoices…",
"tools": ["sql_query"],
"knowledge_ids": [],
"base_skill_original_id": "uuid-finance-base"
}
],
"knowledge_base_refs": [{ "id": "kb-abc123", "name": "Finance Docs" }],
"default_skill_original_id": "uuid-invoice-skill"
}What happens on import
| Step | Result |
|---|---|
"Finance Base" checked by name | Not found → created as new draft skill → uuid-finance-base maps to new-uuid-A |
"Invoice Agent [a1b2c3]" created | base_skill_id = new-uuid-A, knowledge_ids = [] → maps to new-uuid-B |
| Graph nodes rewritten | node-1.config.skill_id = new-uuid-A; node-2.config.knowledge_ids unchanged |
| Workflow created (draft) | Auto-creates a blank default skill |
| Default skill swapped | workflow.default_skill_id = new-uuid-B; blank skill deleted |
| Manual step | Operator opens file_search node and "Invoice Agent" skill, selects local "Finance Docs" KB |
API reference
| Method | Endpoint | Description |
|---|---|---|
GET | /api/v1/agent-workflows/{id}/export | Download the workflow bundle |
POST | /api/v1/agent-workflows/import | Create a new draft workflow from a bundle |
POST | /api/v1/agent-workflows/{id}/promote | Copy a published workflow into a target catalog/space as a new draft — { target_catalog_id?, target_space_id?, name_override? } |