OptiPic

REST API

Image Compression API Documentation

Compress, convert, and resize images programmatically. HTTPS REST API. Returns binary image data with savings metadata in response headers.

Base URL: https://api.opti.picturesVersion: v1

Authentication

All API requests require an API key passed in the Authorization header. Get your key from the dashboard.

http
Authorization: Bearer op_live_your_api_key_here

API keys are shown once at creation. Store them securely — you cannot retrieve a key after closing the creation dialog.

POST

/v1/compress

Compress an image and optionally convert its format. Returns the processed binary image.

Request

ParameterTypeDefaultDescription
filebinary (required)Image file. JPEG, PNG, WebP, AVIF, GIF, HEIC accepted.
formatstringsame as inputOutput format: jpeg, png, webp, avif
qualityinteger 1–10080Compression quality. Lower = smaller file.
strip_exifbooleantrueRemove EXIF metadata from the output.

Example

bash
curl -X POST https://api.opti.pictures/v1/compress \
  -H "Authorization: Bearer op_live_your_api_key" \
  -F "[email protected]" \
  -F "format=webp" \
  -F "quality=80" \
  -F "strip_exif=true" \
  -o photo.webp

Response

http
HTTP/2 200
Content-Type: image/webp
X-Original-Size: 234567
X-Compressed-Size: 89123
X-Savings-Percent: 62.0
X-Request-Id: req_01abc123def456

Response body is the compressed binary image.

POST

/v1/convert

Convert an image from one format to another.

ParameterTypeDescription
filebinary (required)Source image.
tostring (required)Target format: jpeg, png, webp, avif
bash
curl -X POST https://api.opti.pictures/v1/convert \
  -H "Authorization: Bearer op_live_your_api_key" \
  -F "[email protected]" \
  -F "to=avif" \
  -o photo.avif
POST

/v1/resize

Resize an image. Aspect ratio is preserved unless both width and height are specified.

ParameterTypeDescription
filebinary (required)Source image.
widthintegerTarget width in pixels. Omit to scale by height only.
heightintegerTarget height in pixels. Omit to scale by width only.
formatstringOutput format. Defaults to same as input.
bash
curl -X POST https://api.opti.pictures/v1/resize \
  -H "Authorization: Bearer op_live_your_api_key" \
  -F "[email protected]" \
  -F "width=1280" \
  -F "format=webp" \
  -o photo-resized.webp
GET

/v1/usage

Returns current-month usage statistics for the authenticated API key.

bash
curl https://api.opti.pictures/v1/usage \
  -H "Authorization: Bearer op_live_your_api_key"

Response

json
{
  "period": "2026-06",
  "requests": 312,
  "limit": 500,
  "remaining": 188,
  "overage_requests": 0,
  "overage_cost_usd": 0,
  "reset_at": "2026-07-01T00:00:00.000Z"
}

Error codes

HTTP statusError codeDescription
401invalid_api_keyMissing or invalid API key.
400invalid_content_typeRequest must use multipart/form-data.
400missing_fileNo "file" field in multipart body.
400missing_dimensionsResize requires width or height.
413file_too_largeFile exceeds 20 MB limit.
429rate_limit_exceededMonthly request limit reached.
500processing_errorImage could not be processed.
json
{
  "error": "rate_limit_exceeded",
  "message": "Monthly request limit reached. Upgrade to Pay-as-you-go at opti.pictures/pricing",
  "limit": 500,
  "reset_at": "2026-07-01T00:00:00.000Z"
}

Rate limits

TierMonthly limitPrice
Free500 requests$0 (no card required)
Pay-as-you-go501 – 10,000$0.009 / request
Pay-as-you-go (volume)10,001+$0.002 / request

Limits reset on the first day of each calendar month (UTC). View full pricing details.

Code examples

Node.js

javascript
import fs from 'fs/promises'
import fetch from 'node-fetch'
import FormData from 'form-data'

const API_KEY = process.env.OPTIPIC_API_KEY

async function compressImage(inputPath, outputPath) {
  const form = new FormData()
  form.append('file', await fs.readFile(inputPath), 'photo.jpg')
  form.append('format', 'webp')
  form.append('quality', '80')

  const res = await fetch('https://api.opti.pictures/v1/compress', {
    method: 'POST',
    headers: { Authorization: `Bearer ${API_KEY}`, ...form.getHeaders() },
    body: form,
  })

  if (!res.ok) {
    const err = await res.json()
    throw new Error(err.error)
  }

  console.log('Original:', res.headers.get('X-Original-Size'), 'bytes')
  console.log('Compressed:', res.headers.get('X-Compressed-Size'), 'bytes')
  console.log('Saved:', res.headers.get('X-Savings-Percent') + '%')

  await fs.writeFile(outputPath, Buffer.from(await res.arrayBuffer()))
}

await compressImage('photo.jpg', 'photo.webp')

Python

python
import os
import requests

API_KEY = os.environ["OPTIPIC_API_KEY"]

def compress_image(input_path: str, output_path: str):
    with open(input_path, "rb") as f:
        res = requests.post(
            "https://api.opti.pictures/v1/compress",
            headers={"Authorization": f"Bearer {API_KEY}"},
            files={"file": f},
            data={"format": "webp", "quality": "80"},
        )

    res.raise_for_status()

    print(f"Original: {res.headers['X-Original-Size']} bytes")
    print(f"Compressed: {res.headers['X-Compressed-Size']} bytes")
    print(f"Saved: {res.headers['X-Savings-Percent']}%")

    with open(output_path, "wb") as out:
        out.write(res.content)

compress_image("photo.jpg", "photo.webp")

Changelog

v1.0.0 — June 2026

  • Initial release: /v1/compress, /v1/convert, /v1/resize, /v1/usage
  • API key authentication via Bearer token
  • KV-backed usage tracking and rate limiting