Documentation

Kairon CLI

Search LinkedIn, build lists, run campaigns and answer replies from a terminal, a script or a cron job. It is an MCP client, not a second API, so a command and an assistant make the same call.

Installnpm i -g @kairon/cli

Getting started

  1. Step 1

    Install it

    Needs Node 22.23.1 or newer. You can also run it once with npx and install nothing.

    npm i -g @kairon/clinpx @kairon/cli whoami
  2. Step 2

    Sign in

    Opens your browser and signs you in with your Kairon account. There is no API key. Credentials are stored in ~/.kairon/config.json at mode 0600, keyed by server, so a local login never disturbs the production one.

    kairon loginkairon login --server http://localhost:3055
  3. Step 3

    Check who you are

    Reports the account and the LinkedIn seat every command will run as. If this works, the rest will.

    kairon whoami
  4. Step 4

    Run something

    Every command prints JSON, so it pipes straight into jq. Ask for help on any group or command at any time.

    kairon chat list --unreadkairon list --help

Commands

One command per tool, and there is no list of them in the CLI itself. A tool name splits on its first underscore and the rest is kebab-cased, so the surface here is exactly the surface the server exposes.

This page is generated from the tool catalogue by the same functions that build kairon --help, on every release. The page and your terminal cannot disagree, because they are the same code.

kairon campaign

kairon campaign activate

Activate a campaign — starts sending to real people

Full description

THIS STARTS SENDING MESSAGES TO REAL PEOPLE ON LINKEDIN, and a message already sent cannot be un-sent.

Flags: campaign activate
FlagTypeWhat it is for
--startNowboolean
--idrequiredstring

kairon campaign create

Create a draft campaign

Full description

Create a draft campaign: a name, the sending seat (channelAccountId — a connected LinkedIn account in this org), and optionally the ICP to gate enrollment on (icpId; when omitted, the org's most-used ICP is auto-selected as the default gat…

Flags: campaign create
FlagTypeWhat it is for
--namerequiredstring
--channelAccountIdrequiredstring
--icpIdstring

kairon campaign publish

Validate and publish the campaign's draft graph

Full description

Validate and publish the campaign's current draft graph — { id, migrateInFlight? }.

Flags: campaign publish
FlagTypeWhat it is for
--idrequiredstring
--migrateInFlightboolean

kairon campaign run-get

One sequence run, step by step

Full description

Read ONE sequence run in full — { runId } (an id from campaign_runs).

Flags: campaign run-get
FlagTypeWhat it is for
--runIdrequiredstring

kairon campaign runs

The campaign's sequence runs

Full description

Read the campaign's sequence runs — one per enrolled lead — keyset-paginated: { id, bucket?, cursor?, limit? }.

Flags: campaign runs
FlagTypeWhat it is for
--bucketwaiting|didnt_accept|didnt_answer|replied|skipped|error|interested
--cursorstring
--limitinteger
--idrequiredstring

kairon campaign set-graph

Replace the campaign's draft sequence graph

Full description

Replace the campaign's editable DRAFT sequence graph in full — { id, graph: { nodes, edges, startNodeKey } }.

Flags: campaign set-graph
FlagTypeWhat it is for
--idrequiredstring
--graph.nodesrequiredjson arrayjson
--graph.edgesrequiredjson arrayjson
--graph.startNodeKeyrequiredjsonjson

kairon campaign stats

How the campaign is doing

Full description

Everything about how a campaign is performing, in one read — { id, days? }.

Flags: campaign stats
FlagTypeWhat it is for
--idrequiredstring
--daysjsonjson

kairon campaign update

Edit the campaign's configuration and audience

Full description

Edit a campaign's configuration — any subset of { id, name, sendWindow, autonomy, dailyEnrollmentLimit, enrollmentFilter, icpId, stopOnReply, leadListIds }.

Flags: campaign update
FlagTypeWhat it is for
--namestring
--sendWindow.daysjson arrayjson
--sendWindow.startHourinteger
--sendWindow.endHourinteger
--sendWindow.timeZonestring
--autonomymanual|autopilot
--dailyEnrollmentLimitinteger
--enrollmentFilter.bucketsjson arrayjson
--enrollmentFilter.scopeseat|org
--icpIdjsonjson
--stopOnReplyboolean
--idrequiredstring
--leadListIdsjson arrayjson

kairon chat

kairon chat list

List LinkedIn conversations

Full description

List LinkedIn conversations, newest activity first.

Flags: chat list
FlagTypeWhat it is for
--seatIdstringA teammate's seat id (from a chat's `channelAccountId`). Defaults to your own.
--scopemine|org'mine' (default) is your own seat; 'org' is every seat in the organization.
--unreadboolean
--leadsOnlybooleanOnly chats already linked to a lead.
--qstringCase-insensitive match on the counterpart's NAME.
--cursorstring
--limitinteger

