Elizon Docs
Elizon CLICommand reference

install

Verify a signed .pkg and install it into an Organization from the terminal.

npx @elizon/cli install <artifact.pkg> --yes [--target=<name>] [--project=<project-id>]
                       [--slot.<id>=<value> …] [--approver.<node>=<emails>] [--form-user.<node>=<username>]
                       [--rename.<node>=<name>] [--trust=<public-key.json>] [--non-interactive] [--json]
                       [--activate [--acknowledge-evaluation] [--schedule.<trigger>.cron=… --schedule.<trigger>.timezone=…]]

npx @elizon/cli install <artifact.pkg> --resume=<installation-id> --yes [--target=<name>]
npx @elizon/cli install --rollback=<installation-id> --yes [--target=<name>]
npx @elizon/cli install <artifact.pkg> --activate=<installation-id> --yes [--target=<name>] [the same --slot flags]

Installs a signed Package into an Organization. It does the same thing as the install wizard in Studio and runs on the same engine, but from a terminal or a CI job. That makes it the practical way to install one Package into many Organizations.

Needs a connected device and the package.install permission (Owner, Admin, Editor).

What happens

Verify, offline

The signature is checked on your machine before anything is uploaded, against your Organization's own signing keys (current and past) plus any key you pass with --trust.

✓ signature verified — ed25519:4f2c9a…
  Self-signed by "Acme Ltd" (key ed25519:4f2c9a…). The name is the signer's own claim; no registry has counter-signed this Package.

Work out what's missing, up front

The CLI reads the Package's Slots and Workflows and lists everything you still need to supply. In a terminal it asks for each item. With --non-interactive, --json or no terminal, it fails with every missing item in one message, so a CI job never fixes one item per run.

Install

The Organization creates every object in dependency order, binds each Slot to what you chose, and records the install in the audit log. Without --activate it stops here, installed but not yet live; the output says how to activate it.

