Developer docs

MiniPic offers two API layers: a compatibility layer (with authentication and response structure compatible with popular compression APIs — integrate by just swapping the endpoint and key) and a native layer (/v1/*, synchronous compression and usage queries). You pay only for successful compressions, the first 500 each month are free, every response carries usage headers, and your bill is reconcilable line by line.

Stability promise: breaking changes to /shrink and /v1 are announced 90 days in advance.

Quickstart

Compress your first image in 30 seconds: create an API key in the console, then send a request.

# Compress a PNG (Basic auth, username fixed to api) curl -s --user api:YOUR_API_KEY \ --data-binary @input.png \ -o output.png \ https://api.minipic.ai/v1/compress

The result is returned over an encrypted private link only you, the key holder, can access — images are used only for this compression, encrypted throughout, never leaked, and never used for training or any other purpose.

Authentication

  • HTTP Basic (compatible with popular compression APIs): username fixed to api, password is your API key — Authorization: Basic base64("api:KEY")
  • Bearer (recommended for the native layer): Authorization: Bearer KEY

Key prefixes are mp_live_ (production) and mp_test_ (sandbox); the server stores only a hash of the key, and the full key is shown only once at creation. Each account can hold up to 5 keys. Authentication failures always return 401 without distinguishing the cause (to prevent enumeration).

POST /shrink Compress an image

The request body is one of two options: a raw binary image (PNG / JPEG / WebP / HEIC / GIF / BMP / TIFF / AVIF), or JSON specifying a source URL (public http/https addresses only, 10-second fetch timeout). When no output format is specified, the original format is kept: PNG / JPEG / WebP / GIF / TIFF / AVIF are output in their original format (AVIF→AVIF, TIFF→TIFF); HEIC is converted to JPEG; BMP, which cannot be compressed in its own format, is converted to PNG. GIF is losslessly optimized by default (stays GIF), and can also be converted to WebP to save more.

# Option 1: upload binary directly curl -s --user api:YOUR_API_KEY \ --data-binary @input.png \ https://api.minipic.ai/shrink
# Option 2: let the server fetch a URL curl -s --user api:YOUR_API_KEY \ -H "Content-Type: application/json" \ -d '{"source": {"url": "https://example.com/input.png"}}' \ https://api.minipic.ai/shrink

On success it returns 201 Created, with response headers including Location (the result address) and Compression-Count (images billed this month):

{ "input": { "size": 207565, "type": "image/png" }, "output": { "size": 63274, "type": "image/png", "width": 1280, "height": 720, "ratio": 0.3049, "url": "https://api.minipic.ai/output/{id}" } }

GET /output/{id} Download the result

Requires authentication; returns the compressed result binary. Results are served over an encrypted private link; once the link expires it returns 404 OutputExpired, and you can recompress to obtain it again. Re-downloading the same result is not billed.

POST /output/{id} Derived operations

Run resize / convert / preserve on a compressed result; each derived output counts as 1 image:

# Scale proportionally to 800px wide and convert to WebP curl -s --user api:YOUR_API_KEY \ -H "Content-Type: application/json" \ -d '{"resize": {"method": "scale", "width": 800}, "convert": {"type": "image/webp"}}' \ -o thumb.webp \ https://api.minipic.ai/output/{id}
  • resize.method: scale (single-side proportional) / fit (fit entirely) / cover (crop to fill, currently center crop)
  • convert.type: convert between image/webp, image/png and image/jpeg
  • preserve: keep copyright / creation / location metadata
Current limits (read before integrating): thumb smart thumbnails are not yet available (returns 501 NotImplemented); cover is a center crop (smart subject detection is planned); AVIF output is not supported; direct store upload to S3/GCS is not supported (direct upload to object storage is planned).

POST /v1/compress Synchronous compression (native layer)

A single request returns the compressed result binary directly, saving a round trip — handy for CI:

# Quality preset and output format are set via query parameters curl -s -H "Authorization: Bearer YOUR_API_KEY" \ --data-binary @input.jpg \ -o output.jpg \ "https://api.minipic.ai/v1/compress?quality=smart&format=keep"
  • quality: smart (default) / high / extreme / 1-100
  • format: keep (keep original format) / webp
  • Response headers: X-Input-Size / X-Output-Size / X-Ratio / Compression-Count

GET /v1/usage Usage query

Returns this month's count, remaining free quota and remaining credit-pack balance — identical to the console:

{ "month": "2026-06", "compressed": 1234, "free_quota": { "total": 500, "used": 500 }, "bundles": [ { "id": "...", "total": 10000, "remaining": 5210 } ], "pay_as_you_go": { "count": 734, "estimated_amount_cny": "36.70" }, "rate_limit": { "rps": 10, "burst": 20 } }

Quotas and rate limits

  • Rate: 10 req/s per key, burst 20 (token bucket); exceeding it returns 429 + Retry-After
  • Concurrency: in-progress tasks per key <= 20
  • Free monthly quota: 500 images/month/account; once used up with no payment on file it returns 429 AccountLimitReached
  • Per file: 5 MB free; 80 MB paid; customizable for enterprise
  • Pixels: <= 100 megapixels; exceeding it returns 422 ImageTooComplex

Response headers on all metered endpoints: Compression-Count, X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset.

Billing

  • POST /shrink success (201): counts as 1 image
  • POST /v1/compress success (200): counts as 1 image
  • GET /output/{id} re-download: not billed
  • POST /output/{id} derived operation success: counts as 1 image each time
  • 4xx / 5xx, content screening blocks, and URL fetch failures: not billed; on a successful retry only the successful call counts

Deduction order: monthly plan quota → credit packs (first purchased, first used, never expire). Prepaid, with no usage-based monthly invoice — once the quota runs out it pauses, and buying a credit pack restores it.

AI / Skill integration

MiniPic offers an official Agent Skill (minipic-compress): once installed, tell any AI agent that supports the Anthropic Agent Skills open standard (Claude Code / Cursor / Codex CLI / Copilot CLI, etc.) something like "compress the images in this folder" and it will automatically call the MiniPic API to compress, convert to WebP, batch-process and report the compression ratio — no need to hand-write curl or retry logic.

Install

Choose one of the following (three options):

# Option 1: via skills.sh (npx, recommended) npx skills add minipic/minipic-skill
# Option 2: via gh skill gh skill install minipic/minipic-skill
# Option 3: drop into the skills directory manually (Claude Code user / project level) cp -r minipic-compress ~/.claude/skills/ # Or project level: cp -r minipic-compress <your-project>/.claude/skills/

For other agents that support the Agent Skills standard (Cursor / Codex CLI / Copilot CLI, etc.), follow their docs to place the minipic-compress/ directory in the corresponding skills path.

Configure your API key

The key is read only from an environment variable and is never hard-coded or echoed. After creating a key in the console, set it in your environment:

# Required: your API key (500 free images/month/account) export MINIPIC_API_KEY=mp_live_your_key # Optional: override the API base URL (default https://api.minipic.ai) # export MINIPIC_API_BASE=https://api.minipic.ai

Scope and trigger examples

The Skill triggers automatically when you express intents like:

  • "Compress this image / the images in this folder"
  • "Convert hero.png to WebP and make it as small as possible"
  • "These images are too big — batch-optimize them before packaging and tell me how much I saved"

Capabilities: single file / folder batch / remote URL compression, conversion between PNG·JPEG·WebP·GIF, quality preset (smart / high / extreme) selection, automatic computation and reporting of savings percentage, and automatic back-off retry on 429 rate limiting.

VS Code extension

The official MiniPic Image Compression extension lets you compress workspace images directly in your editor, with no hand-written curl, powered by the MiniPic in-house engine. It supports PNG / JPEG / WebP / GIF / AVIF / TIFF and can convert format while compressing (such as to WebP / AVIF to save more), and works in VS Code, Cursor and other compatible editors.

Install

Choose one of the following:

  • In the VS Code Extensions panel (⇧⌘X) search for MiniPic and click Install;
  • or run ext install minipic.minipic-vscode from the command palette;
  • or visit the Visual Studio Marketplace extension page and click Install.

Configure your API key

After creating a key (starting with mp_live_) in the console, run MiniPic: Set API Key from the command palette (⇧⌘P) and paste it. The key is stored securely in VS Code SecretStorage and is never written to plain-text config or synced via settings.json.

How to use

  • Right-click to compress: select images or folders in the Explorer (single, multi-select, or whole directory recursively) → right-click MiniPic: Compress Images to compress in place using the current quality and format settings.
  • Convert to WebP and update references: right-click MiniPic: Convert to WebP and Update References to convert to WebP while automatically updating references to that image across your workspace.
  • Auto-compress: when enabled, watches for new/changed workspace images and compresses them automatically (off by default, as it consumes quota); toggle from the status bar or with MiniPic: Toggle Auto-Compress.
  • View usage: run MiniPic: View Usage to see this month's compressed count, free balance and usage estimate — identical to the console.

Common settings

SettingDefaultDescription
minipic.qualitysmartQuality preset: smart / high / extreme / lossless
minipic.formatkeepOutput format: keep / png / jpeg / webp / gif / avif / tiff
minipic.skipIfLargertrueSkip and don't overwrite the original when same-format compression makes it larger
minipic.keepOriginalOnConverttrueKeep the original file when converting format
minipic.maxFileSizeMB80Skip files larger than this size to avoid triggering 413
minipic.baseUrlhttps://api.minipic.aiAPI service address; change it to your own gateway for self-hosted deployments
The extension is billed against the same image compression API — a successful compression counts as 1 image and enjoys the same monthly free quota; usage is identical to the console. Source on GitHub.

Error codes

The error body follows the convention of popular compression APIs: {"error": "code", "message": "human-readable description"}; fields are only added, never removed.

HTTPerrorTriggerDescription
400BadRequestEmpty body, invalid JSON, or out-of-range parametersSomething was off with this request, so the image was not compressed. Try again, and contact [email protected] if it keeps happening.
400InputMissingRequest body has no image contentThis file is empty, so there is nothing to compress. Check the file and upload it again.
401UnauthorizedMissing, invalid, or disabled keyThis API key is invalid or disabled. Double-check the key, or create a new one in the console.
403AccountSuspendedAccount banned or overdueThis account has been suspended. Contact [email protected] if you think this is a mistake.
404NotFoundWrong pathWe could not find what you requested. Check that the link is correct.
404OutputExpiredResult private link has expiredThis private result link has expired and can no longer be opened. Upload the image again to recompress it.
413PayloadTooLargeExceeds the plan's per-file size limitThis image is over the 5 MB per-file limit on the free plan. Upgrade to Pro to compress files up to 80 MB.
415UnsupportedMediaTypeInput is not a supported image formatThis format is not supported yet. We currently support PNG, JPEG, WebP, HEIC, GIF, BMP, TIFF and AVIF.
422DecodeErrorCorrupt file or spoofed extensionWe could not decode this image: the file may be corrupted or not a valid image. Check it and upload again.
422ImageTooComplexExceeds the 100-megapixel limitThis image is over the 100-megapixel processing limit. Resize it smaller and try again.
422ContentBlockedBlocked by content safety screening (not billed)This image did not pass our content safety check. It was blocked and permanently deleted, and was not counted against your usage. If you believe this is a mistake, contact [email protected].
429TooManyRequestsRate or concurrency limit exceeded (with Retry-After)Too many requests right now, so this image could not be queued. Wait a moment and try again.
429AccountLimitReachedFree quota used up and no payment on file (with upgrade_url)You have used up today's free quota. Sign in to remove the daily limit (1,000 images per month); Pro raises the per-file limit to 80 MB.
500InternalServerErrorService error (with request_id)Something went wrong on our side and this image was not compressed. Please try again shortly.
501NotImplementedCapability not yet available (such as resize thumb)This feature is not available yet. Watch the developer docs for updates.
503ServiceUnavailableOverloaded or under maintenance (with Retry-After)The service is busy and this image was not compressed. Please try again shortly.