pixi-pfx CLIDrive prefix.dev from the command line. pixi-pfx wraps the GraphQL API as a pixi plugin, with tables for humans and a JSON envelope for scripts and agents.
pixi-pfx is a command-line client for the prefix.dev GraphQL API. It ships as a pixi plugin, so once installed it is available both as pixi-pfx and as pixi pfx. You can manage channels, packages and API keys from a terminal or from CI, and every command can emit a machine-readable JSON envelope.
Source and issue tracker
pixi-pfx is open source at github.com/prefix-dev/pixi-pfx. Please file bug reports and feature requests there. The release binaries are built in that repository as well.
The client is written in Rust and checks every query against the prefix.dev schema at compile time with cynic, so a renamed or removed field breaks the build rather than failing at runtime.
Install
pixi-pfx is packaged on conda-forge for linux-64, linux-aarch64, osx-64, osx-arm64 and win-64. Install it as a global tool:
Every push to main also publishes a development build to the pixi-extensions channel on beta.prefix.dev, if you want the latest changes before they are released:
To build from source instead:
Authenticate
pixi-pfx reads rattler's authentication storage, the same credentials that pixi auth login and rattler auth login write. If you are already logged in to prefix.dev there is nothing to set up. OAuth access tokens are refreshed automatically:
To use a specific API key instead, for example in CI, pass --token or set PREFIX_DEV_API_TOKEN. An explicit token always takes precedence over stored credentials:
Read-only queries against public channels need no credentials. To see which credential source would be used without printing any secret, run pixi-pfx auth status. See API and API keys for how tokens work, or create one with the CLI as shown below.
Output: tables or JSON
By default commands print a key/value block for a single object and a table for a list. Long cells are truncated to keep the table narrow, and paginated commands print a Page x/y (n total) footer.
Add --json for a stable JSON envelope that scripts and agents can consume. Field names inside data are snake_case, and details is only present for GraphQL errors.
Successful commands exit 0 and failures exit 1; in table mode the error goes to stderr as error [CODE]: message. The error codes are stable strings:
HTTP_ERROR: the request to the endpoint failed.
GRAPHQL_ERROR: the API returned GraphQL errors, or the response could not be decoded.
AUTH_STORAGE_ERROR: rattler's credential storage could not be opened or refreshed.
INVALID_ARGUMENT: an argument was malformed, for example invalid JSON in --entries.
JSON_ERROR: serializing or deserializing JSON failed.
Global options
These three options are global and can appear anywhere on the command line:
--json: emit the JSON envelope instead of tables.
--token <TOKEN>: API token to authenticate with. Also read from PREFIX_DEV_API_TOKEN. Defaults to rattler's auth storage.
--endpoint <URL>: GraphQL endpoint, https://prefix.dev/api/graphql by default. Point it at https://beta.prefix.dev/api/graphql to use beta.
Channels
Find and inspect
channel list is paginated with --limit (default 25) and --page (0-indexed). --order-by accepts name, size, created-at, package-count, namespace and billing-owner, combined with --direction asc|desc. Note that --search orders results by name similarity rather than filtering them, so the reported total stays the same.
Create, update, delete
On create, --public is a flag; on update it takes an explicit true/false, so visibility can be turned off again. Both commands also accept --logo <URL>, the CEP-0042 relations --relation-base and --relation-overrides, and --allow-v3-uploads true|false for packages that need v3 repodata. The same settings are described in Create and configure a channel.
Members and trusted publishers
The GitHub and GitLab publishers take an optional --environment; the Google publisher takes an optional --sub constraint. All three accept --access-mode (all, read, read-write or read-write-delete), and channel get lists publishers with their ids and access modes. See Publish packages and Manage channel access.
Notices
CEP-6 notices are shown on the channel page and served to compatible conda clients:
The argument after the channel is the stable notice id. --level is info (default), warning or critical, and --expires-at takes an RFC 3339 timestamp. See Channel notices for where notices are displayed.
Packages
package list orders by name, last-created-date or total-size; search, list and versions all take --limit and --page.
Yank and delete
Yanking keeps the file but hides it from solvers; batch-delete removes variants permanently. batch-yank also takes --also-hide to hide the variants from package listings as well. See Manage package and channel lifecycle for what each state means.
Copy packages into a channel
Copying is a beta-only feature for now, so these commands need --endpoint https://beta.prefix.dev/api/graphql. Copying between channels resolves every matching source variant and submits it to an asynchronous copy job:
Packages can also be pulled from arbitrary URLs. Each entry pins a url together with its expected sha256, so the copy either reproduces exactly that file or fails:
Follow a job by id, or inspect any active background job for a channel. With --wait the command reports changed status and counts on stderr and prints the final per-item results:
API keys
The key value is only shown once, on creation, so store it right away. --channel scopes a key to one channel and requires --access-mode. Revoking disables the key but keeps the record; deleting removes it entirely.
Scripts and agents
describe prints the command tree (subcommands, arguments, types and help text) as JSON, so a script or an agent can discover the available commands without parsing --help. It always emits JSON, with or without --json:
Together with --json, a script can discover the commands, run one and read the result from the envelope.
Next steps
GraphQL API: the API behind every command, with an interactive explorer.
pixi global install -c https://beta.prefix.dev/pixi-extensions pixi-pfx
# from gitpixi global install --git https://github.com/prefix-dev/pixi-pfx.git# from a local checkoutpixi global install --path .# plain cargo, the binary lands in target/release/pixi-pfxcargo build --release
$ pixi-pfx package search numpy --limit 3NAME CHANNEL VERSION PLATFORMS SUMMARYnumpy conda-forge 2.5.2 linux-64, linux-aarch64, linu… The fundamental package for scientific …numpy emscripten-forge-dev 2.4.4 emscripten-wasm32 The fundamental package for scientific …numpy emscripten-forge-3x 2.4.4 emscripten-wasm32 The fundamental package for scientific …Page 1/1 (3 total)
# details for one channel (public channels need no auth)pixi-pfx channel get conda-forge# list channelspixi-pfx channel list --limit 10pixi-pfx channel list --owner myuser --order-by size --direction descpixi-pfx channel list --search conda --limit 5
# roles: owner, contributor, viewerpixi-pfx channel add-member my-channel someuser contributorpixi-pfx channel remove-member my-channel someuser# OIDC publishers, for keyless uploads from CIpixi-pfx channel add-github-oidc my-channel --owner org --repo repo --workflow build.ymlpixi-pfx channel add-gitlab-oidc my-channel --namespace group --project proj --workflow .gitlab-ci.ymlpixi-pfx channel add-google-oidc my-channel --email sa@project.iam.gserviceaccount.compixi-pfx channel delete-oidc my-channel <publisher-id># hand the channel to someone elsepixi-pfx channel transfer my-channel new-owner
pixi-pfx channel add-notice my-channel maintenance "Maintenance starts at 20:00 UTC" \ --level warning --expires-at 2026-08-20T22:00:00Zpixi-pfx channel update-notice my-channel maintenance "Maintenance moved to 21:00 UTC" --level warningpixi-pfx channel delete-notice my-channel maintenance
# search by name, ordered by similaritypixi-pfx package search numpy --limit 10# package details, including variantspixi-pfx package get conda-forge numpy --variants-limit 5# list with a name filterpixi-pfx package list --name-contains scipy --order-by name# resolve a matchspec (--channel is required and may be repeated)pixi-pfx package matchspec "numpy>=2.0" --channel conda-forge# a single variant, and all versions of a packagepixi-pfx package variant conda-forge numpy linux-64 numpy-2.0.0-py312h1234.condapixi-pfx package versions conda-forge numpy --limit 10