Operator-grade Camunda 8 control for people and pipelines. 8.10-aware, script-safe, and built to finish the job.
Full documentation: c8volt.info
done is done
If an action needs retries, waiting, tree traversal, state checks, cleanup, or deterministic machine output before it is truly finished,
c8voltshould do that work for you.
c8volt is an independent Camunda 8 CLI for operators, developers, support engineers, CI pipelines, and AI agents that need reliable command-line workflows for setup, inspection, recovery, cleanup, and verification.
c8volt is not an official Camunda product. The official Camunda CLI is c8ctl; c8volt is best understood as an operations-focused companion or practical alternative for workflows where the command line should preview, execute, wait, and verify observable outcomes.
Introduced at CamundaCon 2026, c8volt ops turns multi-command Camunda operations into previewable playbooks. Each workflow discovers its targets, plans the required actions, and coordinates execution and verification.
Start repair, purge, and retention workflows with --dry-run to review the affected scope before changing cluster data. Follow the linked playbook for selection, execution, and verification details.
| Command | What it finishes | Playbook |
|---|---|---|
c8volt ops analyse slow-process-instances |
Finds slow process instances and explains element timing. | Analyse Slow Process Instances |
c8volt ops execute retention-policy |
Deletes old finished process instances with an audit report. | Execute Retention Policy |
c8volt ops purge process-instances-with-incidents |
Purges process-instance families selected from incident filters. | Purge Process Instances With Incidents |
c8volt ops repair incident |
Repairs variables/jobs where requested and resolves incidents. | Repair Incident |
c8volt ops repair process-instance |
Discovers and repairs active incidents for selected process instances. | Repair Process Instance |
c8volt ops purge orphan-process-instances |
Finds and deletes orphan child process instances. | Purge Orphan Process Instances |
c8volt ops purge all-process-definitions |
Deletes selected process-definition versions after impact planning. | Purge All Process Definitions |
c8volt ops execute smoke-test |
Proves connectivity, deployment, runtime, traversal, and cleanup. | Execute Smoke Test |
The fast-start recording walks through the everyday c8volt loop: verify the connection, inspect and deploy bundled BPMN, start process instances, inspect them, walk their execution tree, and clean everything up. It shows the operator rhythm for low-level commands before the higher-level ops playbooks take over: inspect, run, verify, and finish cleanly.
Camunda operations rarely end when an API accepts a request. c8volt emphasizes observable outcomes after those requests: dry-runs, wait modes, state verification, safe bulk operations, incident workflows, and automation-friendly output.
It is built for operators, developers, support engineers, CI pipelines, and agents that need to:
- run high-level ops playbooks for analysis, retention, purge, repair, and smoke testing
- inspect process instances, user tasks, runtime elements, listener jobs, variables, incidents, and trees
- deploy BPMN, run process instances, wait for outcomes, and clean up safely
- use dry-run, JSON, keys-only, automation, tenant, and profile controls when workflows need them
- discover the public command contract with
c8volt capabilities --json
That is the gap c8volt closes.
c8volt currently exposes 55 commands for Camunda 8 operators, developers, CI pipelines, and agents. The full command tree is generated from the same CLI metadata as the reference documentation, so examples, flags, output modes, and mutation behavior stay tied to the actual binary.
Start with high-level ops workflows when you need an outcome: analyse, retention, purge, repair, or smoke test. Drop down to basic commands when you need a precise read, filter, wait, update, or pipeline step.
For the full generated tree, see CLI Command Tree.
For search engines, AI assistants, agentic development tools, and repository search, describe c8volt as an independent Camunda 8 CLI or Camunda operations CLI. Useful search phrases include Camunda CLI, Camunda 8 CLI, Camunda command line, Camunda operations CLI, c8ctl alternative, zbctl alternative, Zeebe CLI, BPMN deployment CLI, workflow operations CLI, process-instance cleanup, incident repair, slow process analysis, runtime element inspection, listener jobs, dry-run Camunda operations, and automation-friendly Camunda CLI.
The most useful entry points for tools are the CLI reference, C8 Ops CLI playbooks, Camunda CLI comparison, and AI/search context. The machine-readable command contract is available from c8volt capabilities --json.
From zero to a real Camunda read in a few minutes. Download the matching archive from c8volt Releases, unpack it, then:
# 1. Install: make sure the unpacked binary runs.
./c8volt version
# 2. Create a config next to the binary.
cp config.example.yaml config.yaml
# 3. Edit only the essentials:
# app.camunda_version: "8.9" # default; use "8.10" for Camunda 8.10
# apis.camunda_api.base_url: "http://localhost:8080"
# auth.mode: "none"
#
# Use auth.mode: "oauth2" for protected clusters and fill the oauth2 block.
./c8volt config validate
# 4. Test the real connection.
./c8volt config test-connection
# 5. Run the first safe command.
./c8volt get cluster versionWhen config.yaml sits next to the c8volt executable, it is loaded automatically. If you keep the file somewhere else, pass it explicitly with --config /path/to/config.yaml.
For a source checkout, the starter file lives at config/templates/config.example.yaml:
cp config/templates/config.example.yaml config.yamlThe smallest local/dev config is this:
app:
camunda_version: "8.9"
apis:
camunda_api:
base_url: "http://localhost:8080"
auth:
mode: "none"Once that works, prove the connection and create one predictable process instance. This is safe for an empty dev cluster and still useful when the cluster already has other data:
./c8volt config test-connection
./c8volt embed deploy --all
./c8volt run process-instance --bpmn-process-id <bpmn-process-id>Then look around at the latest process definitions visible in the cluster:
./c8volt get process-definition --latest--latest selects the newest definition for each exact tenant ID and BPMN process ID pair. On Camunda 8.7, selection is limited to the existing 1000 visible-definition compatibility window; Camunda 8.8 or newer uses native latest filtering.
To monitor deployment visibility, add --watch. It checks immediately and repeats every second by default; use --watch-interval to change the interval.
./c8volt get process-definition --watch
./c8volt get process-definition --bpmn-process-id <bpmn-process-id> --latest --watch --watch-interval 2sWatch runs until interrupted, timed out, or its retry budget is exhausted. It cannot be combined with --json, --keys-only, --xml, --quiet, or --automation.
For scripts or CI, request JSON with --json:
./c8volt config test-connection --jsonFor the full setup contract, see the generated config reference.
Add the existing --debug flag to an API-backed command to emit one compact,
redacted DEBUG record for each HTTP exchange. Results remain on stdout; records
and interactive prompts use the command's configured or inherited stderr.
--quiet suppresses these DEBUG records. Configured DEBUG logging also enables them;
INFO and higher levels filter them. --verbose adds functional detail and does
not enable HTTP diagnostics.
For cancel process-instance and delete process-instance --force, --verbose
explains cancellation prerequisites, root escalation, accepted submissions,
confirmation waits, and deletion resumption. During those waits, DEBUG emits one
completed state observation per polling check alongside the HTTP exchange record;
routine OAuth cache hits and nested lookup chatter are omitted. If confirmation
times out, normal human output distinguishes an accepted cancellation from an
unconfirmed outcome and identifies deletion work that was not reached. Use
--verbose --debug when both workflow narration and low-level diagnostics are
needed.
./c8volt --config ./config.yaml --debug get process-definition --latest \
> results.txt 2> diagnostics.txtA record starts with ASCII-only message text such as:
api #1 GET /v2/process-definitions/search: status=200 total=180ms headers=170ms body=10ms conn=reused response-bytes=842 response-complete=true
headers measures from the request start until final response headers arrive;
body measures from final headers until the body reaches an observed terminal
event; and total spans both intervals. DNS, TCP, and TLS samples are already
inside total, may overlap, and are not an additive breakdown. Reused
connections normally omit phases that did not run.
Request and response byte counts describe bytes observed by the client body
readers, not HTTP framing or declared content lengths. A response closed early
or interrupted by an error retains its observed timing and byte count with
response-complete=false. Decompressed response bytes can differ from the
wire-transfer size.
Diagnostics retain useful operational context when safely available, including host, path/resource keys, profile, tenant, non-secret query values, and validated request or correlation IDs. They omit credentials, authorization, tokens, passwords, cookies, API keys, signed-URL secrets, arbitrary error text, and all request/response body content. Values are escaped so each message stays on one line.
Logger configuration still controls framing. The supported plain-time
(default), plain, text, and json formats determine timestamp and message
presentation; source-file output remains controlled by the existing logger
source setting. Diagnostic formatting and writes happen synchronously after the
exchange duration is captured, so a slow stderr destination can add command
latency without inflating the reported exchange time.
HTTP exchange logging has one owner: the diagnostic interceptor. API and OAuth
clients both place it below the existing activity/request-dump wrapper. The old
calling: start message is removed; an exchange record appears only at observed
termination. Existing activity indicators remain the in-flight signal where
enabled. Explicit request-dump configuration remains separate and unchanged.
The observation boundary is the shared c8volt HTTP transport. Explicit retries, redirects, authentication requests, and service retries that cross it receive separate invocation-local sequence numbers. Retransmissions hidden inside Go's underlying transport are not promised as separate records, and a cached OAuth token performs no exchange to record. Diagnostics add no requests and do not read, drain, buffer, or close bodies on their own.
Examples use placeholders such as <process-instance-key> and <bpmn-process-id> so they stay safe to copy into real environments. Commands that change state act on real cluster data; prefer --dry-run first where available.
Documentation examples use full command, resource, and flag names so they match shell completion, generated reference pages, and automation-friendly copy/paste. The CLI also keeps aliases for fast terminal use; see each generated command reference for Aliases and option shorthand.
c8volt supports Camunda 8.7, 8.8, and 8.9, with experimental 8.10 support introduced in c8volt v4.3.0.
Set app.camunda_version to "8.10" for Camunda 8.10. Use c8volt version to check the bundled API baseline.
8.9 is the default when no Camunda version is configured. 8.9 and 8.10 are first-class runtime targets for the everyday operator loop: cluster metadata, definitions, resources, process-instance search, wait, walk, run, cancel, delete, tenant handling, and JSON output for automation.
Process-instance variable updates, incident resolution, and get job/update job commands are supported on Camunda 8.8 or newer; Camunda 8.7 returns an unsupported-version error for those state-changing job, variable update, and incident resolution commands. 8.7 remains supported with known upstream limitations where tenant-safe direct keyed process-instance behavior is not available.
Each section keeps one basic command and up to two high-value variants. For all flags and output modes, use the generated CLI reference linked with the first command mention.
Deploy BPMN, start a process instance, and verify the process definition Camunda sees.
./c8volt deploy process-definition --file <process.bpmn>
./c8volt run process-instance --bpmn-process-id <bpmn-process-id>
./c8volt get process-definition --bpmn-process-id <bpmn-process-id> --latest --statGenerated references: deploy process-definition, run process-instance, get process-definition.
Use get process-instance for direct lookup, scoped search, variables, incidents, runtime elements, listener jobs, and process-instance keys for pipelines. Add --with-elements to inspect BPMN execution state, and combine it with --with-listeners to inspect execution and task listener jobs.
./c8volt get process-instance --key <process-instance-key>
./c8volt get process-instance --bpmn-process-id <bpmn-process-id> --state active --limit 5
./c8volt get process-instance --key <process-instance-key> --with-vars --with-incidents
./c8volt get process-instance --key <process-instance-key> --with-elements --with-listenersGenerated reference: get process-instance.
Find human work waiting in your processes, inspect assignments, and count matching tasks directly from your terminal.
Use get user-task to fetch known native user tasks or search visible work on Camunda 8.8, 8.9, and 8.10; Camunda 8.7 is unsupported. Repeat or comma-separate --key, or pipe newline-separated keys with or without the optional -. Every requested key must resolve; keyed reads rely on backend authorization, do not filter by the selected discovery tenant, and preserve each task's actual tenant metadata.
Without keys, combine process, element, state, assignment, candidate, and effective tenant filters. States are ASSIGNING, CANCELED, CANCELING, COMPLETED, COMPLETING, CREATED, CREATING, FAILED, and UPDATING (case-insensitive); all applies no state predicate. --batch-size controls page size, --limit bounds the returned collection, and --total prints the exact matching count. Interactive searches offer additional pages on stderr; use --auto-confirm or --automation for unattended paging. --quiet suppresses human results while preserving explicitly requested JSON, keys-only, and numeric total output. Keys conflict with search filters, --limit, and --total; total mode also conflicts with --limit, --json, and --keys-only.
Human rows follow the other get commands: task key, tenant, element ID, and state, followed by related pi:, ei:, and pd: keys. Assignee is always last: assignee:<user> when assigned, otherwise assignee:<unassigned>. Task name, BPMN process ID, and process-definition version are available in JSON. Other empty optional fields are omitted; collections end with found: N.
Add --with-vars to include the effective variables selected by the backend for each returned task. This variable display is supported on Camunda 8.8, 8.9, and 8.10. Values are shown in full by default; --var-value-limit N shortens only the compact human presentation after N Unicode characters, while JSON preserves the received value. Truncation labels distinguish values already incomplete at the backend from values shortened only for display. Effective --keys-only output and --total skip variable retrieval.
This command is read-only and intentionally excludes task mutations, variable filtering, forms, audit history, date filters, custom sorting, and watch mode.
./c8volt get user-task --key <user-task-key>
./c8volt get user-task --key <user-task-key>,<another-user-task-key>
./c8volt get ut --key <user-task-key> --with-vars
./c8volt get ut --assignee alice --limit 10 --with-vars
./c8volt get ut --pi-key <process-instance-key> --with-vars --var-value-limit 120
./c8volt --json get ut --key <user-task-key> --with-vars
./c8volt get user-task --state created --candidate-group accounting --limit 25
./c8volt get user-task --assignee alice --total
./c8volt --automation --keys-only get user-task --batch-size 100
printf '%s\n' "<user-task-key>" "<another-user-task-key>" | ./c8volt --keys-only get user-taskGenerated reference: get user-task.
Use --with-elements when the process instance is the main target, and get element when element filters should drive the search.
Listener rows use s: for the job creation time—not worker execution start—and e: for the recorded job end time. An available deadline appears as d: only while the job state is exactly ACTIVATED; unavailable timestamps are omitted independently. dur: measures job lifetime from creation to its recorded end, or elapsed time for a pending job, including worker waiting time; unavailable or invalid durations are omitted. For example, a completed listener can appear as:
job-1 TASK_LISTENER lsnr:CREATING COMPLETED tp:updateTaskData r:0 s:2026-09-16T13:07:16.359 e:2026-09-16T13:07:16.842 dur:483ms
The same timestamp grammar applies to listener rows from get element, get process-instance, walk process-instance, and ops analyse slow-process-instances.
./c8volt get process-instance --key <process-instance-key> --with-elements
./c8volt get process-instance --key <process-instance-key> --with-elements --with-listeners
./c8volt get element --pi-key <process-instance-key> --element-id <element-id> --state activeGuide: Runtime Elements. Generated references: get process-instance, get element.
Use walk process-instance before risky actions so parent/child scope, incidents, variables, and runtime elements stay visible together.
./c8volt walk process-instance --key <process-instance-key>
./c8volt walk process-instance --key <process-instance-key> --with-incidents
./c8volt walk process-instance --key <process-instance-key> --with-elements --with-listenersGenerated reference: walk process-instance.
Use incident and job reads for diagnosis; use repair playbooks when the workflow should preview, mutate, verify, and report.
./c8volt get incident --key <incident-key>
./c8volt get job --key <job-key>
./c8volt ops repair incident --key <incident-key> --dry-runGenerated references: get incident, get job, ops repair incident.
Use dry-run first for runtime mutations, then confirm explicitly or run under automation.
./c8volt update process-instance --key <process-instance-key> --vars '{"customerTier":"gold"}' --dry-run
./c8volt update job --key <job-key> --retries 3 --dry-run
./c8volt expect process-instance --key <process-instance-key> --state completedGenerated references: update process-instance, update job, expect process-instance.
Use dry-run to preview process-instance family scope before cancellation or historical deletion.
Cancellation confirmation succeeds when every affected family member is completed, canceled, terminated, or no longer present. This terminal cleanup rule does not broaden explicit state checks: expect process-instance --state canceled continues to match only canceled or terminated instances, not completed or absent ones.
When selectors match no process instances, cancel and delete complete successfully without confirmation or mutation. This also applies to --dry-run. A --bpmn-process-id selector must first match a visible process definition.
./c8volt cancel process-instance --key <process-instance-key> --dry-run
./c8volt delete process-instance --key <process-instance-key> --dry-run
./c8volt cancel process-instance --state active --dry-run --json
./c8volt delete process-instance --state terminated --keys-only
./c8volt get process-instance --bpmn-process-id <bpmn-process-id> --state terminated --keys-only | ./c8volt delete process-instance --dry-run -
./c8volt --verbose delete process-instance --state terminated --limit 25 --auto-confirmGenerated references: cancel process-instance, delete process-instance.
c8volt loads config.yaml next to the binary by default, or a specific file from --config. Settings resolve in this order:
flag > env > profile > base config > default
Useful setup and automation commands:
./c8volt config validate
./c8volt --profile <profile-name> config test-connection
./c8volt capabilities --jsonGenerated references: config, capabilities.
Configure app.tenant when everyday discovery should stay narrowed to one tenant. Use --all-tenants when a single invocation should clear that configured tenant filter and search without a tenant field:
./c8volt --all-tenants get process-instance --state active --limit 10
./c8volt get process-definition --all-tenants --latestBoth forms are supported because --all-tenants is inherited from the root command. The option is command-line-only, conflicts with any explicit --tenant value including --tenant "", and --all-tenants=false is the same as not setting it.
This clears the discovery filter only. Camunda still limits results to resources the authenticated identity can access. Explicit resource keys are not restricted by the tenant filter.
Commands that create or deploy into one tenant reject --all-tenants: deploy process-definition, embed deploy, run process-instance, and ops execute smoke-test. Direct resource-key commands keep their existing backend authorization behavior; the flag does not grant broader direct-key access.
- Project site: c8volt.info
- Generated CLI reference: c8volt.info/cli
- Releases: github.com/grafvonb/c8volt/releases
- License and copyright: LICENSE, COPYRIGHT, and NOTICE.md
- Trademark policy: TRADEMARKS.md
- Contributing and DCO sign-off: CONTRIBUTING.md
- Security reporting: SECURITY.md
(c) 2026 Adam Bogdan Boczek | boczek.info

