Confluye
Endpoints

Workflows

Create, import, deploy, validate, review, and execute workflows via the API.

Endpoints under /api/v1/workflows. Send Authorization: Bearer. Missing/invalid token → 401. Workflow in another workspace → 403 { error: "API key cannot access this workflow" }. Missing workflow → 404.

Execute additionally requires a workspace-scoped key (403 "A workspace API key is required."), or a product gateway key for a workflow on its allowlist when the deployment enables end users (see End users).

There is no v1 collaboration API (canvas CRDT is tRPC only). Execute-step and pin-data are session /api/workflows/{id}/... only.

Endpoints

MethodPathDescription
GET/api/v1/workflowsList non-trashed workflows in the key's workspace
POST/api/v1/workflowsCreate, import, duplicate, or placeholder
GET/api/v1/workflows/{id}Get workflow; ?format=portable for export JSON
PATCH/api/v1/workflows/{id}Update, import-replace, trash, or deploy-via-status
DELETE/api/v1/workflows/{id}Delete
POST/api/v1/workflows/{id}/deployDeploy + provision webhook
POST/api/v1/workflows/{id}/executeExecute (workspace key)
GET/api/v1/workflows/{id}/statusRun status (optional runId)
GET/POST/api/v1/workflows/{id}/validateValidation + deployment readiness
GET/POST/api/v1/workflows/{id}/reviewGit review status / create proposal
GET/api/v1/workflows/{id}/versionsList versions
POST/api/v1/workflows/{id}/versions/{version}/restoreRestore version ≥ 1
GET/POST/api/v1/workflows/{id}/sync-from-repoPreview / import merged artifacts
POST/api/v1/workflows/{id}/credentials/testTest mapped credentials
POST/api/v1/workflows/{id}/credentials/bootstrap-from-envCreate credentials from server env
POST/api/v1/workflows/import-previewPreview import (no write)
POST/api/v1/workflows/validate-artifactValidate git artifact files
GET/POST/api/v1/workflows/mcp/{workspaceId}/{serverSlug}Workflow MCP server

Create, import, or duplicate

POST /api/v1/workflows branches on the JSON body (all fields optional):

FieldTypeEffect
namestringName for the new workflow
templateKeystringCreate from a built-in template
sourceWorkflowIdstringDuplicate (same workspace rules as get)
importJsonstringImport one Confluye or n8n JSON
importBundleJsonstringImport a multi-workflow bundle (upsert by n8n id)
subWorkflowPlaceholderobject{ name, workflowId?, sourceNodeId?, sourceNodeLabel? }

Empty body → blank workflow. 201. Single create: { workflow, links, ...syncedTriggers }. Bundle: { bundle, workflows[] } with importAction, importReadiness, bundleSubWorkflowStatus, links. links point at version, validate, execute, status, and portable export URLs.

The signed-in app can also create a linked setup chat when starting a built-in template. Its initial message and fixed explanation copy use the app's interface-language cookie. The bearer API above creates the workflow without that linked chat; it does not seed a setup message.

POST /api/v1/workflows/import-preview — importJson or importBundleJson required (400 otherwise). Does not persist. See Importing n8n.

Update, get, and delete

GET → { workflow, links } or portable { name, description, nodes, edges }.

In full-projection responses, workflow.collaborationSessionId identifies the source session when the graph includes an uncheckpointed collaboration draft. Use the versions endpoint to read saved versions. Collaboration mutations still require authenticated editor access through tRPC.

PATCH accepts name, description, status (draft | deployed | disabled), nodes[], edges[], importJson, trashed. Invalid status → 400. status: "deployed" runs deploy and returns the deploy failure payload on 400. Import-replace forces draft and returns importReadiness. trashed: true/false uses the trash path (in-memory trash on Prisma — see Recently deleted). DELETE → { deleted: true }.

PATCH does not accept versionMode / collaborationSessionId (those are tRPC workflows.update only).

