The fun CLI
The fun CLI lets you manage Fundamentum from your terminal and your scripts. This guide shows you how to install it, sign in, work with several environments, use the curated commands, and call any Public API operation with fun api.
Before you begin
- You have a Fundamentum account with access to at least one project. See Authentication.
- You know your project ID. The Hub shows it.
- For scripting examples,
jqis handy but optional.
1. Install the CLI
Download the archive for your platform from https://cli.fundamentum-iot.com:
| Platform | Archive |
|---|---|
| Linux (amd64) | fundamentum-cli-linux-amd64-<version>.zip |
| macOS (Apple silicon, arm64) | fundamentum-cli-mac-arm64-<version>.zip |
| Windows (386) | fundamentum-cli-windows-386-<version>.zip |
On Linux and macOS, extract the fun binary and put it on your PATH:
unzip fundamentum-cli-mac-arm64-<version>.zip
chmod +x fun
sudo mv fun /usr/local/bin/fun
On macOS, Gatekeeper may block the binary the first time you run it because it was downloaded from the internet. Allow it in System Settings → Privacy & Security.
On Windows, the archive contains fun.exe. Extract it to a folder on your PATH.
Check the installation:
fun --version
Check for a newer release at any time with fun check-update. To upgrade, download the new archive and replace the binary.
Optionally, enable shell completion, which also completes the fun api commands:
source <(fun completion zsh)
Replace zsh with bash, fish or powershell. See fun completion <shell> --help to install it permanently.
2. Sign in
fun login
The CLI asks for:
- a context name: press Enter for
default; - the API endpoint: press Enter for
https://api.fundamentum-iot.com; - the OAuth endpoint: press Enter for
https://oauth.fundamentum-iot.com.
Your browser opens on the Fundamentum sign-in page, where you sign in as usual, including with single sign-on. The CLI then saves your token in contexts.json in its configuration directory. fun config dir prints where that is.
When the token expires, run fun login again and give the same context name: the CLI refreshes the token and keeps your endpoints.
3. Use a context per environment
A context is a named set of endpoints and a token. Create one per environment or account:
fun login # answer "staging" to the context prompt, then the staging endpoints
fun config contexts list
Select a context with --context on any command that calls Fundamentum. Without it, the CLI uses default:
fun functions list --project <project-id> --context staging
To change the endpoints of an existing context, run fun login --override.
4. Use the curated commands
Curated commands cover tasks that need more than one API call. Their names are versioned with the CLI, so they are the right choice for scripts that must keep working.
Forward a port of a device to your machine, for example to reach its web server on port 80 at localhost:8080:
fun devices port-forward -p <project-id> -r <registry-id> -s <serial-number> -l 8080 -d 80
Press any key to stop forwarding. See Remote terminal and port forwarding.
Send a file to a device, and fetch one back:
fun devices transfer cloud-to-device -p <project-id> -r <registry-id> -s <serial-number> \
--file ./config.bin --remote-path /etc/app/config.bin
fun devices transfer device-to-cloud -p <project-id> -r <registry-id> -s <serial-number> \
--remote-path /var/log/app.log --name app.log
The local file must be a relative path inside the current directory. See File transfers.
Create, upload and invoke a cloud function:
fun functions new decoder --project <project-id> --language go --description "Decode sensor frames"
fun functions upload decoder ./decoder.wasm
echo '{"frame":"0a1b"}' | fun functions invoke --name decoder
fun functions executions list --name decoder
decoder is a local name the CLI saves in functions.json, so you don't need to repeat the project and function IDs. See Cloud functions.
5. Call any Public API operation with fun api
fun api exposes every operation of the Public API, generated from its OpenAPI specs. New operations become available without a new CLI release.
Download the specs once, and again whenever you need newly published operations:
fun api refresh
Discover the operations, from the version down to the operation:
fun api v1 --help
fun api v1 device --help
fun api v1 device get-device --help
Call an operation. Path parameters are required flags, and every parameter is a kebab-case flag:
fun api v1 device get-device --project-id <project-id> --device-id <device-id>
Send a body inline, from a file, or from stdin:
fun api v2 service-accounts create-service-account --project-id <project-id> \
--body-file service-account.json
Group and operation names come from the spec, so they can change when the specs change. Use fun api for exploration and one-off calls, and prefer curated commands in long-lived automation.
6. Script with the CLI
The CLI keeps stdout for JSON so you can pipe it:
- Response JSON goes to stdout. The active context and the HTTP status go to stderr.
--data-onlyprints only thedatafield of the response envelope.--dry-runprints the request without sending it.- In a terminal, paginated lists open an interactive pager. In scripts, pass
--page <n>or--data-only.
fun api v2 licenses list-licenses --project-id <project-id> --data-only | jq '.[].id'
fun api v1 device list-devices --project-id <project-id> --page 1 > devices.json
fun api v2 registries create-registry --project-id <project-id> --body-file registry.json --dry-run
In CI, avoid the browser sign-in: define the context with environment variables and a service-account token:
export FUN_CONTEXT_FUNDAMENTUM_IOT_ENDPOINT=https://api.fundamentum-iot.com
export FUN_CONTEXT_API_KEY="$SERVICE_ACCOUNT_TOKEN"
fun functions invoke --project <project-id> --function-id <function-id> --input-file input.json
Store the token in your CI secret store, never in the repository. See Authentication to create a service account and its token.
What's next
- AI agents and skills: let an agent drive the CLI for you.
- fun CLI reference: every command, flag and environment variable.
- Public API reference and Conventions.