kairon chat messages

Read a conversation

Full description

Read one conversation's messages, newest first, by the chatId from chat_list.

Flags: chat messages
FlagTypeWhat it is for
--chatIdrequiredstring
--cursorstring
--limitinteger

kairon filter

kairon filter resolve

Resolve a Sales Navigator filter

Full description

Resolve a human-readable Sales Navigator filter value (location, industry, function) to a LinkedIn id, echoing the canonical label so a wrong match is visible.

Flags: filter resolve
FlagTypeWhat it is for
--typerequiredlocation|industry|function|current_company|past_company|company_location|school|past_role|groups|persona|technologies|account_lists|lead_lists|postal_code
--queryrequiredstring

kairon icp

kairon icp get

Get an ICP

Full description

Read one ICP and its latest (active) version by icpId.

Flags: icp get
FlagTypeWhat it is for
--icpIdrequiredstring

kairon impersonate

kairon impersonate list

List who you can act as

Full description

The users you may act as, each with their organization and whether they have a LinkedIn account connected — you can only act as someone who does.

Flags: impersonate list
FlagTypeWhat it is for
--searchstringFilter by name, email address or organization name.

kairon impersonate start

Act as another user

Full description

Act as another user from now on: every later call runs as them, on their LinkedIn seat and their organization.

Flags: impersonate start
FlagTypeWhat it is for
--userrequiredstringThe email address or user id to act as.

kairon inmail

kairon inmail send

Send an InMail

Full description

Send an InMail (optional subject).

Flags: inmail send
FlagTypeWhat it is for
--targetrequiredjsonjson
--subjectstring
--textrequiredstring
--attachmentsjson arrayjson

kairon invite

kairon invite send

Send a connection invitation

Full description

Send a LinkedIn connection invitation (optional note) through the caller's account.

Flags: invite send
FlagTypeWhat it is for
--targetrequiredjsonjson
--notestring

kairon linkedin

kairon linkedin fetch

Fetch a LinkedIn profile or company

Full description

Fetch a LinkedIn person OR company through the caller's connected account — whichever the target addresses.

Flags: linkedin fetch
FlagTypeWhat it is for
--targetrequiredjsonjson
--kindprofile|companyOverride auto-detection. Required for a company addressed by universal name or numeric id.
--refreshboolean

kairon list

kairon list add

Add members to a list

Full description

Add members to a list ({ asset, id, items }, ≤500 items).

Flags: list add
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring
--itemsrequiredjson arrayjson

kairon list create

Create a list

Full description

Create a named list — the campaign targeting unit.

Flags: list create
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--namerequiredstring

kairon list delete

Delete a list

Full description

Soft-delete a list by asset + id: it disappears from list_list with its memberships, the member leads/companies are untouched (they stay in the org pool, in their other lists, with their qualification state intact), and the name is immedia…

Flags: list delete
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring

kairon list get

Get one list

Full description

One list by asset + id: its name, live member count, and created date.

Flags: list get
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring

kairon list list

List lists

Full description

Read this org's lists of one asset, keyset-paginated, newest first, each with its live member count.

Flags: list list
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--qstring
--cursorstring
--limitinteger

kairon list members

Read a list's members

Full description

One keyset page of a list's members ({ asset, id, q?, cursor?, limit? }), newest-added first.

Flags: list members
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring
--qstring
--cursorstring
--limitinteger

kairon list remove

Remove members from a list

Full description

Remove members from a list ({ asset, id, memberIds }).

Flags: list remove
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring
--memberIdsrequiredjson arrayjson

kairon list update

Rename a list

Full description

Rename a list ({ asset, id, name }).

Flags: list update
FlagTypeWhat it is for
--assetrequiredleads|companiesWhich kind of list: 'leads' (people) or 'companies'.
--idrequiredstring
--namerequiredstring

kairon message

kairon message delete

Delete (retract) a sent message

Full description

Retract a message YOU sent, addressed by the chatId and message id that chat_messages returns.

Flags: message delete
FlagTypeWhat it is for
--chatIdrequiredstring
--messageIdrequiredstringThe message's `id` from chat_messages.

kairon message edit

Edit a sent message

Full description

