Skip to main content

import-cloudflow-flow

dci import-cloudflow-flow [body] [flags]

Creates every flow of a previously exported bundle in the authenticated tenant. Imports are create-only: each call creates new draft flows with new IDs — nothing is published and no schedule is activated until the target tenant publishes.

Requirements declared by the bundle are resolved through bindings (requirement key → target-tenant resource ID). Unbound connections and Datastore tables leave the referencing nodes flagged incomplete; unbound global variables are auto-created. Pass options.createMissingTables: true to create missing Datastore tables from the schemas embedded in the bundle (structure only, never row data).

Dry-run: pass ?dryRun=true to validate without writing. The response is an import plan: per-requirement resolutions with candidate bindings in the target tenant, the flows that would be created, and every validation issue at once.

Pass the request body as name: value arguments or pipe JSON on stdin — see Command structure.

CLI behavior
  • A bare bundle is wrapped for you. Piping the output of export-cloudflow-flow straight in works: the CLI nests it under the request's bundle field. Send the full bundle / bindings / options shape only when you need bindings or options.
  • --dry-run is the API's dry run, not a local preview: the request is sent, nothing is written, and the response is the import plan. The CLI generates a throwaway idempotency key for dry runs, so --idempotency-key is only needed on the real import — where the API requires it (idempotency_key_required). Generate a fresh one per import; re-sending the same key returns the cached response instead of importing again.
Authoring loop

