CLI command reference
Every looped command, its flags, and an example
This page lists every command in the Looped CLI. Run any command with --help to see the same flags in your terminal.
Conventions
A few rules apply across all commands:
- Ids, not names. Flags like
--project,--clientand--sectiontake an id. Each app has a lookup command that shows ids:looped track projects,looped track sections list,looped invoices clients,looped manage team list. --json. Most commands print a table or a short message. Add--jsonto print the API's response as JSON instead.--confirm. Commands that delete something or can't be undone refuse to run without--confirm. There's no interactive prompt, so scripts pass--confirmtoo. Without it, nothing is sent to Looped.- Dates. Dates are
YYYY-MM-DDunless a flag says otherwise. - Comma-separated lists. Flags that take several values, like
--status PAID,OVERDUE, take them as one comma-separated value. - Permissions. Each command needs the matching permission in your role. If you don't have it, the command fails and the error names the permission.
Account
looped login
Signs in through your browser and asks which company to use. See Signing in.
looped loginlooped logout
Removes your saved session.
looped logoutlooped whoami
Shows your user id, the selected company's id and your permissions for that company.
looped whoamiTrack
Commands for Looped Track. All of them live under looped track.
Time entries
looped track list
Lists your time entries for a day. Without flags, it shows today.
| Flag | Description |
|---|---|
--date <date> | The day to list (YYYY-MM-DD). Defaults to today |
--frequency <frequency> | day, week or month. Widens the range around --date |
--project <projectId> | Only show entries for this project |
--json | Print JSON |
looped track list --date 2026-09-21 --frequency weeklooped track start <taskName>
Starts a timer for a new time entry. The entry is created in Looped straight away with a duration of one second, and the CLI remembers it in ~/.looped/track-timer.json until you stop it. Only one timer can run at a time.
| Flag | Description |
|---|---|
--project <projectId> | Project to log the time against |
--section <sectionId> | Section to log the time against |
--description <text> | A longer description |
--json | Print JSON |
looped track start "Homepage redesign" --project <projectId>looped track stop
Stops the running timer and saves the elapsed time on the entry.
If the entry was deleted in the web app while the timer ran, stop fails but clears the timer so you can start a new one.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track stoplooped track time get <id>
Shows one time entry.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track time get <entryId>looped track time update <id>
Changes a time entry. Only the fields you pass change.
| Flag | Description |
|---|---|
--task-name <name> | New task name |
--description <text> | New description |
--date <date> | New date, as an ISO 8601 date-time |
--duration <seconds> | New duration, in seconds |
--project <projectId> | Move the entry to this project |
--section <sectionId> | Move the entry to this section |
--json | Print JSON |
looped track time update <entryId> --duration 5400looped track time delete <id>
Deletes a time entry.
| Flag | Description |
|---|---|
--confirm | Required |
looped track time delete <entryId> --confirmProjects
looped track projects
Lists projects. Use it to find the id to pass to --project.
| Flag | Description |
|---|---|
--status <status> | Only show projects with this status, such as ACTIVE |
--search <query> | Search by title or code |
--json | Print JSON |
looped track projects --status ACTIVE --search websitelooped track project create <title>
Creates a project. The CLI doesn't print the new project's id; run looped track projects --search "<title>" to find it.
| Flag | Description |
|---|---|
--code <code> | Project code. Generated for you if you leave it out |
looped track project create "Website refresh" --code WEBlooped track project update <id>
Changes a project's title, code or status.
| Flag | Description |
|---|---|
--title <title> | New title |
--code <code> | New code |
--status <status> | PENDING, ACTIVE, COMPLETED or ARCHIVED |
looped track project update <projectId> --status COMPLETEDlooped track project delete <id>
Deletes a project. Looped only deletes a project that has no time entries.
| Flag | Description |
|---|---|
--confirm | Required |
looped track project delete <projectId> --confirmSections
Sections split a project into parts.
looped track sections list
Lists a project's sections.
| Flag | Description |
|---|---|
--project <projectId> | Required. The project |
--json | Print JSON |
looped track sections list --project <projectId>looped track sections create <title>
Adds a section to a project.
| Flag | Description |
|---|---|
--project <projectId> | Required. The project |
--json | Print JSON |
looped track sections create "Design" --project <projectId>looped track sections update <id> <title>
Renames a section.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track sections update <sectionId> "Discovery"looped track sections delete <id>
Deletes a section. Looped only deletes a section that has no time entries.
| Flag | Description |
|---|---|
--confirm | Required |
looped track sections delete <sectionId> --confirmTags
See Tags.
looped track tags list
Lists your company's tags.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track tags listlooped track tags create <title>
Creates a tag.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track tags create "billable"looped track tags update <id> <title>
Renames a tag.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track tags update <tagId> "non-billable"looped track tags delete <id>
Deletes a tag. Looped only deletes a tag that isn't on any time entries.
| Flag | Description |
|---|---|
--confirm | Required |
looped track tags delete <tagId> --confirmTodos
looped track todos list
Lists todos.
| Flag | Description |
|---|---|
--filter <filter> | all, active or completed. Defaults to all |
--json | Print JSON |
looped track todos list --filter activelooped track todos create <title>
Creates a todo.
| Flag | Description |
|---|---|
--description <text> | A longer description |
--project <projectId> | Project |
--section <sectionId> | Section |
--priority <priority> | P1 (highest) to P4 (lowest) |
--due-date <date> | Due date, ISO 8601 |
--json | Print JSON |
looped track todos create "Send wireframes" --priority P1 --due-date 2026-10-01looped track todos get <id>
Shows one todo.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track todos get <todoId>looped track todos update <id>
Changes a todo. Only the fields you pass change.
| Flag | Description |
|---|---|
--title <title> | New title |
--description <text> | New description |
--completed | Mark it done |
--not-completed | Mark it not done |
--project <projectId> | New project |
--section <sectionId> | New section |
--priority <priority> | P1 to P4 |
--due-date <date> | New due date, ISO 8601 |
--json | Print JSON |
looped track todos update <todoId> --completedlooped track todos delete <id>
Deletes a todo.
| Flag | Description |
|---|---|
--confirm | Required |
looped track todos delete <todoId> --confirmPreferences
These are your company's Track settings. get and update always print JSON.
looped track preferences get
Shows the company's time-tracking preferences.
looped track preferences getlooped track preferences update
Changes the company's time-tracking preferences. Only the flags you pass change.
| Flag | Description |
|---|---|
--time-unit <unit> | HOUR or MINUTE |
--time-step <n> | Rounding step in the chosen unit, or none to stop rounding |
--ghost-text / --no-ghost-text | Turn ghost-text suggestions on or off |
--auto-log / --no-auto-log | Turn logging time when a todo is completed on or off |
looped track preferences update --time-unit MINUTE --time-step 15Dashboard
looped track dashboard
Prints a weekly or monthly time summary as JSON.
| Flag | Description |
|---|---|
--scope <scope> | me or team. team needs a role that can see everyone's time |
--period <period> | weekly or monthly |
--week-end <date> | Any date inside the week or month you want (YYYY-MM-DD) |
looped track dashboard --period monthly --week-end 2026-09-15Reports
Reports are pivot tables of time data, the same ones you build in Reports. A report's definition (its schema) is JSON with rows, columns, values and filters. The easiest way to get one is to build the report in Track, then copy its schema from looped track reports get <id> --json.
looped track reports list
Lists the saved reports you can see.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track reports listlooped track reports get <id>
Shows one saved report.
| Flag | Description |
|---|---|
--json | Print JSON |
looped track reports get <reportId> --jsonlooped track reports run
Runs a report without saving it. Unless your role lets you see everyone's time, the results only include your own time.
| Flag | Description |
|---|---|
--schema <json> | The full report schema as JSON |
--rows <fields> | Comma-separated row fields. Overrides rows in --schema |
--columns <fields> | Comma-separated column fields. Overrides columns in --schema |
--start-date <date> | Start date, ISO 8601 |
--end-date <date> | End date, ISO 8601 |
--json | Print JSON |
looped track reports run --schema "$(cat report.json)" \
--start-date 2026-09-01 --end-date 2026-09-30looped track reports save <name>
Saves a report definition so you and others can run it again.
| Flag | Description |
|---|---|
--schema <json> | Required. The full report schema as JSON |
--allowed-roles <roles> | Comma-separated roles that can see it: OWNER, ADMIN, MEMBER |
--allowed-users <userIds> | Comma-separated user ids that can see it |
--json | Print JSON |
looped track reports save "Hours by project" --schema "$(cat report.json)" \
--allowed-roles OWNER,ADMINlooped track reports update <id>
Replaces a saved report's name and schema. Only Owners, Admins and the report's creator can change it.
| Flag | Description |
|---|---|
--name <name> | Required. The report name |
--schema <json> | Required. The full report schema as JSON |
--allowed-roles <roles> | Comma-separated roles that can see it |
--allowed-users <userIds> | Comma-separated user ids that can see it |
--json | Print JSON |
looped track reports update <reportId> --name "Hours by project" \
--schema "$(cat report.json)"looped track reports delete <id>
Deletes a saved report. Only Owners, Admins and the report's creator can delete it.
| Flag | Description |
|---|---|
--confirm | Required |
looped track reports delete <reportId> --confirmInvoices
Commands for Looped Invoices. All of them live under looped invoices.
Invoice statuses are PENDING, PAID, PAID_PARTIAL, EXPIRED and OVERDUE.
Invoices
looped invoices list
Lists invoices.
| Flag | Description |
|---|---|
--status <statuses> | Comma-separated statuses, such as PAID,OVERDUE |
--client <clientId> | Only this client's invoices |
--from <date> | Issued on or after this date |
--to <date> | Issued on or before this date |
--json | Print JSON |
looped invoices list --status OVERDUE --from 2026-07-01looped invoices get <id>
Shows one invoice.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices get <invoiceId>looped invoices create
Creates an invoice. Invoices have too many fields for one flag each, so you pass the whole invoice as a JSON object, either inline with --data or from a file with --data-file. Pass one or the other, not both. The invoice needs a clientId (or a client object) and at least one line item. If the JSON doesn't match what Looped expects, the error says which field is wrong. The API reference lists every field.
| Flag | Description |
|---|---|
--data <json> | The invoice as inline JSON |
--data-file <path> | Path to a JSON file with the invoice |
--json | Print JSON |
looped invoices create --data '{
"clientId": "<clientId>",
"lineItems": [{ "description": "Consulting", "unitPrice": 100, "quantity": 5 }]
}'looped invoices update <id>
Changes an invoice. Takes the same --data or --data-file JSON as create.
| Flag | Description |
|---|---|
--data <json> | The changes as inline JSON |
--data-file <path> | Path to a JSON file with the changes |
--json | Print JSON |
looped invoices update <invoiceId> --data-file invoice.jsonlooped invoices delete <id>
Permanently deletes an invoice.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped invoices delete <invoiceId> --confirmlooped invoices mark-paid <id>
Marks an invoice as paid.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices mark-paid <invoiceId>looped invoices send <id>
Emails an invoice to its client.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices send <invoiceId>looped invoices pdf <id>
Downloads an invoice as a PDF.
| Flag | Description |
|---|---|
--output <path> | Required. Where to save the PDF |
--download | Ask the server to send it as an attachment |
looped invoices pdf <invoiceId> --output invoice.pdflooped invoices dashboard
Shows a summary of revenue, outstanding invoices and top clients.
| Flag | Description |
|---|---|
--json | Print the full dashboard data |
looped invoices dashboardStatements
looped invoices statements
Builds a statement for one client. By default it prints the statement as JSON. For a PDF, a CSV or a Xero-ready CSV, pass --format and --output.
| Flag | Description |
|---|---|
--client <clientId> | Required. The client |
--from <date> | Start of the period. Defaults to the start of the year |
--to <date> | End of the period. Defaults to today |
--status <statuses> | Comma-separated invoice statuses to include |
--format <format> | json (default), pdf, csv or xero |
--output <path> | Where to save the file. Required unless --format is json |
--download | Ask the server to send it as an attachment |
looped invoices statements --client <clientId> --format pdf --output statement.pdfClients
See Clients.
looped invoices clients
Lists clients. Use it to find the id to pass to --client.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices clientslooped invoices client get <id>
Shows one client.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices client get <clientId>looped invoices client update <id>
Replaces a client's details. This isn't a partial update: the JSON must include at least name, email, line1 and postalCode every time.
| Flag | Description |
|---|---|
--data <json> | The client as inline JSON |
--data-file <path> | Path to a JSON file with the client |
--json | Print JSON |
looped invoices client update <clientId> --data-file client.jsonlooped invoices client delete <id>
Permanently deletes a client.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped invoices client delete <clientId> --confirmQuotes
All quote commands live under looped invoices quotes. Quote statuses are DRAFT, SENT, ACCEPTED, REJECTED, EXPIRED and CONVERTED.
looped invoices quotes list
Lists quotes.
| Flag | Description |
|---|---|
--status <statuses> | Comma-separated statuses, such as SENT,ACCEPTED |
--client <clientId> | Only this client's quotes |
--from <date> | Issued on or after this date |
--to <date> | Issued on or before this date |
--json | Print JSON |
looped invoices quotes list --status SENTlooped invoices quotes get <id>
Shows one quote.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices quotes get <quoteId>looped invoices quotes create
Creates a quote. Like invoices create, it takes the whole quote as JSON.
| Flag | Description |
|---|---|
--data <json> | The quote as inline JSON |
--data-file <path> | Path to a JSON file with the quote |
--json | Print JSON |
looped invoices quotes create --data-file quote.jsonlooped invoices quotes update <id>
Changes a quote.
| Flag | Description |
|---|---|
--data <json> | The changes as inline JSON |
--data-file <path> | Path to a JSON file with the changes |
--json | Print JSON |
looped invoices quotes update <quoteId> --data-file quote.jsonlooped invoices quotes delete <id>
Permanently deletes a quote.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped invoices quotes delete <quoteId> --confirmlooped invoices quotes send <id>
Emails a quote to its client.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices quotes send <quoteId>looped invoices quotes set-status <id>
Marks a quote as accepted or rejected. A converted quote can't change status.
| Flag | Description |
|---|---|
--status <status> | Required. ACCEPTED or REJECTED |
--json | Print JSON |
looped invoices quotes set-status <quoteId> --status ACCEPTEDlooped invoices quotes convert <id>
Turns a quote into an invoice. The quote's status becomes CONVERTED.
| Flag | Description |
|---|---|
--json | Print JSON |
looped invoices quotes convert <quoteId>looped invoices quotes pdf <id>
Downloads a quote as a PDF.
| Flag | Description |
|---|---|
--output <path> | Required. Where to save the PDF |
--download | Ask the server to send it as an attachment |
looped invoices quotes pdf <quoteId> --output quote.pdfManage
Commands for your company's account. All of them live under looped manage. Most need an Owner or Admin; see Roles & permissions.
Members and invites
looped manage team list
Lists the company's members. The ID column is the member id that remove and change-role take.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage team listlooped manage team invite <email>
Invites someone to the company by email.
| Flag | Description |
|---|---|
--role <role> | admin or member. Defaults to member |
--roles <ids> | Comma-separated role ids they start with, such as track.member,invoices.admin, or a custom role's id. If you leave it out, a Member gets track.member and an Admin gets none |
--json | Print JSON |
Built-in role ids include track.admin, track.member, invoices.admin, financials.admin and payroll.admin. See Roles & permissions.
looped manage team invite sam@example.com --role member --roles track.member,invoices.adminlooped manage team invites
Lists pending invites.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage team inviteslooped manage team revoke-invite <inviteId>
Cancels a pending invite.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage team revoke-invite <inviteId>looped manage team change-role <memberId>
Changes a member's base role, their roles, or both. Pass at least one of --role and --roles.
| Flag | Description |
|---|---|
--role <role> | owner, admin or member. Only an Owner can make someone an Owner |
--roles <ids> | Their full list of role ids, comma-separated. This replaces the list they have. An empty string (--roles "") removes all their roles |
--json | Print JSON |
looped manage team change-role <memberId> --role admin
looped manage team change-role <memberId> --roles track.admin,invoices.adminlooped manage team remove <memberId>
Removes a member from the company. They need a new invite to come back.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped manage team remove <memberId> --confirmlooped manage team leave
Removes you from the selected company. You need a new invite to come back.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped manage team leave --confirmCompany settings
looped manage settings show
Shows the company's name, VAT number, currency and other settings.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage settings showlooped manage settings update
Changes company settings. Only the flags you pass change; pass at least one.
| Flag | Description |
|---|---|
--name <name> | Company name |
--vat-number <vatNumber> | VAT number |
--currency <currency> | Currency code, such as USD |
--auto-add-members <true|false> | Whether new members are added to this company automatically. Takes the word true or false |
--json | Print JSON |
looped manage settings update --currency ZAR --auto-add-members falselooped manage settings friendly-id <friendlyId>
Changes the company's friendly id, the short name used in its URLs.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage settings friendly-id acme-studiolooped manage settings address show
Shows the company's billing address. This is also the address on your invoices.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage settings address showlooped manage settings address set
Sets the company's billing address. Creates it if there isn't one yet, or replaces it. Lines you leave out are cleared.
| Flag | Description |
|---|---|
--line1 <line1> | Required. Address line 1 |
--line2 <line2> | Address line 2 |
--line3 <line3> | Address line 3 |
--postal-code <postalCode> | Required. Postal code |
--json | Print JSON |
looped manage settings address set --line1 "12 Long Street" --line2 "Cape Town" --postal-code 8001looped manage settings bank show
Shows the company's bank account details.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage settings bank showlooped manage settings bank set
Sets the company's bank account details. Creates them if there aren't any yet, or replaces them. All five details are required.
| Flag | Description |
|---|---|
--account-holder <name> | Required. Account holder name |
--account-no <accountNo> | Required. Account number |
--account-type <accountType> | Required. Account type |
--bank-name <bankName> | Required. Bank name |
--branch-code <branchCode> | Required. Branch code |
--json | Print JSON |
looped manage settings bank set --account-holder "Acme Studio" --account-no 123456789 \
--account-type Cheque --bank-name "Example Bank" --branch-code 250655looped manage settings delete-team
Permanently deletes the selected company. This can't be undone. Only an Owner can do it, and Looped refuses if the company has an active subscription or it's your only company. See Danger zone.
| Flag | Description |
|---|---|
--confirm | Required |
--json | Print JSON |
looped manage settings delete-team --confirmAPI keys
These commands manage the company's API keys. They need the "Manage API keys" permission, which Owners and Admins have.
looped manage keys list
Lists the company's API keys, with their permissions, whether they're revoked, and when they expire.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage keys listlooped manage keys create
Creates an API key. The CLI prints the raw key once. Copy it then: it can't be shown again.
| Flag | Description |
|---|---|
--name <name> | Required. A label for the key |
--scope <scopes> | Required. Comma-separated permissions, such as track:time.read,track:time.write |
--expires-at <isoDate> | Expiry date, ISO 8601. Leave it out for a key that doesn't expire |
--json | Print JSON |
looped manage keys create --name "Reporting service" \
--scope track:time.read,invoices:invoices.read --expires-at 2027-01-01looped manage keys revoke <id>
Revokes an API key. Anything using it stops working straight away.
| Flag | Description |
|---|---|
--json | Print JSON |
looped manage keys revoke <keyId>Are you an AI? Visit llms.txt — these docs as plain markdown.