Replace the body of a message YOU sent, addressed by the chatId and message id that chat_messages returns.

Flags: message edit
FlagTypeWhat it is for
--chatIdrequiredstring
--messageIdrequiredstringThe message's `id` from chat_messages.
--textrequiredstring

kairon message send

Send a direct message

Full description

Send a LinkedIn direct message.

Flags: message send
FlagTypeWhat it is for
--chatIdstringReply in this existing conversation (from chat_list). Use this, or `target`.
--targetjsonjsonOpen a NEW conversation with this person. Use this, or `chatId`.
--textrequiredstring
--attachmentsjson arrayjson
--clientTokenstring

kairon profile

kairon profile posts

A profile's recent posts

Full description

A page of a profile's recent posts (transient — not persisted).

Flags: profile posts
FlagTypeWhat it is for
--targetrequiredjsonjson
--cursorstring

kairon signal

Flags

Flags are derived from each tool input schema, not written by hand, which is why they match the tool exactly. Three shapes get three treatments.

Scalars are plain flags

A string, number or boolean becomes --flag and takes its value literally. An enum shows its choices in the type column.

Nested objects are dot paths

A tool input nests freely, so a nested field becomes --config.keyword rather than a flattened name that could collide with another tool field.

Arrays and unions take JSON

There is no honest flat spelling for "an array of either a member id or a URL", so those flags take JSON text. They are marked json in the table below.

Typos are caught before the network

Input is checked against the cached schema before any call, so a misspelled flag costs nothing and names itself: it tells you the option is unknown and suggests the one you meant.

Every command also accepts

--server <url>
Target a specific Kairon (default: KAIRON_API_URL, else production)
--json <json>
Pass the entire tool input as one JSON object
--refresh
Re-fetch the tool catalogue before running
-h, --help
Show help
-v, --version
Show the CLI version
And the escape hatch, when flags get in the way
kairon list create --json '{"asset":"leads","name":"Q3"}'

Output and exit codes

The result is JSON on stdout. Everything a human reads goes to stderr, so a pipe stays clean with no flags. A command that succeeds exits 0. A command that fails exits non-zero, writes nothing at all to stdout, and leads with a stable error code you can branch on rather than prose you would have to pattern-match.

Piping works with no flags
kairon campaign stats --id camp_… | jq '.funnel'
A failure names its code
$ kairon list get --asset leads --id list_01… ; echo "exit=$?"
kairon list get failed: COMMON_NOT_FOUND
{
  "code": "COMMON_NOT_FOUND",
  "params": { "resource": "lead_list" }
}
exit=1

Environment and headless use

For CI, a cron job or a container, there is no browser to open. Pass a token instead and the CLI needs no stored credentials at all.

KAIRON_TOKEN
Use this access token and ignore stored credentials entirely.
KAIRON_API_URL
Default server. The --server flag beats it, and production is the fallback.
KAIRON_CONFIG_DIR
Where credentials live. Defaults to ~/.kairon.
No ~/.kairon needed
KAIRON_TOKEN=<access token> kairon whoami

Acting as someone else

Kairon staff can act as any user; an owner or admin can act as a member of their own organization who does not outrank them. One command in, one command out, nothing to type in between.

kairon impersonate list --search acmekairon impersonate start --user [email protected]kairon chat listkairon impersonate stop

The mode belongs to this login, not to you

Signing in registers a fresh client each time, so your terminal, your assistant and your cron each have their own. Acting as someone here does not redirect the 3am job.

It ends 60 minutes after your last call

Not 60 minutes after it started. Working never interrupts you; leaving for lunch ends it.

Every command under it says so on stderr

One line naming who you are acting as. stdout is untouched, so a pipe keeps working.

Only someone with a LinkedIn seat

Acting as a seatless user would reach nothing, so impersonate list tags each candidate with whether they have one.

Troubleshooting

Every command says there is no seat

The account has no LinkedIn account connected, or the plan is not active. Connect one in Kairon and run kairon whoami again. Commands act as that seat, so nothing works without it.

A command does not exist

Commands come from the server, cached per server URL under ~/.kairon/tools/, and the cache has no expiry because a tool set changes on deploy and not on a schedule. Run the command again with --refresh to re-fetch it.

It asks you to sign in again

Access tokens last 30 days and refresh silently. When the refresh token finally expires after 90 days you get one sentence and the command to run.

Signing out does not revoke anything

kairon logout deletes the local credentials. The server issues opaque tokens with no revocation endpoint, so the access token stays valid there until it expires. The command says so rather than implying a revocation that did not happen.