| name | otta-cli |
| description | Use `otta-cli` to automate `otta.fi` workflows from terminal. This tool is usually used for tracking working time, absences, and sick leaves: authenticate, inspect config/cache, check account status, manage worktimes (list/read/add/update/delete), browse absences, fetch holidays, and generate combined/detailed calendar reports. Trigger this skill when a request needs CLI-first Otta operations, `OTTA_CLI_*` environment setup, machine-readable `--format json` output, or diagnosis of auth/config/API validation errors. |
Otta CLI
Use this skill to execute Otta time-tracking tasks end-to-end with repeatable CLI commands.
Main repository: https://github.com/mekedron/otta-cli
Quick Start
-
Use the otta binary directly.
-
Verify command surface and storage paths.
otta --help
otta config path
otta config cache-path
- Authenticate and hydrate cache.
otta auth login --username "$OTTA_CLI_USERNAME" --password "$OTTA_CLI_PASSWORD" --format json
otta status --format json
status updates cached user metadata (for user and worktimegroup fallbacks used by worktimes/holidays/calendar commands).
- For non-interactive automation, prefer
--password-stdin or secret env handling to reduce shell history exposure.
Command Recipes
Use explicit dates/times in YYYY-MM-DD and HH:MM formats.
List worktimes:
otta worktimes list --date 2026-02-20 --format json
Read worktime by id:
otta worktimes read --id <worktime-id> --format json
Add worktime:
otta worktimes add \
--date 2026-02-20 \
--start 09:00 \
--end 17:00 \
--pause 30 \
--project <project-id> \
--worktype <worktype-id> \
--description "Example task description" \
--format json
--user is optional if OTTA_CLI_USER_ID or cached user ID exists.
Update worktime:
otta worktimes update --id <worktime-id> --start 10:00 --end 18:00 --format json
- Send at least one changed field with
--id.
Delete worktime:
otta worktimes delete --id <worktime-id> --format json
Fetch holidays/workday calendar:
otta holidays \
--from 2026-02-20 \
--to 2026-02-29 \
--worktimegroup <worktimegroup-id> \
--format json
--worktimegroup is optional if OTTA_CLI_WORKTIMEGROUP_ID or cached value exists.
- explicit subcommand form is also available:
otta holidays read --from ... --to ... --worktimegroup ... --format json
Browse absences:
otta absence browse \
--from 2026-02-01 \
--to 2026-02-28 \
--format json
Read one absence by id:
otta absence read --id <absence-id> --format json
Add absence:
otta absence add \
--mode days \
--type <absence-type-id> \
--from 2026-02-20 \
--to 2026-02-20 \
--description "sick leave" \
--format json
Add hour-based absence:
otta absence add \
--mode hours \
--type <absence-type-id> \
--from 2026-02-20 \
--start 09:00 \
--end 11:30 \
--hours 2.5 \
--description "extra hours" \
--format json
-
otta absence add mode handling:
--mode auto|days|hours (default auto)
auto resolves to hours if --start, --end, or --hours is present; otherwise days
hours requires --start and --end, and enforces --to == --from
-
resolve mode-specific type IDs with:
otta absence options --mode days --format json
otta absence options --mode hours --format json
-
--user is optional if OTTA_CLI_USER_ID or cached user ID exists.
Update absence:
otta absence update --id <absence-id> --description "sick leave" --format json
Delete absence:
otta absence delete --id <absence-id> --format json
Fetch current cumulative saldo:
otta saldo --format json
Generate combined calendar overview:
otta calendar overview \
--from 2026-02-01 \
--to 2026-02-28 \
--format json
Generate detailed calendar day-by-day report:
otta calendar detailed \
--from 2026-02-01 \
--to 2026-02-28 \
--format json
- Preferred way for a user to observe the summary for personal work times.
Use alternate duration units when totals are minute-based:
otta calendar detailed --from 2026-02-01 --to 2026-02-28 --format json --duration-format hours
otta worktimes browse --from 2026-02-01 --to 2026-02-28 --format json --duration-format days
--duration-format values: minutes (default), hours, days, hhmm
- day conversion is fixed at
1 day = 24h = 1440 minutes
Generate absence comment text:
otta absence comment \
--type sick \
--from 2026-02-20 \
--to 2026-02-20 \
--details "Flu symptoms" \
--format json
Environment Variables
Use these variables when running in CI/non-interactive environments:
OTTA_CLI_CONFIG_PATH
OTTA_CLI_CACHE_PATH
OTTA_CLI_API_BASE_URL
OTTA_CLI_CLIENT_ID
OTTA_CLI_USERNAME
OTTA_CLI_PASSWORD
OTTA_CLI_ACCESS_TOKEN
OTTA_CLI_TOKEN_TYPE
OTTA_CLI_REFRESH_TOKEN
OTTA_CLI_TOKEN_SCOPE
OTTA_CLI_USER_ID
OTTA_CLI_WORKTIMEGROUP_ID
Agent Operating Rules
- Prefer
--format json for all data-producing commands and parse response fields instead of scraping text output.
worktimes list/read/browse/report are worktime-only and never include absences; do not infer absences from empty worktime rows.
- For user schedule checks/log interpretation and personal worktime summaries, prefer
calendar detailed --format json first; use calendar overview as lighter fallback.
- Use
--duration-format when users request non-minute output; keep raw minute values for auditability.
- Run
status --format json before operations that rely on cached user/worktimegroup metadata.
- Validate dates/times before command execution (
YYYY-MM-DD, HH:MM).
- Run
worktimes list before update or delete when IDs are not explicitly known.
- For
absence add, always resolve and use the right mode (days vs hours) and fetch mode-specific type options before choosing --type.
- Return exact command, exit code, and concise stderr message when failures happen.
- Never print raw credentials or tokens in summaries.
Failure Recovery
no access token configured (run \otta auth login`)`
- Run
auth login, then rerun status.
username is required (use --username)
- Pass
--username or set OTTA_CLI_USERNAME.
--worktimegroup is required (...)
- Pass
--worktimegroup, set OTTA_CLI_WORKTIMEGROUP_ID, or run status to refresh cache.
--date must be YYYY-MM-DD, --start must be HH:MM, --to must be greater than or equal to --from
- Correct input format/order, rerun command.
directory ... is contained in a module that is not one of the workspace modules listed in go.work
- Build/run with
GOWORK=off in this repository context.