All pages

Agents & API

The CLI

Install krinoa, sign in with a device grant or an API key, and use the JSON-first output contract — --fields, --all, --yes and honest exit codes.

krinoa gives you the same jobs, applications, reads, threads and ledger the web app shows, driven from a terminal, a script or an agent. This page is enough to be productive with it. The CLI reference lists every command, and each command's --help names its flags and the exact fields it answers with, without leaving the shell.

Install#

krinoa is a single ESM file. It needs Node 22 or newer and nothing else at runtime.

bash
npx krinoa --help    # no install, always the latestnpm i -g krinoa      # or install it once

The package is not published to npm yet; it goes up with the first tagged release. krinoa completion <shell> prints a completion script for bash, zsh or fish to source from your shell's startup file.

Sign in as yourself#

krinoa login with no flags runs the device-authorization grant: it prints a short code, tries to open /device in your browser — printing the URL if it cannot — and waits while you approve it. What it stores is a session token, so the CLI acts as you, with your role: an interviewer's scoping applies, and the activity ledger names the human. krinoa logout ends the session on the server and forgets the credential.

bash
krinoa loginkrinoa whoami

Sign in with an API key#

An API key is the other way in: a workspace credential rather than a person, acting at admin level, with no browser, and the path for agents, cron jobs and CI. Create one in Settings › CLI access, or with krinoa keys create <name> from a signed-in session; a key cannot create another key, and it lives until it is revoked unless --expires 90 gives it a horizon, up to a year, after which it stops verifying on its own. Exporting it stores nothing on disk:

bash
export KRINOA_API_KEY=krinoa_…krinoa whoami

To persist it in a named profile instead, read it from stdin so it never enters argv, your shell history or ps:

bash
krinoa login --api-key - --profile ci < key.txt

Profiles and environment variables#

Credentials live in one file — $XDG_CONFIG_HOME/krinoa/config.json, falling back to ~/.config/krinoa/config.json — with the directory 0700 and the file 0600, re-applied on every write, and written only by krinoa login and krinoa logout. --profile ci picks a profile per command, at any depth: krinoa --profile ci jobs list and krinoa jobs list --profile ci are the same call. Three variables let an agent or a CI job run with no config file at all.

VariableWhat it does
KRINOA_SERVERThe server for this call, overriding the profile
KRINOA_API_KEYAuthenticate with this key, overriding any stored credential
KRINOA_PROFILEWhich stored profile to start from

Precedence, highest first: flags, then environment, then the profile in the config file, then the built-in default of https://app.krinoa.com. KRINOA_API_KEY beats a stored session, so exporting a key is how you hand your terminal to an agent for one command.

The output contract#

Output mode follows stdout: a terminal gets a table, anything else gets JSON. --json forces JSON on a terminal. The JSON is the API's response, unchanged — nothing renamed, reordered or summarised — and a list prints a page object, { items, nextCursor }.

  • --fields publicId,candidate.name projects the JSON client-side, keeping the model's own nesting rather than flattening it. A path whose first segment is not a field of that command's output is refused before the request goes out, and the error names the valid ones. On a table it is a note on stderr and nothing else.
  • --all follows the cursors for you and prints one complete object with no nextCursor key at all. Lists return 50 items by default and 200 at most with --limit.
  • --yes confirms. The CLI has no interactive prompts: a command that would delete data or send mail to a candidate refuses without --yes, exits 2, and hands back both the consequences and the exact line that would go through. See Agents.

Exit codes#

Exit codes are the branch an agent should take: a failure does not exit 0, and a code always means the same thing. Every failure prints one line on stderr in the shape error: CODE: message, and under --json the API's own error body goes to stdout as well.

CodeMeaning
0Success
1Unexpected error, including a network failure
2Usage error, or a destructive command refusing without --yes
3Not authenticated — run krinoa login, or set KRINOA_API_KEY
4Not found
5Permission denied
6Validation failed
7Conflict with the current state
8Rate limited
9The CLI and the server disagree about the contract version

A session, end to end#

Every command below is read-only or refuses before it writes, so you can run the whole thing against your own workspace and change nothing. Substitute your own job and application ids.

bash
krinoa whoami --fields user.name,org.name,role,viakrinoa jobs list --fields publicId,title,statuskrinoa apps list --job RES4A7 --fields publicId,stage,screening.score,candidate.namekrinoa apps show A-21 --fields publicId,candidate.name,screeningDetail.score,screeningDetail.summarykrinoa apps reject A-13 --reason "no systems experience"

The first four answer. The fifth refuses, and nothing is written:

text
error: CONFIRMATION_REQUIRED: Rejecting A-13 (Daniel Okafor) is final. The stage moves to rejected and the candidate is told.Re-run: krinoa apps reject A-13 --reason 'no systems experience' --yes

Updated 2026-09-10