CLI — terminal-first Phaser
A Go binary distributed on npm. Browse the catalog, mint API keys, and upload tracks from your shell. Signs EIP-4361 challenges locally — byte-identical to viem.
Install
The npm postinstall pulls the prebuilt binary for your OS/arch. Skip with PHASER_CLI_SKIP_INSTALL=1.
npm (recommended)
$ npm i -g @jackmorgan/phaser-cli
Supported: darwin/arm64, darwin/amd64, linux/arm64, linux/amd64, windows/arm64, windows/amd64. Config at ~/.phaser/config.json.
Authentication
Two credential types. The CLI picks the right one per command automatically — you don't have to think about it.
Read-only, long-lived
Paste one from the web app or mint via keys create. Good for CI, scripts, and browsing the catalog.
catalog · albums get · healthWallet-signed, 1-hour
Run auth siwe — the CLI derives your address, fetches a challenge, signs it locally, and stores the JWT. Private key never leaves your machine.
keys · tracks · albums · artists initviem.signMessage. Pure Go, no cgo. Private key resolved via --private-key flag → --private-key-file → $PHASER_PRIVATE_KEY → interactive masked prompt.
Browse (read-only)
$ phaser catalog tracks --genre synthwave --sort newest --limit 10 $ phaser catalog track trk_abc123 $ phaser catalog search "velour static" $ phaser catalog genres $ phaser albums get alb_xyz
Add -o json on any command for machine-readable output. --cursor + --limit for pagination.
Artist flow
Sign in once, mint a key, init your artist profile, then upload forever.
Sign in with Ethereum
CLI derives your address, signs the EIP-4361 challenge locally, stores the JWT.
$ phaser auth siweCreate your profile
One artist per wallet. This is your public page at /a/<slug>.
Mint an API key
--save writes it to config so subsequent commands pick it up automatically.
Publish a track
Single command — multipart upload, cover art, pricing, publish — all at once.
$ phaser tracks upload song.mp3 --title "Neon" --price 0.05 --publishTrack uploads
Two paths depending on file size. Under ~100 MB: single multipart POST. Anything larger: presign → PUT to S3 → finalize.
$ phaser tracks upload song.mp3 \ --title "Track 1" \ --genre synthwave \ --price 0.05 \ --cover art.jpg \ --album-id <uuid> \ --track-number 1 \ --release-date 2026-04-20 \ --publish
$ phaser tracks presign \ --title "Track 2" \ --audio big.flac \ --cover cover.jpg \ --upload $ phaser tracks finalize --track-id <id> --publish
$ phaser tracks presign \ --title "Track 2" \ --audio-content-type audio/flac \ -o json # then PUT it yourself: $ curl -X PUT --data-binary @big.flac \ -H "Content-Type: audio/flac" \ "<upload_url>" $ phaser tracks finalize --track-id <id> \ --source-audio-key <key>
All commands
| Command | What it does |
|---|---|
phaser health | Ping the API |
phaser auth login / siwe / logout / status | Credentials |
phaser config show / path | Inspect config |
phaser catalog tracks / track / search / genres / artists | Browse |
phaser albums get / create / update | Albums |
phaser artists init | Create artist profile |
phaser keys list / create / revoke | API keys |
phaser tracks upload / presign / finalize / update / publish / delete | Tracks |
phaser storage balance / invoices | Credit ledger |
phaser analytics | Streams + revenue |
phaser completion <shell> | Shell completions (bash/zsh/fish) |
Upload progress
When stdout is a TTY, uploads print a live progress line to stderr. CI and piped output stay silent.
uploading 47.32% 47.32 MB / 100.00 MB 8.12 MB/s