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
ottabinary 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
statusupdates cached user metadata (foruserandworktimegroupfallbacks used by worktimes/holidays/calendar commands).- For non-interactive automation, prefer
--password-stdinor 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
--useris optional ifOTTA_CLI_USER_IDor 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
--worktimegroupis optional ifOTTA_CLI_WORKTIMEGROUP_IDor 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 addmode handling:--mode auto|days|hours(defaultauto)autoresolves tohoursif--start,--end, or--hoursis present; otherwisedayshoursrequires--startand--end, and enforces--to == --from
resolve mode-specific type IDs with:
otta absence options --mode days --format jsonotta absence options --mode hours --format json
--useris optional ifOTTA_CLI_USER_IDor 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-formatvalues: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_PATHOTTA_CLI_CACHE_PATHOTTA_CLI_API_BASE_URLOTTA_CLI_CLIENT_IDOTTA_CLI_USERNAMEOTTA_CLI_PASSWORDOTTA_CLI_ACCESS_TOKENOTTA_CLI_TOKEN_TYPEOTTA_CLI_REFRESH_TOKENOTTA_CLI_TOKEN_SCOPEOTTA_CLI_USER_IDOTTA_CLI_WORKTIMEGROUP_ID
Agent Operating Rules
- Prefer
--format jsonfor all data-producing commands and parse response fields instead of scraping text output. worktimes list/read/browse/reportare 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 jsonfirst; usecalendar overviewas lighter fallback. - Use
--duration-formatwhen users request non-minute output; keep raw minute values for auditability. - Run
status --format jsonbefore operations that rely on cached user/worktimegroup metadata. - Validate dates/times before command execution (
YYYY-MM-DD,HH:MM). - Run
worktimes listbeforeupdateordeletewhen IDs are not explicitly known. - For
absence add, always resolve and use the right mode (daysvshours) 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 rerunstatus.
- Run
username is required (use --username)- Pass
--usernameor setOTTA_CLI_USERNAME.
- Pass
--worktimegroup is required (...)- Pass
--worktimegroup, setOTTA_CLI_WORKTIMEGROUP_ID, or runstatusto refresh cache.
- Pass
--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=offin this repository context.
- Build/run with