Each edge may include an ordered zipTies array of { id, x, y } visual guides. Use the same guide ID and coordinates on multiple edges to bundle their cables, and update every edge carrying that ID when moving it. Conflicting coordinates for a shared guide ID are rejected before saving or importing. Remove the matching entry from each edge to release the bundle. Coordinates must be finite numbers; IDs must be nonempty and unique within each edge. Preserve the rest of the graph when replacing edges[]. These guides affect canvas routing only, and are retained in native JSON exports and Git artifacts.

Execute and status

POST /api/v1/workflows/{id}/execute — input?, startNodeId?, dryRun?, target? (active | candidate), executionTargetId?, expectedVersionId?, confirm?. Public API calls target active by default. Idempotency-Key supported. 202 { run, execution, queued: true, statusUrl, cancelUrl } when BullMQ accepted the job; 201 when inline (no Redis, E2E mode, or dry run). execution and run.executionEvidence identify requestedTarget, versionId, resourceMode (simulated | workspace-live), and reviewIdentity.

endUser? ({ externalId }), message? and mode? run the workflow for an end user of your product. They are accepted only from a product gateway key; any other key that sends any of them gets 400. A product gateway key must send endUser.externalId. mode is "conversation" (the default when omitted) or "event" (any other value answers 400). A conversational run also needs a non-blank message of at most 32,000 characters, and its message and the reply form the turn recorded in the end user's memory. mode: "event" runs the workflow with that end user's memory for something that happened in your product, records no conversation turn and sends no end_user.reply callback, so message is optional: an event run can omit it, and a message it does send (at most 32,000 characters) is used to rank which remembered facts are most relevant. The idempotency fingerprint covers endUser, message and mode, so the same key with another message or mode answers 409 instead of replaying (the whole fingerprint is listed below). End user runs execute the active version, are always queued (202 with statusUrl/cancelUrl under /api/v1/end-users/runs/{id}, or 503 without a queue), and return the safe run summary and outcome fields without inputs, steps or logs. See End users for the full contract.

productContext? (an object, at most 2048 bytes of JSON) is your product's context for the run, sent beside input and never inside it. It is accepted only from an end_user_gateway key with the run permission; a workspace key or another caller that sends it gets 400 with code: "product_context_requires_product_credential". This is a behavior change: workspace keys can no longer assert product context. Confluye validates its reserved fields delegationRef, usageTag, subjectExternalIds and selectedCustomerExternalId (a malformed value answers 400 with a product_context_* code; the selected customer must be one of subjectExternalIds) and keeps the rest opaque. The run stores it apart from input: it never reaches a model, the run object, logs or exports, and it is only signed into requests to the workspace's product connections. A run with productContext cannot be a dry run (400) and requires the durable workflow runtime. The idempotency fingerprint covers it, so the same key with another productContext answers 409. Find the runs a delegation started with GET /api/v1/runs?delegationRef=. A workspace API key sees every run of the workspace with that reference; a product gateway key needs the run permission and sees only end-user runs of the workflows it may run that the same API key started. Another gateway key cannot read those runs, even when its allowlist overlaps.

callbackUrl? asks Confluye to call your product back, with a signed POST, when the run ends (run.completed) and, for a conversational end user run, with its reply (end_user.reply). It is accepted from workspace and product gateway keys, and its value must be exactly a callbackUrl registered on one of the workspace's product connections; any other value answers 400 with code: "callback_url_not_registered" and creates no run. The registration is checked only when the request starts a new execution, after the idempotency check: repeating a completed request with the same Idempotency-Key returns the original receipt even if the callback URL has been removed since, so a lost response can always be recovered. A new key is checked against the current registrations. A callback URL is unique in the workspace (registering one that another connection already holds answers 409), so the value names exactly one connection, and that connection's signing secret signs the callback. The run keeps that URL and is called back only while the connection still registers it. The callback is at least once and idempotent by event ID, and carries the run's delegationRef. A run with callbackUrl cannot be a dry run (400) and requires the durable workflow runtime. The idempotency fingerprint covers it, so the same key with another callbackUrl answers 409. The callback never replaces polling: if it does not arrive, read the run, with GET /api/v1/runs/{id} for a workspace key or GET /api/v1/end-users/runs/{id} (with X-End-User-Id) for a product gateway key.

