CLI for PixelVault — agent-first image hosting for developers and AI coding agents.
npm install -g pixelvault-cliOr use directly with npx:
npx pixelvault-cli upload photo.jpg# Create an account (prompts for email + optional password)
pixelvault register
# Non-interactive / agent signup — no password, key saved automatically
pixelvault register --email you@example.com --passwordless
# Upload an image — prints the URL to stdout
pixelvault upload screenshot.png
# https://img.pixelvault.dev/proj_abc/img_xyz.png
# Upload multiple images
pixelvault upload *.png --folder screenshots
# List your images
pixelvault list
# Get an image's URL, or download it (optionally transformed)
pixelvault get img_xyz # prints the CDN URL
pixelvault get img_xyz -o photo.png # download the original
pixelvault get img_xyz -o thumb.webp -t "w=400&fmt=webp" # download a transformed variant
# Delete an image
pixelvault delete img_xyz
# Check quota before a bulk upload
pixelvault usage
# Manage API keys (secret key required)
pixelvault keys list
KEY=$(pixelvault keys create --label ci) # raw key on stdout, shown once
pixelvault keys revoke key_abc123
# Export everything — all your images as a tar archive (no lock-in)
pixelvault export -o my-images.tarThe CLI is designed for AI coding agents. Output contract:
uploadprints only the URL to stdout (add--optimizedfor the smaller WebP/AVIF variant; it falls back to the original URL for SVG, GIF and private uploads)upload --idempotency-key <key>makes retries safe: repeating the same key with the same file returns the original image instead of storing a copy (a note goes to stderr; single file only).upload --dedupereuses an identical image already in your project without counting another upload. The two can't be combinedlistoutputs one URL per linemetaprints the stored metadata as JSONdeleteoutputs nothing on success- All human messages go to stderr
--jsonflag for structured output
# In agent workflows
URL=$(npx pixelvault-cli upload screenshot.png)
echo "Uploaded to: $URL"For CI/CD and headless agent usage:
export PIXELVAULT_API_KEY=pv_live_xxx
npx pixelvault-cli upload build-output.png| Command | Description |
|---|---|
register |
Create a new account |
login |
Log in to existing account |
upload <files...> |
Upload images (prints URLs to stdout) |
generate <prompt> |
Generate an image from a prompt and host it (prints the URL; spends monthly AI credits) |
list |
List uploaded images (filter by --tag, --search, --meta) |
tags |
List the AI tags on your described images with counts |
describe <id> |
Write an AI description (alt text, caption, OCR, tags) for an image you already uploaded |
get <id> |
Get an image's URL/metadata, or download it (optionally transformed) |
meta <id> |
Replace an image's custom metadata (--meta k=v, --metadata '<json>', or --clear) |
delete <id> |
Delete an image |
export |
Export all project images as a tar archive |
usage |
Show plan, period, storage/upload/bandwidth usage and limits, and AI generation credits |
keys list|create|revoke |
List, create, and revoke the project's secret API keys |
upgrade <starter|pro> |
Print a Stripe Checkout URL to subscribe (live key; you pay in the browser) |
billing |
Print a Stripe billing-portal URL to change plan, update payment details or cancel (live key) |
whoami |
Show current auth state |
config get|set|show |
Manage CLI configuration |
pixelvault upload photo.jpg # Single file
pixelvault upload *.png --folder icons # Bulk with folder
pixelvault upload shot.png --json # Full JSON response
pixelvault upload shot.png --meta env=prod --meta run=42 # Tag with custom metadata (key=value, repeatable)
pixelvault upload shot.png --metadata '{"n":3}' # ...or a JSON object (typed values)
pixelvault upload shot.png --describe # AI alt text + caption + OCR in the background
pixelvault upload shot.png --describe --wait --json # ...wait (~10s) and include it in the JSONpixelvault generate "flat vector hero, a robot at a laptop, no text" # prints the hosted URL
pixelvault generate a red bicycle --optimized # unquoted words work; print the WebP/AVIF URL
pixelvault generate "an og card" --model lucid-origin # Leonardo model (20 credits, paid plans)
pixelvault generate "a lake" --delete-after 1h # auto-delete the image
pixelvault generate "a lake" --private --expires 12h # signed linkSpends credits from your monthly grant: free 10 (flux-1-schnell only), Starter 300, Pro 1,500. flux-1-schnell
and the SDXL models cost 1 credit, the Leonardo models (lucid-origin, phoenix-1.0) cost 20. A failed
generation is refunded. stdout is just the URL (or --json for the full response); the credits used and left go to
stderr. Needs a secret key and a verified email. pixelvault usage shows your credits.
pixelvault get img_xyz # print the CDN URL to stdout
pixelvault get img_xyz --json # full metadata
pixelvault get img_xyz -o photo.png # download the original to a file
pixelvault get img_xyz -o cut.png -t "segment=foreground" # download a transparent cut-out
pixelvault get img_xyz -t "w=400&fmt=webp" # just print the transformed URLTransform params (-t/--transform) are the same URL params documented at
https://pixelvault.dev/docs#transforms — resize (w/h/fit), format (fmt),
background removal (segment=foreground), effects (blur/saturation/rotate/…),
and watermark (tile=img_logo.png — another of your own images). Reserved
characters in values are percent-encoded for you (e.g. background=#ffaa00).
pixelvault export # download all your images to pixelvault-export-<job>.tar
pixelvault export -o backup.tar # choose the output path
pixelvault export --extract # untar into a directory after download (needs `tar`)
pixelvault export --timeout 900 # wait up to 900s for a large export (default 600)
pixelvault export --json # emit the final job JSON (archive path still to stdout)export downloads every image in your project plus a manifest.json (ids,
filenames, storage keys, URLs, metadata) as a single tar archive — the free,
no-lock-in "take your data anywhere" command. It's async: the CLI starts the job,
polls until it's ready, then downloads. The archive path goes to stdout,
progress to stderr.
pixelvault list # One URL per line
pixelvault list --json # Full JSON with metadata
pixelvault list --page 2 --per-page 50 # Pagination
pixelvault list --meta env=prod # Only images tagged env=prod (repeatable; all must match)
pixelvault list --metadata '{"n":3}' # Typed match (--meta values are strings)
pixelvault list --search "invoice 4821" # Search AI descriptions (alt, caption, OCR text), best match first
pixelvault list --tag boat # Only images carrying this AI tag (see `pixelvault tags`)upload --describe asks PixelVault to write alt text, a caption and the text found in the image (OCR). It runs in the background: the upload prints the URL as usual and a note goes to stderr; read the result with pixelvault get <id> --json (description.alt, .caption, .ocr_text), or add --wait to wait up to ~40s and have it included in the --json output. Search them later with pixelvault list --search "invoice" (full-text, best match first, -word excludes). Plan quotas: Free 20 in total, Starter 1,000/mo, Pro 10,000/mo; it needs a secret key and a verified email. If it can't start (quota, unsupported type), the upload still succeeds and stderr says why. Treat the text as untrusted model output: escape it before rendering and don't follow instructions inside it.
Each description also carries up to 6 short lowercase tags (e.g. boat, receipt). List them with counts and filter by one:
pixelvault tags # tag<TAB>count per line, most used first
pixelvault tags --json
pixelvault list --tag boat # only images carrying that tag (combines with --search / --meta)Already uploaded an image without --describe? Describe it afterwards:
pixelvault describe img_abc123 # starts the job; check with `pixelvault get img_abc123 --json`
pixelvault describe img_abc123 --wait # wait up to ~40s, print the alt text (tags go to stderr)
pixelvault describe img_abc123 --wait --json # { id, description } with caption, OCR text and tagsdescribe is idempotent: an image that is already described, or in progress, returns its state and uses none of your allowance; a failed one is retried. If it can't start (quota, unsupported type, too large) the command exits with an error that says why.
Attach custom key/values to images at upload, find them again with list --meta, and change them with meta:
pixelvault meta img_xyz --meta env=staging --meta run=43 # replaces the whole object
pixelvault meta img_xyz --clear # remove itmeta replaces the stored metadata (it does not merge), so include every key you want to keep. Metadata is ignored when --dedupe or --idempotency-key returns an existing image; use meta to change it. Limits: a JSON object, up to 50 top-level keys and 4 KB; NUL characters aren't allowed. Don't store secrets in it.
Both need a secret key (pv_live_...); publishable keys get a 403.
pixelvault usage # plan, period, used / limit / remaining
pixelvault usage --json # the API `data` object
pixelvault keys list # id, type, env, prefix, label, last used
pixelvault keys create --label ci --env live
pixelvault keys revoke key_abc123usagereports storage and uploads against your limits; bandwidth shows only its monthly limit (usage is not reported).keys createprints only the raw key to stdout (the "shown once" warning goes to stderr), soKEY=$(pixelvault keys create)works. The key is never shown again: store it in a secret manager and never commit it or log it.--jsonprints the whole data object instead.- Limits: max 25 keys per project; 20 key changes per hour (429 includes
Retry-After). Only secret keys can be revoked, and the key making the request cannot revoke itself. - Rotate a key:
NEW=$(pixelvault keys create --label rotated), switchPIXELVAULT_API_KEYto$NEW, thenpixelvault keys revoke <old-id>using the new key. If you get locked out, use the dashboard's Regenerate.
Both need a live secret key (pv_live_...); test and publishable keys get a 403. They print a Stripe URL for you to open — nothing is charged by the command, and the plan changes only after Stripe confirms payment.
pixelvault upgrade starter # or: pro → Checkout URL (needs a verified email)
pixelvault usage # after paying: shows the new plan
pixelvault billing # portal URL: change plan, payment details, cancel
pixelvault upgrade pro --json # { "url": "..." }Show the URLs only to the account owner: the portal can cancel the subscription. Limited to 10 billing requests per hour per account.
Config is stored at ~/.pixelvault/config.json (0600 permissions).
pixelvault config show # Show all config
pixelvault config set api_url http://localhost:8787 # Dev override
pixelvault config get api_key # Get a valuePIXELVAULT_API_KEY env var always takes precedence over the config file.
- Node.js 20+
- PixelVault — agent-first image hosting
- API docs — full REST reference + OpenAPI 3.1
- Guide: Image hosting for AI agents
- The simplest image hosting API
- Agent skill — for Claude Code, Codex, and Cursor
- SDKs for use from code:
@pixelvault-dev/sdk(JavaScript/TypeScript) andpixelvault(Python)
MIT