Confluye
Building Workflows

Importing n8n

Preview, import, and migrate n8n JSON into Confluye, including lossy mappings and sub-workflows.

Confluye can ingest a single n8n workflow JSON, a multi-workflow bundle, or portable Confluye JSON. Import is lossy: n8n expressions, credentials, and unsupported nodes do not become a 1:1 runtime clone. Preview first, then connect credentials and replace blockers before deploy.

Preview before you write

POST /api/v1/workflows/import-preview requires a bearer API key. Body: importJson (one workflow) or importBundleJson (bundle). Optional name is used only as the preview base name. Missing both JSON fields returns 400. Invalid JSON returns 400 with the parser message.

Single-workflow response: { preview, workflow }. Bundle response: { bundle, workflows[] } with per-entry sourceName, sourceId, bundleSubWorkflowStatus, preview, and workflow.

preview.format is n8n or fluxus. Counts include nodeCount, edgeCount, triggerCount, outputCount, and nodeTypes[]. Typical n8n warnings:

  • Expressions become Confluye templates where the importer can rewrite them ({{input.field}} style). Remaining n8n $json / $node syntax may not evaluate.
  • If the graph has no output node, import adds a synthetic imported_output node so the graph can execute.
  • Missing trigger or output is called out explicitly.

preview.readiness is the setup checklist: missing credentials, imported n8n parameter snapshots, referenced sub-workflows, unsupported nodes, AI provider hints, and schedule/webhook review items.

Apply an import

ActionRouteAuth
Create from JSONPOST /api/v1/workflows with importJsonBearer API key
Create from bundlePOST /api/v1/workflows with importBundleJsonBearer API key
Replace an existing graphPATCH /api/v1/workflows/{id} with importJsonBearer API key; workspace must match
Server bundle pathPOST /api/v1/workers/n8n/import-bundleBearer API key
Session bundle pathPOST /api/workers/n8n/import-bundleSession cookie; workspaceId in body or session
Original subflow JSONPOST /api/v1/workers/n8n/subflows/import-originalsBearer API key

Create returns 201. Bundle create returns { bundle, workflows[] } with importAction (create vs upsert by original n8n id), importReadiness, bundleSubWorkflowStatus, trigger sync fields, and links. PATCH import forces status: "draft" and returns importReadiness. Identity (id, workspaceId) of the target workflow is preserved; imported n8n ids stay on node config (n8nWorkflowId, n8nType).

Portable Confluye JSON (GET /api/v1/workflows/{id}?format=portable) round-trips name, description, nodes, and edges only. It does not include workspace id.

How n8n nodes map

The importer inspects n8n type + node name + parameters. Positions are rounded. n8n connections become edges; loop back-edges into splitInBatches / Loop Over Items are dropped so Confluye loops stay acyclic.

n8n (examples)Confluye kindNotes
Manual Trigger, Execute Workflow TriggermanualTriggerChild graphs start as a normal manual trigger
WebhookwebhookTriggerTriggers are re-synced on save
Schedule / CronscheduleTriggerTimezone defaults from n8n settings (America/New_York if absent)
Waitwaitresume=webhook\|formmode: event; otherwise duration from amount+unit. onTimeout imports as fail. Date/until waits are not reconstructed from n8n
Respond to WebhookresponseStatus 200–599; body templated; content type forced to JSON or plain text
HTTP RequesthttpRequestLive HTTP still needs WORKFLOW_LIVE_HTTP (or workspace live transports)
Execute Workflow / Call WorkflowworkflowCallKeeps original n8n workflow id/name; input defaults to {{lastOutput}}
IF / Conditioncondition
SwitchrouterRoute labels come from n8n output names
Split In Batches / Loop Over Itemsloop
Set / Edit FieldsfunctionMapping object when fields parse
Code / FunctionfunctionLive JS is gated (see below)
Filter, Stop and Error, Extract from File, Read/Write FilefunctionDedicated operation values
OpenAI / Anthropic / LangChain / AgentaiAgentProvider/model hints only
Claude Code / Codex CLIclaudeCode / codexCliNeeds local CLI readiness
Sticky NotestickyNoteCanvas annotation; not executed
Postgres/MySQL/SQLite/Sheets/Airtable (generic)tableRead / tableWriteWrite vs read from operation name; often still needs a native table
Known Gmail/Sheets/Drive/Calendar/Docs/Jira/GitHub/Postgres query opsfunction + operationPlus optional integration manifest projection

