Skip to content
Getting Started
.md

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/intuizi

macOS 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 version

It 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 login

Prompts 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 status
Base 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 list

Running 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 coffee

Every 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 list

Output

FlagPrints
nonea table
--jsonthe raw response envelope
--quietids 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 30m

Status 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.fish

Zsh 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.