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
Response:
"account": {
"id": "acct_abc123",
"email": "you@example.com"
},
"project": {
"id": "proj_xyz789",
"name": "Default"
},
"apiKey": "pv_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
}
2. Upload an image
Response:
"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.
 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": "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.
| Field | Type | Required |
|---|---|---|
| string | Yes | |
| password | string (8+ chars) | No |
POST /v1/images
Upload an image. Accepts multipart/form-data (a file) or, with an API key, application/json (a URL).
| Field | Type | Required |
|---|---|---|
| file | binary | Yes* |
| folder | string | No |
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.
| Param | Type | Default |
|---|---|---|
| limit | integer | 50 |
| offset | integer | 0 |
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 | Param | Values | Notes |
|---|---|---|
| size | s · m · l · social | Named preset. s=256w, m=640w, l=1280w, social=1200×630 (OG card). |
| w, h | pixels | Width/height. Snapped up to a discrete set (16–4000) for cache efficiency. |
| fit | scale-down · contain · cover · crop · pad | Default scale-down never enlarges a smaller source; cover/crop/contain/pad fit the exact box and may upscale. |
| fmt | webp · avif · jpg · png · auto | auto negotiates WebP/AVIF from the Accept header. Omit to keep the source format. |
| q | auto · 60 · 75 · 85 | Output quality. Default auto. |
| segment | foreground | Removes the background (AI cut-out) → transparent output. Forces PNG unless you set a solid background or request fmt=webp/avif. |
| background | hex · rgb()/rgba() · named color | Fills behind a removed background (or the fit=pad area). Hex (%23ffaa00), rgb()/rgba(), or a common CSS color name (white, black, …). |
| gravity | auto · face · left · right · top · bottom · XxY | Where to crop toward, with fit=cover/crop. face is face-aware. |
| zoom | 0.0–1.0 | Face-crop tightness — with gravity=face (which needs fit=cover/crop). |
| blur | 0–250 | Gaussian blur. Snapped to a discrete set. 0 = off. |
| sharpen | 0–10 | Sharpen strength. Snapped to a discrete set. 1 is a good default for downscaled images; 0 = off. |
| rotate | 90 · 180 · 270 | Rotate in 90° steps. |
| flip | h · v · hv | Mirror horizontally, vertically, or both. |
| brightness | multiplier | Snapped to 0.5 · 0.75 · 1.25 · 1.5 · 2. 1 = no change. |
| contrast | multiplier | Snapped to 0.5 · 0.75 · 1.25 · 1.5 · 2. 1 = no change. |
| saturation | multiplier | Snapped to 0 · 0.5 · 1.5 · 2. 0 = grayscale; 1 = no change. |
| tile | image filename | Watermark. 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:
| Skill | Description |
|---|---|
/pixelvault-upload <file> | Upload image(s), get CDN URLs |
/pixelvault-setup | Install CLI and configure API key |
/pixelvault-list | List recent uploads |
/pixelvault-transform | Resize, 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.
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 . 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:
| Tool | Description |
|---|---|
upload_image | Upload an image (base64 data or a public source_url) → instant CDN URL |
list_images | List your images (paginated) |
get_image | Get metadata + CDN URL for one image |
delete_image | Delete 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 server —
https://mcp.pixelvault.dev/mcp