Idempotency-Key is supported. Its fingerprint covers the whole execution request: input, startNodeId, target, dryRun, expectedVersionId, executionTargetId, confirm, endUser, message, mode, productContext, callbackUrl and the API key that sent it. Repeating a key with a change to any of them answers 409 (code: "idempotency_replay_mismatch") instead of replaying the earlier run.

Repeating a completed request with the same key, principal and complete execution request (every field of the fingerprint above) returns the original execution receipt, even if the destination has since stopped, its candidate changed or its callbackUrl was unregistered. It does not execute again. Use a new key for a new execution; current version, destination and approval checks then apply. Agent execute, test and step tools follow the same replay rule.

executionTargetId selects a named preview or production destination. Its active version must have a current approval and enabled deployment for live execution. Simulations use that destination's candidate and retain its identity in execution.destination; live runs include run.executionTarget. Reusing a key for a different destination, expected version or API principal returns a conflict. A foreign or unavailable destination does not select production instead. The typed workflows.execute tool accepts the same ID.

expectedVersionId pins the version a call may run. When the target now resolves to another version, nothing starts (no run, no end user, no audit entry) and the call answers 400 with { "error": "Workflow active version changed: expected …, resolved ….", "code": "workflow_version_changed" } (it names candidate for a candidate call). The code is stable: read the current version and send a new request with it; do not parse the message. A rejected productContext answers 400 with { "error": "…", "code": "product_context_…" } (for example product_context_invalid, product_context_too_large, product_context_requires_product_credential or product_context_selected_customer_invalid); branch on the code, not the message. A 400 for any other validation failure that has no code keeps its { "error" } body only.

Candidate calls default to dry run. Live candidate execution requires dryRun: false, confirm: true, and the matching expectedVersionId. It uses real workspace resources; it is not an isolated runtime. Testing candidate v2 never changes active v1. Only deploy promotes a version.

GET /api/v1/workflows/{id}/status?runId= → { workflow, projection, run, status, queued, active, output, error, steps[], logs (last 20), links, pollAfterMs }. projection is the discriminator { kind: "workflow-status", version: 1, redacted }; keys without workspace.secret.read receive redacted: true and the safe run/workflow DTOs only (never inputs, outputs, errors, logs, node configuration, or credentials). active is true for queued | running | waiting. Unknown run → 404. Omit runId → { workflow, runs, statuses } (limit 20).

File inputs

input.fileInputs is interpreted as a selection map only when the chosen Start node defines File inputs. Otherwise it remains ordinary application input.

For a Start node with File input report, send input: { "fileInputs": { "report": ["file-id"] } }. Every ID must belong to the execution workspace and have status: "ready"; required fields, multiple selection, accepted extensions and file limits are validated before execution. The server builds one item with json and binary. The 10-file/100 MiB total limit covers the complete input, including reused descriptors, retained upstream outputs and new selections together, before live or simulated admission. Admission uses stored file sizes and checks descriptor size/checksum against the stored file. Conflicting metadata for aliases of the same file is rejected. Existing normalized items keep their JSON and binary properties. New Start selections are merged into the first item; a selected property that collides with an existing binary property is rejected instead of silently replacing it. Selections are execution input and are not persisted in node configuration. The same input.fileInputs contract applies to workflows.execute over workspace and organization MCP.

File test listeners

POST /api/v1/workflows/{id}/file-tests accepts nodeId, executionMode: "step" | "workflow" and optional executionTargetId. An authorized execution principal receives a temporary URL, listener ID and expiry. GET .../file-tests?listenerId={id} reads its state; DELETE cancels it. Only its owner with current execution permission can manage it. It captures one candidate submission in 120 seconds, then scans and simulates the selected step or workflow. It does not deploy a version.