Imports are create-only and land as drafts. Requirement keys for bindings come from the dry-run plan (or the bundle's requirements); connection IDs come from dci list-cloudflow-connections. Unbound connections and tables leave their nodes flagged incomplete; unbound global variables are created automatically. After importing, validate and exercise the draft with dci test-run-cloudflow-flow.

Examples

# Validate a bundle first — writes nothing and returns the import plan.
dci import-cloudflow-flow --dry-run < bundle.json
`valid`, every validation `error` at once, the `flowsToCreate`, and each requirement's `resolution` (`bound`, `suggested`, `willCreate`, or `unbound`) with candidate IDs in this tenant.
# Import for real; a fresh idempotency key is required on every real import.
dci import-cloudflow-flow --idempotency-key "$(uuidgen)" < bundle.json
`flows[]` with each created flow's new `id`, `status: draft`, and any `incompleteNodes` to finish in the builder before publishing.
# Bind a connection requirement and set import options by sending the full request shape.
dci import-cloudflow-flow --idempotency-key "$(uuidgen)" < import.json
# import.json — the exported bundle under "bundle", plus bindings and options
{"bundle": {"kind": "cloudflow.doit.com/FlowBundle", "schemaVersion": 1, "rootFlow": "main",
"flows": [{"key": "main", "name": "Nightly cleanup", "firstNode": "trigger",
"nodes": [{"key": "trigger", "name": "Manual trigger", "type": "manualTrigger"}]}],
"requirements": {"connections": [{"key": "aws-main", "name": "AWS production", "provider": "amazon-web-services"}]}},
"bindings": {"connections": {"aws-main": "<connection-id>"}},
"options": {"createMissingTables": true, "namePrefix": "Copy of "}}

Request

Content-Type: application/json

FieldTypeRequiredDescription
bundleobjectyesPortable, tenant-neutral export of one or more flows. Contains no credentials, tenant identifiers, schedules, or execution state; tenant-scoped references are declared under requirements and appear inside node parameters as $req:&lt;section&gt;/&lt;key&gt; tokens (subflow references as $bundle:flows/&lt;flowKey&gt;).
bundle.kindstringyesOne of: "cloudflow.doit.com/FlowBundle".
bundle.schemaVersionintegeryesBundle format version. The server exports the newest version and accepts every version it has ever shipped. One of: 1.
bundle.exportedAtstring (date-time)Informational export timestamp; ignored on import.
bundle.rootFlowstringyesKey (into flows) of the flow that was exported; the rest are its subflows.
bundle.flowsarray of objectyes
bundle.flows[].keystringyesBundle-local flow key. Opaque — the server generates new IDs at import.
bundle.flows[].namestringyes
bundle.flows[].descriptionstring
bundle.flows[].tagsmap of array of string
bundle.flows[].triggerTypestring
bundle.flows[].firstNodestringyesKey of this flow's entry node.
bundle.flows[].nodesarray of objectyes
bundle.flows[].nodes[].keystringyes
bundle.flows[].nodes[].namestringyes
bundle.flows[].nodes[].descriptionstring
bundle.flows[].nodes[].typestringyesNode type (e.g. triggerNode, actionNode, datastoreNode). Validated against the supported node-type set at import.
bundle.flows[].nodes[].parametersobjectNode parameters with tenant-scoped scalar references replaced by $req:/$bundle: tokens.
bundle.flows[].nodes[].approvalobjectApproval configuration without recipients (recipients are tenant-scoped and removed at export). Nested fields omitted — see the raw JSON schema.
bundle.flows[].nodes[].transitionsarray of objectNested fields omitted — see the raw JSON schema.
bundle.flows[].localVariablesarray of object
bundle.flows[].localVariables[].keystringyes
bundle.flows[].localVariables[].namestringyes
bundle.flows[].localVariables[].descriptionstring
bundle.flows[].localVariables[].requiredboolean
bundle.flows[].localVariables[].typestringyes
bundle.flows[].localVariables[].elementTypestring
bundle.flows[].localVariables[].valuestringPresent unless the export stripped variable values. Connection-typed values are $req:connections/&lt;key&gt; tokens.
bundle.flows[].unsupportedReferencesarray of objectTenant-scoped references removed at export (policy IDs, Slack channels); import flags the affected nodes incomplete.
bundle.flows[].unsupportedReferences[].nodeKeystringyes
bundle.flows[].unsupportedReferences[].kindstringyesOne of: "policy", "slackChannel".
bundle.flows[].unsupportedReferences[].detailstring
bundle.requirementsobjectTenant-scoped resources the bundle needs; each is bound to a target-tenant resource at import.
bundle.requirements.connectionsarray of object
bundle.requirements.connections[].keystringyes
bundle.requirements.connections[].providerstringyesCloud provider the bound connection must have (e.g. amazon-web-services).
bundle.requirements.connections[].namestringyesThe source connection's display name, as a matching hint.
bundle.requirements.connections[].usedByNodesarray of string
bundle.requirements.datastoreTablesarray of object
bundle.requirements.datastoreTables[].keystringyes
bundle.requirements.datastoreTables[].namestringyes
bundle.requirements.datastoreTables[].descriptionstring
bundle.requirements.datastoreTables[].fieldsarray of objectyesNested fields omitted — see the raw JSON schema.
bundle.requirements.datastoreTables[].usedByNodesarray of string
bundle.requirements.globalVariablesarray of object
bundle.requirements.globalVariables[].keystringyes
bundle.requirements.globalVariables[].namestringyes
bundle.requirements.globalVariables[].descriptionstring
bundle.requirements.globalVariables[].typestringyes
bundle.requirements.globalVariables[].elementTypestring
bundle.requirements.globalVariables[].valuestringPresent unless the export stripped variable values.
bundle.requirements.globalVariables[].usedByNodesarray of string
bindingsobjectRequirement key → target-tenant resource ID. Keys must be declared in the bundle's requirements. Run with ?dryRun=true first to list required keys and candidate IDs.
bindings.connectionsmap of string
bindings.datastoreTablesmap of string
bindings.globalVariablesmap of string
optionsobject
options.createMissingTablesbooleanCreate unbound Datastore tables from the schemas embedded in the bundle (structure only, never row data). A same-named existing table with an incompatible schema is a validation error. Default: false.
options.namePrefixstringOptional prefix for every created flow's name.
Raw JSON schema
{
"type": "object",
"required": [
"bundle"
],
"properties": {
"bundle": {
"type": "object",
"description": "Portable, tenant-neutral export of one or more flows. Contains no credentials, tenant identifiers, schedules, or execution state; tenant-scoped references are declared under `requirements` and appear inside node parameters as `$req:<section>/<key>` tokens (subflow references as `$bundle:flows/<flowKey>`).",
"required": [
"kind",
"schemaVersion",
"rootFlow",
"flows"
],
"properties": {
"kind": {
"type": "string",
"enum": [
"cloudflow.doit.com/FlowBundle"
]
},
"schemaVersion": {
"type": "integer",
"description": "Bundle format version. The server exports the newest version and accepts every version it has ever shipped.",
"enum": [
1
]
},
"exportedAt": {
"type": "string",
"format": "date-time",
"nullable": true,
"description": "Informational export timestamp; ignored on import."
},
"rootFlow": {
"type": "string",
"description": "Key (into `flows`) of the flow that was exported; the rest are its subflows."
},
"flows": {
"type": "array",
"maxItems": 20,
"items": {
"type": "object",
"required": [
"key",
"name",
"firstNode",
"nodes"
],
"properties": {
"key": {
"type": "string",
"description": "Bundle-local flow key. Opaque — the server generates new IDs at import."
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"tags": {
"type": "object",
"additionalProperties": {
"type": "array",
"items": {
"type": "string"
}
}
},
"triggerType": {
"type": "string",
"nullable": true
},
"firstNode": {
"type": "string",
"description": "Key of this flow's entry node."
},
"nodes": {
"type": "array",
"maxItems": 150,
"items": {
"type": "object",
"required": [
"key",
"name",
"type"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string",
"description": "Node type (e.g. `triggerNode`, `actionNode`, `datastoreNode`). Validated against the supported node-type set at import."
},
"parameters": {
"type": "object",
"additionalProperties": true,
"description": "Node parameters with tenant-scoped scalar references replaced by `$req:`/`$bundle:` tokens."
},
"approval": {
"type": "object",
"description": "Approval configuration without recipients (recipients are tenant-scoped and removed at export).",
"properties": {
"required": {
"type": "boolean"
},
"message": {
"type": "string"
},
"rejectApprovalAfterTime": {
"type": "boolean"
},
"rejectTimeValue": {
"type": "integer"
},
"rejectTimeUnit": {
"type": "string"
}
}
},
"transitions": {
"type": "array",
"items": {
"type": "object",
"required": [
"target"
],
"properties": {
"target": {
"type": "string",
"description": "Key of the node this transition points at."
},
"label": {
"type": "string",
"nullable": true
},
"pathId": {
"type": "string",
"nullable": true
}
}
}
}
}
}
},
"localVariables": {
"type": "array",
"maxItems": 50,
"items": {
"type": "object",
"required": [
"key",
"name",
"type"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"required": {
"type": "boolean"
},
"type": {
"type": "string"
},
"elementType": {
"type": "string"
},
"value": {
"type": "string",
"description": "Present unless the export stripped variable values. Connection-typed values are `$req:connections/<key>` tokens."
}
}
}
},
"unsupportedReferences": {
"type": "array",
"description": "Tenant-scoped references removed at export (policy IDs, Slack channels); import flags the affected nodes incomplete.",
"items": {
"type": "object",
"required": [
"nodeKey",
"kind"
],
"properties": {
"nodeKey": {
"type": "string"
},
"kind": {
"type": "string",
"enum": [
"policy",
"slackChannel"
]
},
"detail": {
"type": "string"
}
}
}
}
}
}
},
"requirements": {
"type": "object",
"description": "Tenant-scoped resources the bundle needs; each is bound to a target-tenant resource at import.",
"properties": {
"connections": {
"type": "array",
"maxItems": 50,
"items": {
"type": "object",
"required": [
"key",
"provider",
"name"
],
"properties": {
"key": {
"type": "string"
},
"provider": {
"type": "string",
"description": "Cloud provider the bound connection must have (e.g. `amazon-web-services`)."
},
"name": {
"type": "string",
"description": "The source connection's display name, as a matching hint."
},
"usedByNodes": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"datastoreTables": {
"type": "array",
"maxItems": 50,
"items": {
"type": "object",
"required": [
"key",
"name",
"fields"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"fields": {
"type": "array",
"items": {
"type": "object",
"required": [
"name",
"dataType"
],
"properties": {
"name": {
"type": "string"
},
"dataType": {
"type": "string"
},
"isUnique": {
"type": "boolean"
},
"description": {
"type": "string"
}
}
}
},
"usedByNodes": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
},
"globalVariables": {
"type": "array",
"maxItems": 50,
"items": {
"type": "object",
"required": [
"key",
"name",
"type"
],
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"description": {
"type": "string"
},
"type": {
"type": "string"
},
"elementType": {
"type": "string"
},
"value": {
"type": "string",
"description": "Present unless the export stripped variable values."
},
"usedByNodes": {
"type": "array",
"items": {
"type": "string"
}
}
}
}
}
}
}
}
},
"bindings": {
"type": "object",
"description": "Requirement key → target-tenant resource ID. Keys must be declared in the bundle's requirements. Run with `?dryRun=true` first to list required keys and candidate IDs.",
"properties": {
"connections": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"datastoreTables": {
"type": "object",
"additionalProperties": {
"type": "string"
}
},
"globalVariables": {
"type": "object",
"additionalProperties": {
"type": "string"
}
}
}
},
"options": {
"type": "object",
"properties": {
"createMissingTables": {
"type": "boolean",
"default": false,
"description": "Create unbound Datastore tables from the schemas embedded in the bundle (structure only, never row data). A same-named existing table with an incompatible schema is a validation error."
},
"namePrefix": {
"type": "string",
"description": "Optional prefix for every created flow's name."
}
}
}
}
}

Flags

FlagTypeDefaultExampleDescription
--dry-runbooleanfalseIf true, validates the bundle and resolves its requirements against the tenant without committing changes, returning the import plan.

Every command also accepts the CLI-wide flags for output shaping — see Output formats and Table output options.

Output

Dry-run import plan (no writes performed).

By default dci renders the result as a table. Use --output json to get the full structure described below — see Output formats.

FieldTypeDescription
validboolean
requirementsarray of object
requirements[].sectionstringOne of: "connections", "datastoreTables", "globalVariables".
requirements[].keystring
requirements[].resolutionstringOne of: "bound", "suggested", "willCreate", "unbound".
requirements[].boundTostring
requirements[].candidatesarray of object
requirements[].candidates[].idstring
requirements[].candidates[].namestring
requirements[].candidates[].providerstring
requirements[].consequenceIfUnboundstring
flowsToCreatearray of object
flowsToCreate[].keystring
flowsToCreate[].namestring
flowsToCreate[].nodeCountinteger
flowsToCreate[].incompleteNodeCountinteger
errorsarray of object
errors[].codestringOne of: "bundle_schema_invalid", "bundle_version_unsupported", "bundle_limits_exceeded", "binding_not_found", "binding_provider_mismatch", "table_schema_incompatible", "global_variable_type_conflict", "internal_field_rejected".
errors[].fieldstring
errors[].messagestring
Raw JSON schema
{
"type": "object",
"description": "Dry-run result — what an import of this request would do, with every validation issue reported at once.",
"required": [
"valid",
"requirements",
"flowsToCreate",
"errors"
],
"properties": {
"valid": {
"type": "boolean"
},
"requirements": {
"type": "array",
"items": {
"type": "object",
"required": [
"section",
"key",
"resolution"
],
"properties": {
"section": {
"type": "string",
"enum": [
"connections",
"datastoreTables",
"globalVariables"
]
},
"key": {
"type": "string"
},
"resolution": {
"type": "string",
"enum": [
"bound",
"suggested",
"willCreate",
"unbound"
]
},
"boundTo": {
"type": "string"
},
"candidates": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string"
},
"name": {
"type": "string"
},
"provider": {
"type": "string"
}
}
}
},
"consequenceIfUnbound": {
"type": "string"
}
}
}
},
"flowsToCreate": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string"
},
"name": {
"type": "string"
},
"nodeCount": {
"type": "integer"
},
"incompleteNodeCount": {
"type": "integer"
}
}
}
},
"errors": {
"type": "array",
"items": {
"type": "object",
"required": [
"code",
"message"
],
"properties": {
"code": {
"type": "string",
"enum": [
"bundle_schema_invalid",
"bundle_version_unsupported",
"bundle_limits_exceeded",
"binding_not_found",
"binding_provider_mismatch",
"table_schema_incompatible",
"global_variable_type_conflict",
"internal_field_rejected"
]
},
"field": {
"type": "string"
},
"message": {
"type": "string"
}
}
}
}
}
}

Errors

On failure, dci prints a single error message — with a hint when one is available — and exits with a typed code your scripts can branch on. See Errors and exit codes for the full contract.

HTTP status to exit code mapping
HTTP statusExit codeError codeMeaning
400, 42230VALIDATION_ERRORThe arguments or request body were rejected. Review the command's flags and payload.
40110AUTHENTICATION_FAILEDNot signed in, or the API token is invalid. Run dci login or check DCI_API_KEY.
40311PERMISSION_DENIEDThe DoiT user or the active customer context does not have access.
50040API_SERVER_ERRORThe API failed to process the request. Retryable; contact DoiT support if it persists.

Aliases: importcloudflowflow