Etlworks CLI
A built-in, scriptable command-line environment inside the Etlworks UI — plus a single REST endpoint that runs the same commands programmatically. 137 commands, inline SQL on JSON output, capture variables, control structures, parallel execution.
The built-in CLI documented here runs inside Etlworks (Command Editor + REST endpoint). It manages metadata, flows, data, and automation under the calling user's permissions. A separate External Etlworks CLI exists for system administration (upgrades, backups, services) and is documented in the support center.
137 commands
Flows, executions, schedules, connections, formats, macros, webhooks, on-prem agents, audit, tags, users, tenants, inline SQL, JavaScript — everything platform-side has a command.
Inline SQL on JSON
list-flows select id,name where flowType like '%cdc%' order by name. SELECT, FROM (array flattening), WHERE, ORDER BY, LIMIT, plus scalar & time-helper functions on any command's output.
Capture & variables
Pipe any JSON value into a variable with | capture var=stdout.field, then use it in subsequent commands as {var}. Multi-step automation in a few lines.
Control structures
if with full boolean expressions and JSON-path access. for-each (x in xs) { … } over arrays. Nest them, compose with capture and SQL.
Parallel & redirects
Append & to run a command asynchronously without blocking the script. Append >> filename to save stdout (and stderr) to the tenant's data folder — subfolders auto-created.
Same security model as the UI
Each command runs as the calling user. Roles (Viewer / Operator / Editor / Admin / Super Admin) gate which commands you can use. Destructive ops require --force. Every invocation lands in the audit log.
See it in action
Three real shapes from production scripts — bulk-export every flow that matches a name, find recently failing flows, and update every enabled agent in one shot.
// Capture every flow whose name matches "script", then dump each flow's
// configuration to a JSON file in the tenant's backup/ folder.
list-flows --silent where name like "%script%" | capture flows=stdout;
for-each (f in flows) {
get-flow {f.id} >> backup/{f.name}.json;
};
// Last 10 days of failed executions across all tenants. Inline SQL filters
// the JSON output and projects only the columns you want.
flow-executions-aggregated tenants=all offset=1 includeMetrics=true
select flowId, eventName, tenantId, status, user,
date(started) started, date(ended) ended, exception
from executions
where status != "success"
and started > ts("now - 10d")
order by auditId desc
limit 50;
// Roll out the latest agent build to every enabled agent in every tenant.
list-agents scope=all select id, name where enabled=true | capture agents=stdout;
for-each (agent in agents) {
update-agent {agent.id} --force;
};
# Same surface, different transport. POST /v1/cli with the script as a single
# string. Returns an array of CliResponse: { command, stdout, stderr, exitCode }.
curl -s -X POST "$ETLWORKS_URL/v1/cli" \
-H "Authorization: Bearer $ETLWORKS_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"command": "list-flows --silent where name like \"%script%\" | capture flows=stdout; for-each (f in flows) { get-flow {f.id} >> backup/{f.name}.json; };"
}'