The matching tRPC procedures are fileTestStart, fileTestStatus and fileTestCancel. MCP exposes workflows.file-test-start, workflows.file-test-status and workflows.file-test-cancel. MCP returns metadata and execution IDs without upload tokens or private entry links; obtain upload URLs through the editor or authenticated HTTP API. Organization calls must explicitly select an authorized workspace.

Deploy

Production and named previews

GET /api/v1/workflows/{id}/targets lists destination identities, candidate/active pointers, revisions and enabled state. Each destination also has sources: its RSS feeds, mail routes and Jenkins sources, and any overlaps with another destination. A Jenkins source reports its jobs, result filter, interval, lastPolledAt, paused, error and a jobStatuses entry per job with baselineBuildNumber, lastSeenBuildNumber, omittedBuildCount, paused and error. It does not return connection secrets, the Jenkins server address or draft graphs. Add ?includeHistory=true to include the latest 30 production activations in history, with activationId, targetId, versionId, numbered version, displayLabel, createdAt and canPrepareRollback. This flag identifies snapshots that can enter rollback preparation; current AIMS, connection and Git checks still decide whether publication is allowed.

POST /api/v1/workflows/{id}/targets accepts { "confirm": true, "change": { "action": "…" } } and requires an Idempotency-Key header (or idempotencyKey body field). The authenticated key needs write and execute authority. The key is bound to the authenticated principal, workflow and exact change. Replaying it returns the same receipt; a different change or principal returns 409.

ActionChange fields
prepare-productionNo additional fields
create-previewversionId, name
rename-previewtargetId, expectedRevision, name
rename-versionversionId, displayLabel (empty removes the label)
save-candidatetargetId, expectedRevision, name, nodes, edges, optional description
save-connectionstargetId, expectedRevision, bindings alias-to-credential-ID map; optional exact child dependencies and allowProductionReactivation
restore-candidatetargetId, expectedRevision, versionId
request-git-reviewtargetId, expectedRevision
prepare-promotionsourceTargetId, sourceActivationId, productionTargetId, production expectedRevision, optional stopAfter (default true)
prepare-rollbackProduction targetId, expectedRevision, historical activationId
publishtargetId, expectedRevision, versionId, UUID requestId; optional prepared source, restoreActivationId or resumeActivationId
stoptargetId, expectedRevision
configure-sourceThe source destination's expectedRevision; source: an RSS source (kind: "rss", targetId, feedUrl, optional intervalSeconds) or a Jenkins source (see below)

A Jenkins source has kind: "jenkins", targetId, the Jenkins trigger's nodeId in the destination's saved version, a credentialId, 1 to 50 jobs, optional results (omitted means every result) and optional intervalSeconds (60 to 86400, default 60). It is configured and polled as the key's user, so the credential must be one that user may use. It is refused when the workflow would start a job that the source watches on the same Jenkins server. An RSS source (and a mail route) needs a Start or plain Webhook trigger in the destination's saved version and is otherwise refused with event_source_trigger_not_found, because Jenkins, Sentry, app and schedule triggers start only from their own source. Mail and Sentry sources return a one-time secret, so you configure them in Versions & previews. A destination whose version has a Jenkins trigger cannot publish until the trigger has a source. When the destination's saved version changed after the revision you sent, the source is not stored and the request fails with 409 and workflow_target_revision_conflict; read the destination again and retry with its current revision.

Preparation keeps the current deployment running. A rollback preparation also preserves the editor candidate and returns preparedPublicationVersionId; use that historical version when requesting its approval and publication. Publication verifies the destination's current AIMS authority, Git evidence, connections and dependencies. API calls cannot grant approval. A production rollback can reuse only an approval explicitly permitting reactivation of that snapshot; otherwise prepare it and complete a new decision in Approvals.