Known integration operations also set manifestProviderId / manifestOperationId when the catalog can resolve them. Unknown n8n types still become function nodes with n8nType and a parameter snapshot. Nodes flagged unsupportedN8nNode: true (side-effect connectors without a live mapping) block deploy until you replace them. Runtime refuses those nodes with the stored n8nRecommendedMigration text.

n8n node flags map onto settings:

n8nStored settings
alwaysOutputDataalwaysOutputData
executeOnceexecuteOnce
onError continueRegularOutput / continueErrorOutput / stopWorkflowsame string

Sub-workflows

Execute Workflow nodes become workflowCall with config.workflowId equal to the original n8n id. Until a real Confluye workflow with that marker exists, the parent stays a placeholder graph: deploy is blocked. Import the child JSON (or the full bundle) so upsert can replace the placeholder while keeping n8nWorkflowId.

POST /api/v1/workflows with subWorkflowPlaceholder creates an empty child draft for an unresolved id. Bundle import reports bundleSubWorkflowStatus per parent. Reconstructed fallback children (when original JSON was missing) still need a later original-export import via /api/v1/workers/n8n/subflows/import-originals.

Credentials and code

Import does not copy n8n credential secrets. It records names/types and optional credentialBindings. Create workspace credentials, or:

  • POST /api/v1/workflows/{id}/credentials/bootstrap-from-env — per workflow, from server env
  • POST /api/v1/workers/n8n/credentials/bootstrap-from-env — workspace-wide for imported aliases (no secret values in the response)

Then POST /api/v1/workflows/{id}/credentials/test to probe connections.

Imported Code nodes stay disabled until the operator enables FLUXUS_ENABLE_WORKFLOW_CODE=true and the deployment reports the isolated Linux executor and its policy as available. Code and general JavaScript expressions then run in a fresh one-use child with serialized inputs, a 5-second Code wall/CPU budget, and bounded code, input, and output sizes. Intl time zones, Buffer, n8n input/output helpers, per-item execution, loops, and JSON normalization remain supported; asynchronous Promise results are not supported. The old FLUXUS_ALLOW_UNSAFE_WORKFLOW_CODE variable is ignored and never enables an unsafe backend. If the flag or policy is unavailable, fix or redeploy the operator environment; the application never falls back to its process. Inline secret-looking strings in code still block deploy. Convert trivial Code nodes to native array/join operations when the importer already did so.

Live side-effect transports (WORKFLOW_LIVE_* / workspace liveTransports) still apply after import. Dry-run and the n8n smoke test do not execute those external writes.

Operator checks

  1. Preview JSON; read setupChecklist and unsupportedNodeRequirements.
  2. Import bundle or originals; confirm placeholders are gone (GET .../validate).
  3. Bootstrap credentials; test them.
  4. POST /api/v1/workers/n8n/smoke-test with optional bundlePath, useQueue, waitForWorkerMs. HTTP 200 = passed, 202 = attention (readiness leftovers or queued run still waiting), 500 = failed. The audit does not run the imported graph’s live side effects.

/api/v1/workers/luminai/* mirrors the n8n worker routes for the same bundle tooling.

Limitations

  • Not every n8n node type has a native executor. Unknown types are function shells or unsupported flags.
  • Expression conversion is best-effort. Nested n8n expressions can remain invalid.
  • Wait until dates and rich webhook Wait options are not fully reconstructed.
  • Response headers from n8n are not imported (headers: {}).
  • Bundle upsert keys off original n8n workflow ids. Portable JSON without those markers will not merge into the same rows.
  • In-memory platform store (DATABASE_URL unset) loses imported workflows on process restart.

Next steps