Getting Started
Install the CLI, log in once, and the first command works. There is no client to write: the CLI is a single binary for macOS, Linux, and Windows, on amd64 and arm64, and it needs no runtime.
Install
brew install intuizi/intuizi-cli/intuizimacOS and Linux. Shell completion for bash, zsh, and fish comes with it.
The CLI’s source code and releases are on GitHub. Report a bug or ask for a feature in its issues, and for anything about your account, contact Intuizi support.
Confirm it worked:
intuizi versionIt prints the version, such as v0.1.6.
The examples in this section use bash or zsh syntax, and some pipe --json
output through jq, which is installed separately. On Windows, run them in
Git Bash, or in WSL with the Linux build installed inside WSL (Homebrew, npm,
or the linux archive).
Log in
intuizi auth loginPrompts for the email and password of your Intuizi Console account, exchanges them for an API token, and keeps it for subsequent commands. Confirm it worked:
intuizi auth statusBase URL: https://console.intuizi.com
Token: present (in the OS credential store)
Account: you@example.com
Expires: 2027-09-26 (in 364 days)The token goes to the OS credential store when there is one: the macOS
Keychain, Windows Credential Manager, or the Linux secret service. Containers,
CI runners, and SSH sessions usually have none, so there it goes to the config
file, written with owner-only permissions: ~/.config/intuizi/config.json
($XDG_CONFIG_HOME/intuizi/config.json when that is set, and
%AppData%\intuizi\config.json on Windows). INTUIZI_NO_KEYRING=1, set before
logging in, keeps it in the file. The file also records the console URL, the
account, and the expiry,
and auth status says where the token is held.
auth login mints the same kind of API token as the My Account > API Tokens
page: it is listed there, expires after one year by default, and counts toward
the 10 active API tokens an account can hold. The contract is on
Create API Token. Logging in
again reuses a working token already stored for the same console and account
rather than minting another. Pass --email to log in as another account,
which mints a token for it and replaces the stored one.
A token is bound to the console it was minted for. To use a console other than
https://console.intuizi.com, pass --base-url to auth login. Later
commands use the stored URL.
intuizi auth logout forgets the local copy and does not revoke the token. It
stays valid until it expires, until it is revoked on the My Account > API
Tokens page, or until the account password changes, which revokes every API
token on the account.
In CI
Where nobody is there to type a password, mint an API token on the My Account >
API Tokens page and pass it in the INTUIZI_API_TOKEN environment variable
instead of running auth login. It wins over any stored token. A password
change revokes it, so CI needs a new one after that.
INTUIZI_API_TOKEN=<token> intuizi audiences listRunning auth login on a runner that starts with no stored token mints
another year-long token on every run, and those fill the cap of 10. See
Scripts and CI.
First commands
Reference reads are the safest place to start: they are plain GETs with no side effects.
intuizi reference common dataset-types
intuizi reference poi brands --search coffeeEvery catalog except reference profile-attributes recency-limits takes
--search, a case-insensitive contains match.
Catalogs says which field each catalog matches.
Then look at what already exists in your account:
intuizi audiences list
intuizi projects listOutput
| Flag | Prints |
|---|---|
| none | a table |
--json | the raw response envelope |
--quiet | ids alone, one per line |
Commentary always goes to stderr: status changes while a command waits, the pagination footer, “no results”. Only data reaches stdout, so a pipe never has to filter noise out.
intuizi reference poi brands --search coffee --quiet
intuizi audiences show <id> --json | jq '.data[0].status'--json and --quiet contradict each other and are rejected together.
Commands that return no ids, such as usage, reject --quiet, so use
--json there. auth, version, and completion print plain text and
ignore either flag given alone.
--debug prints every HTTP request and response on stderr, with credentials
redacted, and leaves stdout alone. --json, --quiet, and --debug are three
of the five global flags every command takes.
The other two are --base-url (above) and --idempotency-key (below).
Waiting
audiences create and activations create return as soon as the build is
queued, so a new audience comes back with a results count of zero. That is
expected, not a failure. Add --wait to block until it reaches Completed
(104) or fails:
intuizi audiences create --file audience.json --wait --timeout 30mStatus changes print to stderr as they happen. The last record read prints
to stdout whether the build completed or failed, or the wait timed out or gave
up, so branch on the exit code rather than the output: 0 is Completed, and 1
is a failed build, a failed delivery, or a wait that timed out or gave up.
With --json stdout is always the server’s envelope, so read
.data[0].status.id: a failed build still prints a "status": "success"
envelope, because reading the record succeeded, and a wait that timed out or
gave up prints the envelope it last polled. See
Conventions. --quiet prints the id whatever
the outcome.
The wait times out after 60 minutes unless --timeout sets another bound, and
--timeout without --wait is rejected. It also gives up after three failed
reads in a row, for example during a short API outage. Neither stops the build
on the server, so pick it up again with intuizi audiences show <id> --wait
(or activations show) rather than creating it again. Both a timeout and a
give-up name that command on stderr.
The wait keeps going while the build is still moving, including while an
audience draws the data stream visualizations it opted into, which it reports
as 109 Visualizing data streams before 105 and 104. A failed build is
final and is not worth resuming. That includes 107 Additional Info, which
means Intuizi stopped the build because it cannot be built as defined. The API
reports only Additional Info. The Audience Manager shows the reason, most
often a date range outside the data available for the dataset, so fix what it
names and create the audience again. An activation that stops on 107 is
final in the same way.
audiences show <id> --wait also follows a Lookalike Model while it trains.
audiences estimate create and audiences estimate show wait on a size
estimate the same way, and it ends at completed, blocked, or failed (see
Estimate show). No other command
waits. See The Async Model.
Shell completion
A Homebrew install includes the completion scripts for bash, zsh, and fish. After a binary or npm install, load the script the CLI generates for your shell:
# zsh: add to ~/.zshrc
autoload -U compinit && compinit
source <(intuizi completion zsh)
# bash, with the bash-completion package: add to ~/.bashrc
source <(intuizi completion bash)
# fish: run once
mkdir -p ~/.config/fish/completions
intuizi completion fish > ~/.config/fish/completions/intuizi.fishZsh loads no completion, the Homebrew one included, until its completion
system is switched on, which is what the compinit line does. For PowerShell,
and for installing a script file instead, see
intuizi completion <shell> --help.
Completion covers commands, flag names, and the values of --type,
--signal, --file-format, --identifier-type, schedules create --frequency, and --purpose.
Limits
Rate limits are the API’s: 120 reads and 30 writes per minute per token. Some
commands make more than one call, and each counts: a brand or category name is
looked up in its catalog, audiences create and audiences estimate create
read the signal-provider catalog for their default, --wait reads the record
until the work finishes, and uploads put also sends the file to storage.
Audience, estimate, Lookalike Model, cohort, and activation creates also count
against a per-organization build budget, by default 60 an hour and 300 a day,
counted across the console, the API, and MCP. See Limits & Quotas.
On a 429 the CLI waits the interval the response asks for and retries at
most twice, saying so on stderr each time
(rate limited (429): retrying in 3s (retry 1 of 2)). That rides out the
per-minute limits. A 429 that asks for more than 60 seconds, as a
build-budget 429 usually does, is not retried: the command exits 1 at
once, and the error ends with the wait the server asked for, such as
(429, Retry-After: 1800s). Nothing was created, so run the command again
after that. A create that claims an upload reference is retried only after the
per-minute limiter’s 429. A build-budget refusal of
cohorts create --upload-reference has already used the reference, so it is
returned as it came, and the error says to upload the file again for a new
reference. Do that once the budget has room. See
Uploads.
audiences create, audiences estimate create,
audiences lookalike create, activations create, cohorts create,
projects create, schedules create, and
poi submissions create --upload-reference send an Idempotency-Key, and a
retry after a 429 reuses it. Each run sends a fresh key, so running a create
again can make a second resource. When a create gets no response at all, the
CLI prints the key it used on stderr: run the same command with
--idempotency-key <key> to retry it without risking a duplicate. Other
writes send no key. See Idempotency.
Exit codes: 0 success. 1 a failure once the command line parsed: an API
error, a --wait that failed, timed out, or gave up, or a local failure such
as an unreadable --file, a missing token, or a declined confirmation. 2 a
usage error: an unknown command or flag, a bad value or id, missing or
conflicting flags, a delete without --yes where stdin is not a terminal, or a
name that matches no catalog entry or several. Nothing is created on a 2,
though a name lookup or the --provider check may already have read a catalog.
130 on Ctrl-C and 143 on SIGTERM. With the npm package, intuizi is a Node
launcher. A SIGTERM or SIGHUP sent to the launcher alone, as Docker, systemd,
or a CI runner sends one, is passed on to the binary, so the command stops and
exits 143 for a SIGTERM, as it would without the launcher.