A fast Go CLI for the ITONICS Innovation OData v2 API. Manage elements, element types, files, attachments, watches and likes from your terminal or from AI agents (Claude Code, Codex CLI, Cursor, …).
The companion itonics-skills repo provides the agent skill that documents this CLI for LLM-based assistants.
brew tap itonics/itonics https://github.com/itonics/itonics-cli
brew install itonicsUntil the first v* tag is released, the tap installs the --HEAD formula and builds from main.
scoop bucket add itonics https://github.com/itonics/itonics-cli
scoop install itonicsscoop update itonics pulls the next release.
Grab a release archive for your OS/arch from the latest release:
- macOS / Linux —
itonics_X.Y.Z_<Os>_<arch>.tar.gz, extractitonicsinto~/.local/bin - Windows —
itonics_X.Y.Z_Windows_x86_64.zip, extractitonics.exeinto a directory onPATH
go install github.com/itonics/itonics-cli@latestOr, working in a clone:
git clone https://github.com/itonics/itonics-cli.git
cd itonics-cli
go build -o itonics .itonics loginInteractively prompts for the tenant domain, space URI, and API key (hidden input), validates them against the API, and writes them to ~/.config/itonics/config.toml with chmod 0600. Re-running login rotates the key — existing values are shown as defaults.
Non-interactive forms:
itonics login --domain https://acme.itonics.io --space SPACE_URI --api-key SECRET
echo "$KEY" | itonics login --domain ... --space ... --api-key - # read key from stdin
itonics login ... --skip-check # skip the validation round-tripOther commands:
itonics whoami # show which creds would be used, and from where
itonics logout # delete ~/.config/itonics/config.tomlCredentials are resolved in this order (highest first):
ITONICS_DOMAIN/ITONICS_API_KEY/ITONICS_SPACEenv vars — set by your shell, by--env-file, or by a.envin the current directory.- The persisted profile at
~/.config/itonics/config.toml.
See .env.example if you prefer the env-var path.
| Task | Command |
|---|---|
| Log in / rotate API key | itonics login |
| Show effective credentials | itonics whoami |
| Log out | itonics logout |
| List elements | itonics elements list -n 20 --format table |
| Filter by type | itonics elements list -f "elementTypeUri eq 'XXX'" |
| Filter by text | itonics elements list -f "contains(label,'budget')" (no full-text $search) |
| Get one element | itonics elements get URI --raw |
| Create | itonics elements create --type URI --label LBL --created-by EMAIL |
| Update | itonics elements update URI --updated-by EMAIL --label "New" |
| Delete | itonics elements delete URI [URI…] --yes |
| Upload file | itonics files upload ./logo.png --created-by EMAIL |
| Upload + attach | itonics files upload ./logo.png --created-by EMAIL --attach-to ELEMENT_URI |
| File details | itonics files get FILE_URI |
| List attachments | itonics attachments list ELEMENT_URI |
| Attach by URI | itonics attachments attach ELEMENT_URI FILE_URI --attached-by EMAIL |
| Detach | itonics attachments detach ELEMENT_URI FILE_URI --detached-by EMAIL |
| List watches | itonics watches list ELEMENT_URI |
| Add watch | itonics watches add ELEMENT_URI USER_URI |
| List likes | itonics likes list ELEMENT_URI --orderby "likedOn desc" |
| List comments | itonics comments list ELEMENT_URI |
| Add comment | itonics comments create ELEMENT_URI --commented-by EMAIL --text "Hi @bob@acme.com, see #{Idea X}" |
| Edit comment | itonics comments update ELEMENT_URI COMMENT_URI --updated-by EMAIL --text "…" |
| Delete comment | itonics comments delete ELEMENT_URI COMMENT_URI --yes |
| List views | itonics views list --format table |
| Create page view | itonics views create --label "Dashboard" --created-by EMAIL --html "<div class='p-4'>…</div>" |
| List element types | itonics types list --format table |
Run itonics --help or itonics <group> --help for the full surface.
import "github.com/itonics/itonics-cli/internal/api"
c := api.New("https://your-tenant.itonics.io", "your-api-key", "your-space-uri")
elements, err := c.ListElements(ctx, api.ListElementsParams{Filter: "elementTypeUri eq 'XXX'", RawFieldValues: true})
fileURI, err := c.UploadFile(ctx, "/path/to/logo.png", "user@example.com", "")
_, err = c.AttachFiles(ctx, "ELEMENT_URI", []string{fileURI}, "user@example.com")Note: the API client lives under
internal/today — if you have a need for it as a public package, open an issue.
- The OpenAPI spec lives at apidocs.itonics-innovation.com (
bundled-openapi.yaml). rawFieldValues=1returns each property as{uri, type, label, rawValue}.rawValueis always an array.- For
rich_textproperties, send plain HTML orbase64:<base64-of-HTML>. Thetiptap:storage encoding is read-only and rejected on writes. - The pre-signed upload response advertises
x-amz-acl: private, but the backing bucket has ACLs disabled. The CLI strips that header before PUTting the binary — replicate this when calling the API directly. - Not every element type exposes a default Attachments field. When it doesn't,
POST /elements/{uri}/attachmentsreturns400 BadRequestException: Element type 'X' does not expose the default Attachments field. Use afile/headerImage-typed element property instead.
Tagging vX.Y.Z triggers a GoReleaser workflow that builds binaries for macOS / Linux / Windows (amd64 + arm64), creates a GitHub release, publishes checksums, and updates Formula/itonics.rb so the tap installs the new version.
MIT — see LICENSE.