CLI: Agent Workflows
The Keito CLI is agent-friendly because every command supports JSON output, deterministic exit codes, non-interactive authentication, and structured error messages.
For local Codex and Claude Code sessions, the Keito Agent Skill is the recommended wrapper. It installs hooks and calls keito time session-record for you.
Required Environment
Agents should avoid interactive prompts. Configure credentials with environment variables:
export KEITO_API_KEY="kto_xxxxx"
export KEITO_ACCOUNT_ID="your_company_id"
Then run a preflight check:
keito auth status --json
Discovery Workflow
Agents should discover project and task IDs before starting work:
keito projects list --json
keito projects tasks --json
Use IDs in automation to avoid ambiguity:
keito time start \
--project "project_id_here" \
--task "task_id_here" \
--json
Timer Workflow
keito auth status --json
keito time running --json
keito time start --project "project_id_here" --task "task_id_here" --json
# agent performs work
keito time stop --notes "Implemented OAuth flow" --json
Call keito time running --json before time start. If another timer is running, time start exits with code 3 and suggests keito time stop.
Shell Wrapper Pattern
Use a trap so the timer is stopped when the process exits:
#!/usr/bin/env bash
set -euo pipefail
PROJECT_ID="${KEITO_PROJECT_ID:?Set KEITO_PROJECT_ID}"
TASK_ID="${KEITO_TASK_ID:?Set KEITO_TASK_ID}"
STARTED=0
cleanup() {
status=$?
if [ "$STARTED" = "1" ]; then
if [ "$status" -eq 0 ]; then
keito time stop --notes "Agent session completed" --json || true
else
keito time stop --discard --json || true
fi
fi
}
trap cleanup EXIT
keito auth status --json >/dev/null
keito time start --project "$PROJECT_ID" --task "$TASK_ID" --json
STARTED=1
agent-command "$@"
This pattern only stops or discards a timer if this script successfully started it.
Completed Session Workflow
Lifecycle hooks should record completed sessions with time session-record:
keito time session-record \
--project "project_id_here" \
--task "task_id_here" \
--session-id "codex-123" \
--duration-seconds 5400 \
--started-at 2026-05-12T09:00:00Z \
--ended-at 2026-05-12T10:30:00Z \
--source agent \
--metadata '{"integration":"custom_agent","agent_type":"codex"}' \
--json
If a session entry with the same session ID already exists for that date and source, the CLI updates it instead of creating a duplicate.
Error Handling
The CLI writes JSON errors to stderr in JSON mode:
{
"error": true,
"code": 3,
"message": "Conflict: A timer is already running. Stop it first with 'keito time stop'.",
"suggestion": "keito time stop"
}
Agents should use the exit code first and the suggestion field second.
| Code | Agent response |
|---|---|
1 | Re-check KEITO_API_KEY and KEITO_ACCOUNT_ID |
3 | Inspect keito time running --json; stop or reuse the existing timer intentionally |
4 | Refresh project/task IDs with discovery commands |
5 | Retry after a short delay |
6 or 7 | Retry with backoff or fail the session cleanly |
8 | Fix config or use environment variables |
Notes Convention
Use notes to make agent work auditable:
keito time stop \
--notes "Codex: implemented CLI docs, ran npm run build" \
--json
Use notes for a concise human-readable summary. Use --metadata, --agent-id, --agent-type, and --skill for structured reporting fields.
When to Use API or SDKs
Use the API, Node SDK, or Python SDK instead of the CLI when you need:
- LLM Usage expense creation
- tighter integration with a long-running application process
See Agent Integration Overview for those patterns.