✓ acme.triage-intake installed into acme (https://acme.internal:8443)
  installation:  0f0b1c2d-…
  status:        installed
  objects:       11

Activating

Installing creates everything, inert. Activating makes the Package live: it runs the evaluation suite, records the activation in the audit log, publishes the entry point Workflow when a trigger needs it, and arms the triggers: schedule timers, webhook addresses, api access, inbound-call phone routing, email and app polling, and knowledge-document triggers. A manual trigger needs no arming. See Triggers only fire when the Package is live. Add --activate to install and activate in one run:

npx @elizon/cli install acme-triage-1.0.0.pkg --yes --activate \
  --project=<project-id> --slot.reasoning=<llm-configuration-id> --slot.phone-line=<trunk-id>
Evaluation: PASSED — 4/4 passed (gate: must-pass, recorded, not enforced)
  ✓ active-failure-escalates  passed 5120 ms
  …
✓ activated — status installed
  ✓ after-hours-call (inbound-call): Answering on +359…
  ✓ run-manually (manual): Runs from Studio.

To activate a Package installed earlier without --activate, pass its installation id. Nothing is created again:

npx @elizon/cli install acme-triage-1.0.0.pkg --yes --activate=<installation-id> \
  --slot.reasoning=<llm-configuration-id> --slot.phone-line=<trunk-id>
  • The same .pkg, and the same bindings. The organization never keeps the artifact or your answers, so activation needs them again. A different Package or version is refused.
  • Evaluation results are acknowledged by a person. If the Package has a suite, its results are printed first. In a terminal you're asked to type yes; otherwise pass --acknowledge-evaluation, which states that you have read what this run prints. Without either, activation stops with EVALUATION_NOT_ACKNOWLEDGED. The Package stays installed and inactive, and the error gives the command to finish.
  • Schedules run as the Package declares them unless you override them, both halves together: --schedule.<trigger-id>.cron="30 7 * * 1-5" --schedule.<trigger-id>.timezone=Europe/Sofia.
  • Webhook addresses are generated at activation and printed with the trigger outcomes.
  • A Package is activated once. Activating it again (from the CLI or Studio) is refused with INSTALL_STATE_INVALID. An update arms the new version itself.

You can also activate from Studio: a Package installed but not activated shows Activate on its page in Studio → Packages. See Installed Packages.

Binding Slots: --slot.<id>=<value>

A Package never carries models, credentials, documents or phone lines. It declares Slots, and you fill each one. The Slot's declared type decides what the value means:

Slot typeValueExample
llmThe id of one of your LLM Configurations--slot.reasoning=4b1e…
credentialA whole {{secret.KEY}} reference to your Secrets vault--slot.calendar-access='{{secret.CALENDAR_TOKEN}}'
knowledge-sourceThe id of a Knowledge Base holding the documents--slot.policy-documents=9c07…
stt, tts<provider>:{{secret.KEY}}--slot.speech-in='soniox:{{secret.SONIOX_API_KEY}}'
sip-trunkThe id of one of your inbound SIP trunks--slot.phone-line=77aa…

A sip-trunk binding from the CLI carries no inbound number, so the Package's inbound-call triggers stay unwired until the line is bound with its number in Studio. See Voice and SIP → From the CLI.

Any Slot except llm accepts defer, which leaves it for later. The Package then installs as installed-incomplete and lists the Slot as outstanding. Finish it later with packages bind or Bind in Studio, which take the same values as this table; a knowledge-source Slot is finished by adding documents to its Knowledge Base. An LLM Slot can't be deferred, because nothing in a Package runs without a model.

Credentials: references only, never values

The CLI never accepts a secret value, whether as a flag, from a file or on stdin. A credential Slot takes only a whole {{secret.KEY}} reference to a Secret that already exists in the target Organization. Anything else (a bare key name, a raw token) is refused before it leaves your machine. Create the Secret first in Studio → Settings → Secrets. If one is missing, the error includes a link to that page. --values and similar credential-file flags are refused by name.

OAuth credentials can't be completed in a terminal. A Slot with scheme: oauth2 fails with SLOT_OAUTH_REQUIRES_BROWSER. Retrying won't help: install through the Studio wizard, or defer the Slot and connect it in Studio afterwards.

Other options

OptionEffect
--yesRequired. Installing creates real resources.
--target=<name>Which connected Organization. Default: your default target.
--project=<project-id>Install into a project instead of the Organization level. The project must belong to the target's Organization. Required for Packages with a Knowledge Base. Without it, the Package's Agents, Teams, Workflows and voice configurations go into your Organization's default project.
--approver.<node>=<emails>Who approves a Workflow's human-review step (comma-separated emails). Keyed by the Workflow node id.
--form-user.<node>=<username>The username for a Workflow's password-protected form trigger. Never a password.
--rename.<node>=<name>Install an object under a different name, e.g. when the Organization already has one by that name.
--trust=<file>Also trust this signer's public-key document (elizon.signing-public-key.v1). See Sharing across Organizations.
--non-interactiveNever prompt; fail listing everything missing.
--activateActivate after installing. See Activating.
--activate=<installation-id>Activate an existing, never-activated installation instead of installing.
--acknowledge-evaluationAcknowledge the evaluation results this run prints (for runs that can't prompt).
--schedule.<trigger>.cron=, .timezone=Override a schedule trigger at activation; pass both.

When an install fails partway

The Organization records each object as it's created. If an install stops partway, it stays failed with a record of what exists, and nothing is left half-configured without a record. You choose what happens next, from the CLI or from Studio → Packages, whichever is handier:

# carry on from the object that failed (takes the artifact again)
npx @elizon/cli install acme-triage-1.0.0.pkg --resume=0f0b1c2d-… --yes

# remove everything this install created (takes no artifact)
npx @elizon/cli install --rollback=0f0b1c2d-… --yes

--resume and --rollback can't be combined. A rollback won't delete an object that something outside the Package now uses (INSTALL_ROLLBACK_BLOCKED). It's reported, and you decide.

Common errors

CodeMeaning and fix
PKG_UNSIGNEDThe artifact isn't signed. Ask the author to run sign.
PKG_SIGNATURE_INVALIDContents don't match the signature. Don't install; get a fresh copy.
PKG_UNKNOWN_SIGNER_KEYSigned by an Organization whose key you haven't trusted. Pass its key with --trust.
PKG_INCOMPATIBLE_PLATFORM_VERSIONThe Organization's platform is older than the Package's minPlatformVersion.
SLOT_CREDENTIAL_UNRESOLVEDThe referenced Secret doesn't exist in the target Organization. Create it (link in the hint).
SLOT_LLM_UNRESOLVEDThat LLM Configuration doesn't exist, or none of its models meets the Slot's constraints.
SLOT_LLM_NOT_DEFERRABLEAn llm Slot was given defer.
SLOT_UNDECLARED--slot.<id> names a Slot the Package doesn't declare (check the spelling).
EVALUATION_NOT_ACKNOWLEDGEDThe Package has an evaluation suite and this run couldn't acknowledge it. Read the results, then re-run with --acknowledge-evaluation.
CLI_PROJECT_NOT_FOUNDThe --project id isn't a project of the target's Organization. Check the id; if the project is in another Organization, connect a target for it (target add <host> --org=<organization-id>) and pass --target. Archived and deleted projects are refused the same way.
INSTALL_STATE_INVALIDActivation refused: already active, not finished, or a different .pkg than was installed. The message says which.

All codes: Error codes.

Example: one Package, three client Organizations

for client in client-a client-b client-c; do
  npx @elizon/cli install triage-1.2.0.pkg --target="$client" --yes --non-interactive \
    --activate --acknowledge-evaluation \
    --trust=./acme-signing-key.json \
    --project="$(cat "projects/$client")" \
    --slot.reasoning="$(cat "llm/$client")" \
    --slot.calendar-access='{{secret.CALENDAR}}' \
    --slot.phone-line=defer \
    --json > "install-$client.json"
done