Looped CLI
Work with Track, Invoices and Manage from your terminal
The Looped CLI is a command-line tool called looped. It lets you log time, manage todos and projects, create and send invoices and quotes, and run company admin tasks from your terminal, without opening the apps.
It talks to the same public API as any other integration, at https://api.looped.sh. You sign in as yourself, so the CLI can do exactly what your role lets you do in the apps, no more.
The CLI covers three apps:
| Command | App |
|---|---|
looped track | Time entries, the timer, projects, sections, tags, todos, preferences, dashboard and reports |
looped invoices | Invoices, quotes, clients, statements and the invoice dashboard |
looped manage | Team members, invites, company settings, address, bank details and API keys |
Financials and Payroll aren't in the CLI.
See the command reference for every command and flag.
Installing
Caution
The CLI isn't published to npm, Homebrew or as a downloadable binary yet. For now it's built from source in the Looped monorepo, which needs Node.js and pnpm.
From a checkout of the monorepo, with dependencies installed (pnpm install):
pnpm --filter @looped/cli build
node apps/cli/dist/index.js --helpThe build writes the looped entry point to apps/cli/dist/index.js. To call it as looped from anywhere, link the package onto your path:
cd apps/cli
pnpm link --global
looped --versionThe examples in these docs use looped. If you didn't link it, use node apps/cli/dist/index.js in its place.
Signing in
looped loginThis opens your browser at Looped's sign-in page. Sign in with your normal Looped account. When you're done, the browser shows "Login successful" and you can close the tab.
If the browser doesn't open by itself, the CLI prints the sign-in URL. Copy it into a browser on the same machine.
A few things to know:
- The CLI listens for the browser's reply on
http://127.0.0.1:8952. If something else is using port 8952,looped loginstops with an error. Close whatever holds the port and try again. - You have 5 minutes to finish signing in. After that, run
looped loginagain. - Your session refreshes itself in the background. If it can't (for example, after a long time away), commands fail with an authentication error and you run
looped loginagain.
The CLI doesn't sign in with API keys. For scripts and CI jobs that need a key, call the public API directly.
Choosing a company
Everything in Looped belongs to a company, and the CLI works with one company at a time.
After you sign in, the CLI lists your companies and your role in each:
Which company do you want to use?
1) Acme Studio (OWNER)
2) Personal (OWNER)
Enter a number (1-2):Type the number and press Enter. If you only belong to one company, the CLI picks it without asking.
To switch companies, run looped login again and pick a different one. There's no separate command for switching.
To check who you're signed in as and which company is selected:
looped whoamiUser: <your user id>
Company: <selected company id>
Key: bearer-token
Scopes: track:time.read, track:time.write, invoices:invoices.read, ...Key always reads bearer-token for a CLI session, because you signed in as yourself rather than with an API key. Scopes lists your permissions in Track, Invoices and Manage for the selected company. If a command fails with a permission error, the message names the permission you're missing. Ask an Owner or Admin to change your roles.
Signing out
looped logoutThis removes the saved session from your config file. Any apiUrl setting stays.
Config file
The CLI keeps its settings in your home directory:
| File | What's in it |
|---|---|
~/.looped/config.json | Your session (tokens, selected company) and an optional apiUrl |
~/.looped/track-timer.json | The timer started by looped track start, while it's running |
Both are plain JSON. config.json holds your sign-in tokens, so treat it like a password and don't share or commit it.
The CLI talks to https://api.looped.sh by default. To point it somewhere else, set apiUrl in config.json or the LOOPED_API_URL environment variable. The environment variable wins if both are set.
{
"apiUrl": "https://api.looped.sh"
}Getting help
Every command and command group has built-in help:
looped --help
looped track --help
looped track todos create --helpPrint the installed version with:
looped --versionOutput and scripting
Most commands print a table or a short message. Add --json to print the API's response as JSON instead, which is easier to pipe into jq or a script:
looped invoices list --status OVERDUE --json | jq '.[].serial'When a command fails, the CLI prints a one-line error to stderr and exits with code 1.
Where to go next
Are you an AI? Visit llms.txt — these docs as plain markdown.