Profiles
Use a different profile for a single command
--profile <name> works on every command and doesn’t change your default.
Sign out
duvo logout revokes the OAuth tokens server-side and removes the profile locally.
Environment variables
For non-interactive use (CI, scripts), the CLI also reads:Teams
A profile’s credentials are scoped to a team. Use these commands to confirm which team you’re acting on and inspect its members before running commands that change data.--team is omitted, member listing uses the team scoped to your API key or active profile. Add --json to any command for machine-readable output.
The org-* commands are the exception to the team scoping above. They read across every team in the organization, so a key pinned to a single team is rejected — use one created with access set to all teams you can access, and an organization Admin, Executive, or Owner role.
org-runs carries one time window per lifecycle timestamp, and they are not interchangeable. Reach for --created-after / --created-before to ask “everything in this period”: every run has a creation time, so that window drops nothing. --started-after / --started-before excludes runs that never started — pair both ends with --status running to bound a stuck-run sweep, since a lower bound is what stops it also counting runs left running months ago. --completed-after / --completed-before filter on completion, so they never match a run that is still going — they are also accepted as --since / --until, the names duvo runs list ships, but the column-named pair is the one to reach for here, where all three windows exist side by side. Every bound is half-open ([after, before)), so consecutive windows tile without counting a run twice, and the three windows combine.
With no time bound at all, org-runs returns the last 7 days of runs and says so (default window: last 7 days in the summary line). An organization’s history is unbounded and a monitor wants what is recent, so the default keeps an unfiltered poll cheap however long the organization has been running. Pass any bound — on creation, start or completion — to replace it.
org-runs does not count matches unless asked: without --include-total the response carries no total, so a full page is reported as More may be available alongside the --offset that reaches the next one. Pass --include-total for Showing X of Y — it walks every match, which is the expensive half of an org-wide query.
org-runs pages up to 500 runs at a time (--limit 500), five times the team runs list cap, because pulling an organization’s history is rate-bound rather than query-bound: the API allows 100 requests a minute per key, so page size decides how fast a month of runs comes back.
To read more than one page, follow the cursor: every page that has a successor prints Next page: --cursor <value>, and passing that value (with the same filters) returns exactly the runs after the one you last saw. There is no --offset here, unlike runs list and teams org-agents: runs are created constantly, so an offset sweep can repeat a run at a page boundary or, on a --status needs_attention poll where runs are also being resolved, skip one. A cursor does neither. Agents are a small, slow-changing directory, which is why that list keeps --offset.
Manage people already on the team
These change who is on the team and what they can do.duvo invite is for people who haven’t joined yet.
--team <team-id> to act on a team other than the active one, and --json for machine-readable output. Get member ids from duvo team members.
Both remove-member and leave ask for confirmation before acting; pass --yes to skip the prompt in scripts. In a non-interactive shell they refuse rather than treat piped input as consent.
Invite people
duvo invite covers both team and organization invitations. Team commands honour --team; invite org-member takes the organization id positionally and needs an org Admin, Executive, or Owner role.
duvo teams invite-org-member was removed in 1.46.0 with no alias. Use duvo invite org-member <org-id> instead.--process-role with --process to attach one of that Process’s configured roles. The team invitation remains a Clarity Member invitation; an existing teammate keeps their team role. Reusing an invitation with a different Process assignment fails without replacing the original assignment.
When you ask for an email and it does not go out, the command still prints the invitation ID and then exits non-zero, so a script can tell that the delivery failed. If the failure was ambiguous — a timeout or a gateway error, where the server may already have sent the mail — the message says so rather than claiming nobody was notified; check with the recipient before resending, or you may deliver a second invitation.
duvo invite bulk exits non-zero when any invitation was rolled back.No command takes a frontend URL. The accept link is built server-side from the environment’s configured app origin, so an invitation email always points at the real Duvo app.
Confirm your team before a destructive command
Related
Duvo CLI
installation and first sign-in
Scripting and CI/CD Patterns
authenticating with API keys in pipelines