CLI
Push, pull, and search artifacts from a terminal, a Dockerfile, or a CI step with afk
Install
pip install "artefaktum[cli]"
This installs artefaktum, and the shorter alias afk, both pointing at the same command. It needs Python 3.10+, same as the SDK it wraps.
Authenticate
artefaktum login # or set ARTEFAKTUM_API_KEY in CI and sandboxes
login prompts for the key at a hidden prompt (or reads it from stdin with --api-key-stdin), verifies it against the server, then saves it to ~/.config/artefaktum/config.json ($XDG_CONFIG_HOME, or %APPDATA%\artefaktum on Windows), mode 0600. The key is never taken as a positional argument, so it never lands in shell history.
logout removes the saved config file.
For every setting (the API key, --base-url, --project), precedence is: the matching flag, then the matching environment variable (ARTEFAKTUM_API_KEY, ARTEFAKTUM_BASE_URL, ARTEFAKTUM_PROJECT), then the saved config file. In CI and sandboxes, prefer ARTEFAKTUM_API_KEY over login (no writable home directory needed) or --api-key (visible in ps to other users on the host).
whoami shows the tenant, and project if the key is scoped to one:
artefaktum whoami
API keys themselves are created in the console at https://artefaktum.dev/console/. The CLI has no keys create (or any keys/usage command); it only consumes a key that already exists.
Commands
| Command | Purpose |
|---|---|
whoami |
show the tenant (and project) the key belongs to |
projects |
list the tenant’s projects |
login |
verify an API key and save it |
logout |
remove the saved API key |
get |
show one artifact, by ID or --key |
ls |
list artifacts |
search |
search artifacts |
push |
upload a file as a new artifact |
pull |
download an artifact’s latest version |
rm |
delete an artifact |
link |
print a short-lived signed download URL |
relations |
list an artifact’s relations |
relate |
record a relation from one artifact to another |
versions |
list an artifact’s versions |
resolve |
get-or-create an artifact by external key |
run new |
create a run |
run seal |
seal a run so no more artifacts attach to it |
run ls |
list a run’s artifacts |
Global options, given before the command: --api-key, --base-url, --project, --json / --table (force the output format), plus --version and -h/--help. artefaktum --help and artefaktum <command> --help list every command and flag.
Command reference
get ID / get --key KEY: show one artifact. Exactly one of ID or --key EXTERNAL_KEY is required.
ls: list artifacts. --tag TAG, --status STATUS (repeatable), --limit N (default 50), --all (follow every page instead of one).
search QUERY: --mode hybrid|text|semantic|exact (default hybrid), --tag TAG (repeatable, required tag), --limit N (default 10), --history (include superseded artifacts, excluded by default).
push FILE: --title (required), --tag (repeatable), --description, --key EXTERNAL_KEY, --meta K=V (repeatable), --expires DURATION (e.g. 30d), --run RUN_ID, --no-wait (return once accepted, don’t wait for ready), --timeout SECONDS (default 30).
Field sizes are limited; see Limits.
pull ID [DEST]: DEST defaults to .; a trailing / creates it as a directory. --no-verify skips the sha256 check.
rm ID: delete an artifact. No flags.
link ID: print a signed download URL. --table mode prints exactly the URL and nothing else.
relations ID / versions ID: list an artifact’s relations or versions. No flags.
relate ID TARGET: --type (derived_from (default), supersedes, attachment_of, generated_by, or related_to).
resolve KEY: --file (required), --title (required), --tag (repeatable), --description, --meta K=V (repeatable), --max-age DURATION (an existing artifact older than this is treated as stale), --wait SECONDS (default 60, retried while another writer holds the reservation). Prints hit (nothing uploaded), created (uploaded --file), or exits 4 if still pending after --wait.
run new [RUN_ID]: RUN_ID is optional; the server assigns one if omitted.
run seal RUN_ID / run ls RUN_ID: run ls takes --limit N (default 50).
Duration flags (--expires, --max-age) accept 90s, 30m, 12h, 30d, 2w, or a bare integer of seconds.
Exit codes
| Code | Meaning |
|---|---|
| 0 | ok |
| 1 | API or SDK error |
| 2 | usage error |
| 3 | not found |
| 4 | resolve still pending when --wait ran out |
| 130 | interrupted |
Recipes
Dockerfile or sandbox image: bake the CLI in and read the key from the environment at run time, never at build time.
RUN pip install "artefaktum[cli]"
# ARTEFAKTUM_API_KEY is supplied by the container's runtime environment, not baked in
GitHub Actions step:
- run: pip install "artefaktum[cli]"
- run: afk push report.pdf --title "Q3 churn" --tag churn
env:
ARTEFAKTUM_API_KEY: ${{ secrets.ARTEFAKTUM_API_KEY }}
Push before a container is recycled: an agent working in a sandbox or CI job that’s about to be torn down should push its output as its last step, so the artifact outlives the container.
afk push /tmp/output.json --title "Run output" --run "$RUN_ID"
Scripting with JSON: output is an aligned text table on a terminal and one JSON document otherwise, so a plain pipe already gets JSON.
artefaktum ls | jq -r '.items[].id' # one page
artefaktum ls --all | jq -r '.[].id' # every match, as a bare array
Pass --json explicitly when the command’s stdout might still look like a terminal to it (for example, inside another program that captures output), rather than relying on the auto-detection.
Push only if it isn’t already there, without resolve:
artefaktum get --key vendor-x/report/2026-09 >/dev/null \
|| artefaktum push report.json --title "Vendor X report" --key vendor-x/report/2026-09
This page as Markdown: /docs/cli.md