Skip to main content

Environment Variables

VariableDescriptionDefault
OUTLIT_API_KEYAPI key for authentication (overridden by --api-key flag)
OUTLIT_API_URLOverride the API base URLhttps://app.outlit.ai
XDG_CONFIG_HOMEOverride the config directory (Unix)~/.config
CITriggers JSON output mode when equal to exactly "true" or "1"
GITHUB_ACTIONSTriggers JSON output mode when set
TERMWhen set to dumb, disables ANSI colors

Config Directory

The CLI stores configuration in a platform-specific directory:
PlatformPath
macOS / Linux~/.config/outlit/ (or $XDG_CONFIG_HOME/outlit/)
Windows%APPDATA%\outlit\

Files

FilePurposeCreated by
credentials.jsonStored API keyoutlit auth login
The credentials file has 0600 permissions (readable by owner only) and contains:
{
  "apiKey": "ok_your_api_key_here"
}

Output Behavior

TTY Mode (Interactive)

When running in an interactive terminal, the CLI outputs:
  • Tables with Unicode box-drawing characters for list commands
  • Spinners on stderr during API calls
  • Colored output with green checkmarks for success
  • Pagination hints showing total count and next cursor
Example:
┌──────────────────────────┬────────────┬─────────┬──────────┬────────────┐
│ Name                     │ Domain     │ Billing │ MRR      │ Last Active│
├──────────────────────────┼────────────┼─────────┼──────────┼────────────┤
│ Acme Corp                │ acme.com   │ PAYING  │ $5000.00 │ 2d ago     │
│ Globex Inc               │ globex.com │ TRIALING│ $0.00    │ 5h ago     │
└──────────────────────────┴────────────┴─────────┴──────────┴────────────┘
Showing 20 of 150 total. Next page: --cursor cursor_abc123

JSON Mode

When JSON mode is active, all output is pretty-printed JSON on stdout:
{
  "items": [...],
  "pagination": {
    "hasMore": true,
    "nextCursor": "cursor_abc123",
    "total": 150
  }
}
Errors are also JSON, written to stderr:
{
  "error": "Not authenticated. Run `outlit auth login` or pass --api-key.",
  "code": "not_authenticated"
}

When JSON Mode Activates

JSON mode activates automatically in any of these conditions:
ConditionExample
--json flagoutlit customers list --json
stdout is pipedoutlit customers list | jq
CI=true or CI=1GitHub Actions, CircleCI, etc.
GITHUB_ACTIONS is setGitHub Actions
TERM=dumbTerminals without ANSI support
This means AI agents (Claude Code, Cursor, etc.) automatically get JSON output when they run CLI commands as subprocesses — no extra configuration needed.

Error Handling

All errors exit with code 1. The error format depends on the output mode: TTY:
Error: Not authenticated. Run `outlit auth login` or pass --api-key.
JSON (stderr):
{
  "error": "Not authenticated. Run `outlit auth login` or pass --api-key.",
  "code": "not_authenticated"
}

Error Codes

CodeDescription
not_authenticatedNo API key found in any source
invalid_key_formatAPI key doesn’t match expected format (ok_ prefix)
invalid_keyAPI key rejected by the server
validation_failedKey failed server verification during auth login
auth_requiredClient creation failed (authentication error)
missing_key--key flag required but not provided (non-interactive auth login)
missing_inputRequired argument not provided
api_errorAPI request failed (includes HTTP status)
write_errorFailed to write a config file
unlink_errorFailed to delete credentials file during auth logout
exec_errorSubprocess execution failed (setup commands)

Data Formatting

The CLI formats values for readability in TTY mode:
TypeRaw valueDisplayed as
MRR (cents)500000$5000.00
Date2025-02-10T15:30:00Z2d ago
Long namesVery Long Customer Name IncVery Long Custo...
Missing valuesnull / undefined--

Relative Date Format

Time elapsedDisplay
Under 1 minutejust now
Under 1 hour5m ago
Under 1 day3h ago
Under 30 days7d ago
Under 1 year2mo ago
1 year or more1y ago

Scripting Examples

Export All Customers

#!/bin/bash
LIMIT=100
CURSOR=""

while true; do
  if [ -z "$CURSOR" ]; then
    PAGE=$(outlit customers list --limit $LIMIT --json)
  else
    PAGE=$(outlit customers list --limit $LIMIT --cursor "$CURSOR" --json)
  fi

  jq -r '.items[].domain' <<< "$PAGE" >> all_domains.txt

  HAS_MORE=$(jq -r '.pagination.hasMore' <<< "$PAGE")
  [ "$HAS_MORE" = "false" ] && break

  CURSOR=$(jq -r '.pagination.nextCursor' <<< "$PAGE")
done

Export to CSV

outlit customers list --limit 100 --json \
  | jq -r '.items[] | [.domain, .billingStatus, .currentMrr] | @csv'

CI Health Check

# Validate API key and agent setup in CI
outlit doctor --json | jq -e '.ok' > /dev/null || exit 1

Filter Churned Users

outlit users list --journey-stage CHURNED --no-activity-in 30d --json \
  | jq '.items[] | {email, customer: .customerId, lastSeen: .lastActivityAt}'