fleetctl api calls Fleet Manager HTTP API endpoints from a shell. Its resource
commands are generated from docs/openapi.yaml: all readable GET operations are
exposed, plus a small allowlist of operator mutations (allocation device
assignment, job creation, and burn-in rerun planning and dispatch) that need an
authenticated API workflow instead of direct database access. The command list
therefore follows the committed OpenAPI surface instead of a hand-written
catalogue.
Use it when you need a quick API inspection tool, a copy-pasteable debugging
command, a way to dispatch an existing workflow, or a stable way for automation
to discover read endpoints. For writing a dedicated client, start with
Client Authentication and
Scopes & Permissions.
Quick start
Install dependencies, then confirm the command group is wired up:fleetctl-api; that application must allow the
authorization-code + PKCE flow and register http://127.0.0.1/callback as a
redirect URI. Django OAuth Toolkit treats loopback redirect URIs this way as
valid for any callback port, so the CLI’s default runtime redirect
http://127.0.0.1:8765/callback is covered.
Log in with the browser-based OAuth flow:
fleetctl api login uses the production API
(https://api.fleet.nscale.com) and stores credentials in the default
profile. Pass --base-url and --profile when you need dev, local, or a named
profile:
--no-open-browser; the command prints the authorization URL so you can open it
yourself.
If you change --client-id or --callback-port, the selected OAuth client must
still allow the resulting loopback callback.
Profiles are stored in ~/.config/fleetctl/api-tokens.json by default with
0600 file permissions. The file contains plaintext access and refresh tokens,
so treat it like any other local credential file. Set
FLEETCTL_API_TOKEN_STORE=/path/to/api-tokens.json when you need an isolated
token store for tests or automation.
Discover commands
Human users can discover the generated surface through--help:
src/fleet_manager/cli/commands/api/generated/fleetctl-api-agent-command-reference.md.
It is the compact command index for agent context, and outside a source checkout
fleetctl api agent-reference prints the same content. Generated help pages end with a
runnable example when the command needs no caller-specific values, or an explicitly
labelled usage template when IDs or request data must be supplied.
Resource names are singular and kebab-cased, for example device,
device-group, inventory-device, and job-device-status. Most generated
resources expose list for collection endpoints and get for detail endpoints.
Some OpenAPI actions are exposed as their action name when the endpoint is not a
plain list or retrieve.
Common call patterns
List resources:--all-devices true to select every device in the allocation’s site; a
request with no selector is rejected. Run without --dry-run true to apply the
memberships. The operation is idempotent for existing members. If another allocation overlaps,
the API still assigns every non-conflicting device but returns HTTP 409 with a
typed conflict list; the CLI prints that result and exits non-zero so the
conflict cannot be missed.
Unassign devices using the same selectors:
--dry-run true to remove the selected memberships. Devices that
are not members of the target allocation are reported as idempotent no-ops;
memberships in other allocations are never changed. To select the whole site,
pass --all-devices true explicitly; a bare unassignment request is rejected.
Override the profile URL for one call:
--debug to print HTTP method, final URL, status code, and request duration
to stderr. Authorization headers and token values are not printed.
Dispatch an existing workflow
The job-create command dispatches an existing Fleet Manager workflow. It does not create or edit workflow definitions:--data must contain a JSON object. Fleet Manager validates the workflow ID,
devices, parameters, eligibility, and conflicts.
Plan and dispatch burn-in reruns
Preview the minimum policy-satisfying reruns for selected devices without creating Jobs:- Add
job:createto thefleetctl-apiOAuth Application’s allowed scopes. - Grant the invoking user or group the Django permission
fleet_manager_core.add_job. - Run
fleetctl api loginagain so a new token is issued with the updated access.
--scope read-only deliberately excludes job:create, even
when both the application and user permit it.
Filters and output
Generated query parameters become kebab-case options. Check the command help for the exact options on each endpoint:key=value entries at the CLI:
--format json so structured output does not have to be requested on every call. Set
FLEETCTL_AGENT_MODE=true or false to force either behaviour, and an explicit
--format always wins.
After a successful call, commands print a Next: hint on stderr suggesting follow-up
commands pre-filled with the first result’s id — device list suggests
fleetctl api device get <id> — so results can be chained without re-deriving the
workflow. Hints never appear on stdout, so piped output stays clean.
Use --columns to keep only the fields you need, including dot paths for nested
fields. With the default table format it selects the table columns; with --format json
it projects every object down to those fields, whatever the response shape — a results
collection, a bare array, or a single object. Projection only narrows the fields inside
rows; it never adds or removes response-level keys such as count:
next page and
merge the results. --format count reads the count from the first page and does
not fetch the remaining pages.
At a large site an unfiltered list is slow and returns a snapshot whose per-row status
can lag the underlying record, because every page is merged in memory. Filter
server-side and size with --format count first; when a decision depends on one
resource’s current state, read it back by id or --name-exact rather than trusting a
row from a big merged list.
Troubleshooting
Error: API profile 'default' is not logged in: runfleetctl api login, or pass the profile you stored with--profile.- Login fails before a profile is stored: verify the OAuth client exists in Fleet
Manager, uses the expected client ID, supports authorization-code + PKCE, and
allows
http://127.0.0.1/callback. 401 Unauthorized: the token is missing, expired without a refresh token, or rejected by the API. Re-runloginand thenwhoami.403 Forbidden: the user or token is valid but does not have the required scope or Django permission. See Scopes & Permissions.- Command help does not show a new supported endpoint: regenerate the OpenAPI-derived
CLI metadata. If API code changed, run
make openapi. If onlydocs/openapi.yamlchanged, runmake api-cli. - Generated artifact drift in CI: run
make api-cli-checklocally to confirm whethersrc/fleet_manager/cli/commands/api/generated/operations.pyandsrc/fleet_manager/cli/commands/api/generated/fleetctl-api-agent-command-reference.mdmatchdocs/openapi.yaml.