Menu

CLI

Use the preview Kirora CLI to manage API resources from your terminal, with saved logins, pagination and safe retries.

Preview

Use the kirora CLI to manage contacts, events, campaigns and other API resources from your terminal. Commands use the Node.js library for authentication, retries and error handling. The CLI is in preview and not yet published to npm.

kirora login                      # paste an API key; it is checked, then saved
kirora groups create --name VIPs
kirora contacts list --limit 100 --paginate | jq -r .email
kirora contacts identify --external-id cust_1042 --email ada@example.com --email-consent

Install

The package is @kirora/cli, for Node.js 22.13 or later. It is not on npm yet.

Sign in

kirora login asks for an API key (kirora_…) at a masked prompt. It checks the key against GET /v1/me before saving it, so a mistyped key fails straight away. In a script, pipe the key in instead:

kirora login --profile staging    # a second login, used with --profile staging
kirora login < key.txt            # the key from stdin
kirora me get                     # check which key and workspace you are using

The key is never taken as a flag, where it would land in your shell history. Logins are saved in $XDG_CONFIG_HOME/kirora/config.json (by default ~/.config/kirora/config.json), readable only by you. At login, --base-url saves another API host with the profile (without it, KIRORA_API_URL is used when set), and --workspace saves a partner key’s tenant.

kirora logout removes the default login; kirora logout --profile staging removes a named one.

The key’s scopes decide what the CLI may do. See Authentication.

Where the key comes from

Each call takes the first of these that is set:

  1. The profile named by --profile, or by the KIRORA_PROFILE environment variable.
  2. The KIRORA_API_KEY environment variable, for CI and scripts, which need no login. KIRORA_API_URL sets another host (the default is https://api.kirora.io) and KIRORA_WORKSPACE a partner key’s tenant.
  3. The default profile saved by kirora login.

Commands

Every command is kirora <resource> <action>, and there is one for each operation in the API reference: CLI commands lists them all. The resource is the first part of the path (/v1/sending-domains/… is sending-domains), and the action is what the operation does:

kirora groups list
kirora groups get 3f1c2a9e-0000-4000-8000-000000000000
kirora sending-domains check 3f1c2a9e-0000-4000-8000-000000000000
kirora campaigns send 01a1c7e2-0000-4000-8000-000000000000

The help goes three levels deep. kirora --help lists the resources, kirora groups --help a resource’s actions, and kirora groups create --help an action’s flags and the scope its key needs. A mistyped command gets a suggestion.

Arguments and flags

  • Ids in the path are arguments, in order: kirora templates get-version <id> <version>.
  • Query parameters and simple body fields are flags, named as in the API reference in kebab case: externalId is --external-id. A flag with a fixed set of values lists them in its help, and a number flag refuses anything else.
  • True or false fields are a pair: --email-consent and --no-email-consent. Leave both out and the field isn’t sent.
  • Lists of text take several values: --allowed-origins https://example.com https://www.example.com.
  • Anything nested goes in -d (--data) as the whole body: inline JSON, a file (@file) or stdin (-). Flags set fields on top of it.
  • A file upload takes the file’s path: kirora assets upload --file logo.png.
kirora transactional send -d @message.json --idempotency-key order-1001 --send-at 2026-11-02T09:00:00Z

Sends and events

events track, transactional send, campaigns trigger and push send require --idempotency-key. Tie the key to what you are sending, such as an order number, and reuse it if you run the command again. See Idempotency.

Lists

A list returns one page. On a list action, --paginate follows the cursors for you and prints each item as one line of JSON (JSON Lines), ready for jq. A larger --limit means fewer requests. See Pagination.

Flags on every command

Flag
--profile <name> Use a saved login other than the default.
--workspace <externalId> A partner key’s tenant, sent as Kirora-Workspace: --workspace tenant-42.
-i, --include Print the HTTP status and headers before the body.

Output and exit codes

A success prints the response body on stdout as the API sent it: pretty-printed, or one line per item with --paginate. -i prints the status and headers on a failure too.

An API error goes to stderr as { "error": { code, message, details, requestId } }, so a pipeline only sees the body of a success. See Errors for the codes.

Exit code Meaning
0 The call succeeded.
1 The call failed: an API error, a network failure, or no key to use.
2 The CLI could not read the command, and nothing was sent: an unknown command or flag, a missing id or idempotency key, a value that is not a number, or a body that is not valid JSON.

Retries

Retries follow the Node.js library: a 429 is always retried, and other failures only when the call is safe to repeat. A create without an idempotency key is never retried, so it can’t run twice.

Agent keys

The CLI works with any API key, including an agent key, which drafts but never sends: see Agents for what it may do. For AI assistants, prefer the hosted MCP server over shelling out to the CLI; it takes the same key.