English
Bundle import
bundle:import installs, in one command, the tables and the workflows you prepared for a customer. It reads a JSON bundle on its standard input and runs inside the instance container, with the instance configuration and database. No browser and no session are needed.
bash
docker exec -i <container> node dist/cli.js bundle:import \
--owner-email admin@customer.example --dry-run < bundle.jsonOptions
| Option | Effect |
|---|---|
--owner-email ADDRESS | The member who owns the imported workflows. Must be an active member; creating tables requires an administrator. |
--team-staff ID [--team-name NAME] | Use the technical member of a back-office staff account instead, created the same way as when the staff opens the instance. |
--dry-run | Validate the whole bundle and print the report. Nothing is written. |
--prune | Delete the owner's imported workflows (those that carry a bundle key) that the bundle no longer contains. A workflow that was ever published, or that has runs, is kept and reported. Workflows created otherwise, tables, templates and files are never deleted. With --dry-run, the deletions are only announced. |
Exactly one owner option is required.
The bundle
json
{
"version": 1,
"tables": [
{
"slug": "zones",
"name": "Zones",
"description": "Department → consultant",
"columns": [
{ "key": "departement", "label": "Department", "isKey": true },
{ "key": "consultant", "label": "Consultant", "type": "email" }
],
"rows": [{ "departement": "74", "consultant": "jp@customer.example" }]
}
],
"documentTemplates": [
{ "key": "certificate", "name": "Visit certificate", "description": "Signed by the agency.",
"fileName": "certificate.docx", "contentBase64": "UEsDBBQ…" }
],
"files": [
{ "key": "questionnaire", "name": "Owner questionnaire", "fileName": "questionnaire.pdf",
"mime": "application/pdf", "contentBase64": "JVBERi0…" }
],
"workflows": [
{
"key": "routing",
"name": "Route incoming requests",
"description": "Shown as a sticky note above the graph.",
"minutesSavedPerRun": 6,
"dsl": {
"nodes": [
{ "id": "trigger", "type": "trigger.email", "name": "Email received", "params": {} },
{ "id": "zone", "type": "table.find", "name": "Consultant",
"params": { "table": { "mode": "id", "value": "zones" },
"key": [{ "column": "departement", "value": "74" }] } }
],
"edges": ["trigger>zone"]
}
}
]
}- Tables use the same column types as the interface (
text,number,boolean,date,datetime,select,email). Rows are converted exactly like any table write. - Workflows are written either as
dsl(nodes and edges writtenfrom>toorfrom:port>to; positions are computed) or asgraph, a full workflow document as exported by the product. - Document templates are Word files (
.docx, base64, 10 MB at most) added to the instance library (Templates › Document templates). They need a documents service. Adocument.generatenode designates a template of the bundle by its key in itstemplateparameter ({ "mode": "id", "value": "certificate" }): it is replaced by the identifier of the imported template. Each template is checked with the same parser as an upload. - Files go to the instance library (Templates › Files) and are attached by « Send » nodes as fixed attachments: a
mail.sendnode designates a file of the bundle by its key infiles([{ "file": { "mode": "id", "value": "questionnaire" } }]). 10 MB per file. - A node designates a table by its slug. A
workflow.callnode designates another workflow of the bundle by its key: it is replaced by the identifier of the imported workflow.
What the command guarantees
- Validation before any write. The bundle format, every cell, every key, the instance limits and every workflow graph are checked first, with the same validator as publishing. One error and nothing is written.
- Drafts only. Workflows are created or updated as drafts and never published. A workflow the customer already published keeps its published version: the import saves a new draft next to it.
- Replays without duplicates. A table is matched by its slug, a row by its key, a document template, a file and a workflow by their key in the bundle. Running the same bundle twice updates what the first run created. An update merges: a column absent from the bundle keeps its value.
- Missing connections are not errors. A required connection or resource left empty (a Microsoft 365 connection, the sending mailbox of a scheduled workflow, a MyNotary organisation) is listed as
pendingin the report: the workflow stays an incomplete draft until the customer connects their accounts. AI nodes with no provider wired use the instance default model.
The report
The command prints one JSON line:
| Field | Content |
|---|---|
ok, dryRun, owner | The outcome, the mode, the owner member |
tables[] | slug, action (create or update), addedColumns, rows (planned, inserted, updated, skippedNoKey) |
documentTemplates[] | key, action, id, fields (the number of fields found in the template) |
files[] | key, action, id |
pruned[] | key, id, outcome (deleted, would_delete, kept_published, kept_has_executions) |
workflows[] | key, action, id, pending[] (node and parameter to complete), warnings[] |
errors[] | where (bundle, table:<slug>, documentTemplate:<key>, workflow:<key>), code, message |
Exit codes: 0 done (or validated), 2 usage error, 3 refused (invalid bundle or JSON, unknown member), 1 unexpected error.
Limits
- Without
--prune, nothing is deleted. With it, only imported workflows that were never published are. - A column type is never converted by an import: change it in the interface first.
- A bundle is read from standard input, up to 32 MB.