Desktop Pricing Docs Blog About GitHub Get started

Quickstart

Get your first image hosted in 30 seconds. No signup form, no dashboard — just API calls. Prefer to try it in your browser first? Drop an image into the free image-to-URL tool.

1. Register an account

npx pixelvault-cli register

Response:

JSON
{
  "account": {
    "id": "acct_abc123",
    "email": "you@example.com"
  },
  "project": {
    "id": "proj_xyz789",
    "name": "Default"
  },
  "apiKey": "pv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
Save your API key — it's shown only once.

2. Upload an image

npx pixelvault-cli upload screenshot.png

Response:

JSON
{
  "id": "img_abc123",
  "url": "https://img.pixelvault.dev/proj_xyz789/img_abc123.png",
  "mime_type": "image/png",
  "size_bytes": 245000,
  "width": 1200,
  "height": 800
}

3. Use the URL

The CDN URL is live immediately. Use it in markdown, HTML, or anywhere you need an image.

![Screenshot](https://img.pixelvault.dev/proj_xyz789/img_abc123.png)

Authentication

All API requests (except registration) require a Bearer token:

Authorization: Bearer pv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

API keys use the prefix pv_live_ for production and pv_test_ for test environments. Keys are hashed server-side — we never store the raw key.


API Reference

Base URL: https://api.pixelvault.dev

All responses are JSON. Errors follow the format:

Error response
{
  "error": "error_code",
  "message": "Human-readable description"
}

POST /v1/auth/register

Create a new account. Returns an account, a default project, and an API key. The password is optional — omit it for a passwordless account (ideal for agents); the owner can set one later via the reset flow to enable dashboard login.

FieldTypeRequired
emailstringYes
passwordstring (8+ chars)No

POST /v1/images

Upload an image. Accepts multipart/form-data (a file) or, with an API key, application/json (a URL).

FieldTypeRequired
filebinaryYes*
folderstringNo

Supported formats: JPEG, PNG, GIF, WebP, AVIF, SVG.

Keyless quickstart: this endpoint works without an API key — no account needed for your first upload. Keyless uploads are temporary ("temporary": true, expire in 30 days); add an Authorization: Bearer key to make uploads permanent.

Upload from a URL (requires a key): send application/json with { "url": "https://…" } instead of a file. The image is fetched server-side (https only) and stored.


GET /v1/images

List images in your project. Paginated.

ParamTypeDefault
limitinteger50
offsetinteger0

GET /v1/images/:id

Get a single image's metadata by ID.


DELETE /v1/images/:id

Delete an image. Removes from storage and CDN.


Image transforms

Every CDN URL supports on-the-fly transforms via query params — no extra API call. The edge resizes, crops, and converts the image, then caches the result globally. Available on all plans.

https://img.pixelvault.dev/proj_xyz789/img_abc123.jpg?w=400&fit=cover&fmt=webp
ParamValuesNotes
sizes · m · l · socialNamed preset. s=256w, m=640w, l=1280w, social=1200×630 (OG card).
w, hpixelsWidth/height. Snapped up to a discrete set (16–4000) for cache efficiency.
fitscale-down · contain · cover · crop · padDefault scale-down never enlarges a smaller source; cover/crop/contain/pad fit the exact box and may upscale.
fmtwebp · avif · jpg · png · autoauto negotiates WebP/AVIF from the Accept header. Omit to keep the source format.
qauto · 60 · 75 · 85Output quality. Default auto.
segmentforegroundRemoves the background (AI cut-out) → transparent output. Forces PNG unless you set a solid background or request fmt=webp/avif.
backgroundhex · rgb()/rgba() · named colorFills behind a removed background (or the fit=pad area). Hex (%23ffaa00), rgb()/rgba(), or a common CSS color name (white, black, …).
gravityauto · face · left · right · top · bottom · XxYWhere to crop toward, with fit=cover/crop. face is face-aware.
zoom0.0–1.0Face-crop tightness — with gravity=face (which needs fit=cover/crop).
blur0–250Gaussian blur. Snapped to a discrete set. 0 = off.
sharpen0–10Sharpen strength. Snapped to a discrete set. 1 is a good default for downscaled images; 0 = off.
rotate90 · 180 · 270Rotate in 90° steps.
fliph · v · hvMirror horizontally, vertically, or both.
brightnessmultiplierSnapped to 0.5 · 0.75 · 1.25 · 1.5 · 2. 1 = no change.
contrastmultiplierSnapped to 0.5 · 0.75 · 1.25 · 1.5 · 2. 1 = no change.
saturationmultiplierSnapped to 0 · 0.5 · 1.5 · 2. 0 = grayscale; 1 = no change.
tileimage filenameWatermark. The filename of another raster image in the same project (png/jpg/webp/avif, e.g. img_logo.png, optionally folder-prefixed), tiled edge-to-edge at native size. Bake opacity into the source PNG. Must be your own image — not an external URL, not SVG. A missing filename is ignored.

Background removal isolates the subject and makes the background transparent:

.../img_abc123.jpg?segment=foreground                    # transparent PNG cut-out
.../img_abc123.jpg?segment=foreground&background=white   # subject on a white fill
.../img_abc123.jpg?w=400&h=400&fit=cover&gravity=face&segment=foreground   # portrait cut-out

Effects (blur, sharpen, rotate, flip, brightness, contrast, saturation) stack and combine with resize/crop:

.../img_abc123.jpg?blur=30                       # blurred
.../img_abc123.jpg?saturation=0                  # grayscale
.../img_abc123.jpg?rotate=90&flip=h              # rotated + mirrored
.../img_abc123.jpg?w=800&blur=30&saturation=0    # grayscale, blurred 800px thumbnail

Watermark tiles one of your own images over the base — upload the watermark once, then reference it by filename:

.../img_abc123.jpg?tile=img_logo.png             # your logo, tiled at native size
.../img_abc123.jpg?w=1200&tile=watermarks/brand.png   # resized + watermarked

Background removal, face-crop, effects, and watermark (segment, gravity, zoom, blur, sharpen, rotate, flip, brightness, contrast, saturation, tile) apply to your project images, not the anonymous playground. Invalid params are ignored — you get the original image back, never an error. SVG sources are served as-is (not transformed).


CLI

The pixelvault-cli package gives you one-liner uploads from any terminal. Designed for AI coding agents — URLs go to stdout, messages to stderr.

npm install -g pixelvault-cli

Or use directly with npx:

npx pixelvault-cli register          # Create account, stores API key
npx pixelvault-cli register --email you@example.com --passwordless  # Headless/agent signup, no password
npx pixelvault-cli upload photo.jpg  # Prints CDN URL to stdout
npx pixelvault-cli list              # One URL per line
npx pixelvault-cli get img_abc       # Print URL, or download with -o (and -t to transform)
npx pixelvault-cli delete img_abc    # Silent on success

For CI/CD and headless agent usage, set PIXELVAULT_API_KEY:

export PIXELVAULT_API_KEY=pv_live_xxx
npx pixelvault-cli upload screenshot.png

Source: github.com/pixelvault-dev/cli


Claude Code skill

PixelVault ships a Claude Code skill so your agent can upload images without leaving the conversation.

claude plugin add pixelvault-dev/skill

Once installed, four skills are available:

SkillDescription
/pixelvault-upload <file>Upload image(s), get CDN URLs
/pixelvault-setupInstall CLI and configure API key
/pixelvault-listList recent uploads
/pixelvault-transformResize, convert, remove backgrounds, add effects or a watermark

The upload skill can also be triggered automatically — when Claude sees "upload this screenshot" or needs to host an image, it invokes the skill without you typing the command.

The skill wraps the pixelvault-cli, so make sure it's installed first (or run /pixelvault-setup).

Source: github.com/pixelvault-dev/skill


Paste & host (browser widget)

Let your own users paste, drop, or select an image in a textarea and get a hosted CDN URL inserted automatically — the same flow as GitHub's markdown editor, on your site. It runs entirely in the browser with a publishable key, so there's no server code to write.

1. Create a publishable key

In your dashboard, open a project's Publishable keys section and add one with an allowlist of the origins it may be used from (for example https://app.example.com). Publishable keys (pv_pub_…) are safe to ship in browser code: they are upload-only and rejected from any origin that isn't on the allowlist.

A publishable key can only upload. It can't list, read, or delete images, and it only works from the origins you allow — so putting it in your page source is fine.

2a. Drop-in script tag

Zero build step. Add one tag; every field matching data-pv-target becomes paste-and-host:

<textarea data-pixelvault></textarea>
<button data-pv-pick="[data-pixelvault]">Upload image</button>
<script src="https://pixelvault.dev/paste.js"
        data-pv-key="pv_pub_xxxxxxxx"
        data-pv-target="[data-pixelvault]"></script>

Attributes on the tag: data-pv-key (required), data-pv-target (CSS selector; defaults to [data-pixelvault]), and optional data-pv-endpoint / data-pv-folder. Add a data-pv-pick attribute to any button (its value is the target field's selector) to open the file picker on click. The script also exposes a global window.PixelVaultPaste with attach, openFilePicker, and init for wiring elements added later.

2b. npm package

For bundled apps, install the framework-agnostic core:

npm install @pixelvault-dev/paste
import { attachPaste, openFilePicker } from "@pixelvault-dev/paste";

const field = document.querySelector("textarea");
const options = { publishableKey: "pv_pub_xxxxxxxx" };

attachPaste(field, options);                       // paste + drop
uploadButton.addEventListener("click", () => openFilePicker(field, options));

Or a framework binding:

// npm install @pixelvault-dev/paste-react
import { useRef } from "react";
import { usePaste } from "@pixelvault-dev/paste-react";

function Editor() {
  const ref = useRef(null);
  const { openFilePicker } = usePaste(ref, { publishableKey: "pv_pub_xxxxxxxx" });
  return (
    <>
      <textarea ref={ref} />
      <button onClick={openFilePicker}>Upload image</button>
    </>
  );
}
<!-- npm install @pixelvault-dev/paste-vue -->
<script setup>
  import { ref } from "vue";
  import { usePaste } from "@pixelvault-dev/paste-vue";

  const field = ref(null);
  const { openFilePicker } = usePaste(field, { publishableKey: "pv_pub_xxxxxxxx" });
</script>

<template>
  <textarea ref="field" />
  <button @click="openFilePicker">Upload image</button>
</template>

3. What the user sees

Pasting, dropping, or picking an image inserts an ![Uploading…]() placeholder at the caret, uploads the file, then swaps in ![name](https://img.pixelvault.dev/…). Override the inserted text (HTML, BBCode, a bare URL) with the render option, and hook onUploadStart, onUploadComplete, and onError for progress and error handling.


MCP server

PixelVault runs a remote Model Context Protocol server, so any MCP-capable agent (Claude, Cursor, and others) can host images directly. It's hosted on Cloudflare's edge at:

https://mcp.pixelvault.dev/mcp   (transport: streamable-http)

Four tools are exposed:

ToolDescription
upload_imageUpload an image (base64 data or a public source_url) → instant CDN URL
list_imagesList your images (paginated)
get_imageGet metadata + CDN URL for one image
delete_imageDelete one image

Authenticate by sending your API key as a Bearer token. Add it to Claude Code with:

claude mcp add --transport http pixelvault https://mcp.pixelvault.dev/mcp \
  --header "Authorization: Bearer pv_live_xxxxxxxx"

Or configure any client that supports the streamableHttp transport:

{
  "mcpServers": {
    "pixelvault": {
      "type": "streamable-http",
      "url": "https://mcp.pixelvault.dev/mcp",
      "headers": { "Authorization": "Bearer pv_live_xxxxxxxx" }
    }
  }
}

Agent discovery

PixelVault provides standard discovery endpoints for any AI agent:

  • /.well-known/api-catalog — API catalog for agent discovery
  • /llms.txt — LLM-readable service description (lists the MCP server)
  • /openapi.json — OpenAPI 3.1 specification
  • MCP serverhttps://mcp.pixelvault.dev/mcp