For prepare-production and create-preview, the result also includes preparation: approvalGranted: false, publicationPerformed: false, a connections list with each required key, name, type and configured flag, nextAction, and an explanatory message. If connections are missing, call save-connections before requesting approval. These preparation receipts contain no credential IDs or secret values and do not imply that the candidate is published. The receipt describes the revision prepared by that request. Retrying with the same idempotency key returns that original receipt even if the destination has changed; read the destination again for its current state. A lost response does not create another preview when retried with the same key.

Missing connections are reported with workflow_target_connections_required; invalid or inaccessible connections and missing or unavailable child activations have separate workflow_target_* codes and corrective messages. MCP errors include retryable and the next action. An occupied AI credential lease returns local_ai_cli_credentials_busy with retryable: true instead of waiting behind the running operation during publication readiness. Retry after that operation finishes.

Blocked publication checks also include code, retryable, and nextAction when the cause is a known setup or busy-account error. Successful checks keep their usual fields.

POST /api/v1/workflows/{id}/targets/preview-publication accepts the publish fields without action and requires execute authority. It returns { ready, checks, warnings, connections, dependencies }: checks report blockers, warnings identify overlapping event sources, connections contain credential references (never secret values), and dependencies identify pinned child deployments. It is a read-only readiness check, not permission to skip revalidation on publish.

The equivalent tools are workflows.targets, workflows.preview-target-publication and workflows.update-target (with the same change object). MCP publication additionally requires its existing AIMS service-token and deployment-role checks. workflows.test and workflows.execute-step accept executionTargetId; step execution rejects a source run from another destination. Live steps run the destination's approved active version.

Using a deployed destination

In the destination panel, Use deployment opens the Use as API and Use as MCP options. Opening these options does not publish a workflow or run an execution; AIMS approval and deployment remain separate actions.

For an on destination with a target-authorized active version, the API option shows a copyable server-side request. It fixes executionTargetId, expectedVersionId, target: "active", and dryRun: false. Supply a workspace API key, a unique request ID for Idempotency-Key, and the workflow's required input. If the active version changes, obtain a new example rather than removing the version pin. Off, blocked, stopping, or legacy destinations must complete their approved deployment flow before an exact live request is offered.

The MCP option opens the existing workflow publication settings. MCP publication uses the workflow's deployed production version; named previews use the API and are not separate published MCP tools. Check publication readiness in MCP Servers; navigating there does not publish anything.

Legacy production transport

POST /api/v1/workflows/{id}/deploy validates readiness, pins the synchronized candidate, provisions a webhook, and syncs triggers. Success includes { workflow, synchronizedVersionId, webhookUrl, links: { webhook, invoke }, ...syncedTriggers }. Repository review blocks use workflow_review_not_synced, workflow_candidate_changed, or workflow_reviewed_version_unavailable. Other deploy failures → 400 with the public readiness payload.

Validate and review

GET|POST /api/v1/workflows/{id}/validate → { report, deploymentReadiness } (public: no internal env dump). POST validates a draft body without saving.

GET|POST .../review and GET|POST .../sync-from-repo: Versions & Git Review. Review POST: Member+. Sync POST: Admin/Owner.

POST /api/v1/workflows/validate-artifact { files } object or array (400 if missing).

Credentials

POST .../credentials/test → connection probe results for imported aliases. POST .../credentials/bootstrap-from-env → public bootstrap (no secret values). Workspace-wide n8n bootstrap: /api/v1/workers/n8n/credentials/bootstrap-from-env.

MCP

GET|POST /api/v1/workflows/mcp/{workspaceId}/{serverSlug} serves the workflow MCP server for that workspace slug. It always requires a bearer workspace-scoped API key bound to the stored workflow server workspace. Initialize, discovery, and listing require current read authority; tool calls require current execute authority. Personal and copilot keys are rejected, and revoked or downgraded keys lose authority at use time.

Next steps