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