API Documentation

This page documents the ImgSmaller API for programmatic image compression. Use your personal API key from the Dashboard. Examples below use a dummy key for demonstration:

Overview

  • Base URL: https://imgsmaller.com
  • Auth: Send your key in X-API-Key header or ?api_key=... query.
  • Anonymous usage limits: Subject to a small daily cap; exceeding returns HTTP 429.
  • Authenticated usage limits: No daily cap. Your monthly allowance is based on your plan. See GET /api/v1/plan.
  • Endpoints: GET /api/v1/info, POST /api/v1/compress, GET /api/v1/plans, GET /api/v1/plan, GET /api/v1/allowed-domains, POST /api/v1/allowed-domains

Authentication

Provide your API key via header or query parameter:

# Header
curl -H 'X-API-Key: demo_api_key' https://imgsmaller.com/api/v1/info

# Query string
curl 'https://imgsmaller.com/api/v1/info?api_key=demo_api_key'

Missing or invalid keys return HTTP 401.

GET /api/v1/plans

Returns available plan definitions (names, limits, allowed domain counts).

curl -H 'X-API-Key: demo_api_key' 'https://imgsmaller.com/api/v1/plans'

# Example 200 response
{
  "plans": {
    "free": { "name": "Free", "price": 0, "limit": 999, "allowed_domains_limit": 1 },
    "pro": { "name": "Pro", "price": 29, "limit": 20000, "allowed_domains_limit": 5 },
    "unlimited": { "name": "Unlimited", "price": 49, "limit": 0, "allowed_domains_limit": 10 }
  }
}

GET /api/v1/plan

Returns the authenticated user’s current plan, usage, and renew date.

curl -H 'X-API-Key: demo_api_key' 'https://imgsmaller.com/api/v1/plan'

# Example 200 response
{
  "plan_key": "pro",
  "plan_name": "Pro",
  "limit": 20000,
  "usage": 123,
  "renews_at": "2025-10-15T12:30:00Z",
  "allowed_domains_limit": 5
}

GET /api/v1/allowed-domains

Returns your current URL allowlist, plan limit, and remaining edits quota.

curl -H 'X-API-Key: demo_api_key' 'https://imgsmaller.com/api/v1/allowed-domains'

# Example 200 response
{
  "domains": ["example.com","cdn.example.com"],
  "limit": 5,
  "edits_remaining": 2
}

POST /api/v1/allowed-domains

Update your URL allowlist. Accepts either a JSON array or a comma/space separated string of domains. Wildcards like *.example.com are normalized to example.com. Subdomains are allowed automatically.

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/allowed-domains' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "domains": ["example.com", "assets.example.org"]
  }'

# Example 200 response
{"message":"Allowed domains updated","domains":["example.com","assets.example.org"]}

Form / query-style input

curl -X POST 'https://imgsmaller.com/api/v1/allowed-domains' \
  -H 'X-API-Key: demo_api_key' \
  -d 'domains=example.com, cdn.example.com'

Errors: 422 when exceeding your plan’s domain limit or invalid format; 429 when domain edit attempts are exhausted; 401 for invalid key.

GET /api/v1/info

Returns general capabilities and rate-limit context for anonymous requests. For authenticated users, daily fields are not enforced; see GET /api/v1/plan for monthly limits/usage.

curl -H 'X-API-Key: demo_api_key' 'https://imgsmaller.com/api/v1/info'

# Example 200 response (anonymous)
{
  "endpoint": "https://imgsmaller.com/api/v1/compress",
  "remaining_today": 98,
  "reset_in_seconds": 3600,
  "limit": 100,
  "supported_input": ["jpeg","jpg","png","webp","avif"],
  "supported_output": ["jpeg","jpg","png","webp","avif","original"]
}

# Example 200 response (authenticated – daily info not enforced)
{
  "endpoint": "https://imgsmaller.com/api/v1/compress",
  "remaining_today": 2147483647,
  "reset_in_seconds": 86400,
  "limit": 0,
  "supported_input": ["jpeg","jpg","png","webp","avif"],
  "supported_output": ["jpeg","jpg","png","webp","avif","original"]
}

POST /api/v1/compress

Accepts either multipart form-data (file upload) or JSON body with file_base64 or file_url.

  • target_size: auto or e.g. 20KB (defaults to auto).
  • output: one of jpeg, jpg, png, webp, avif, or original (keeps input format).
  • file_url: requires your Dashboard “Allowed Domain”. If not set or host not allowed, returns 403.

Successful requests return 202 with a progress_key and result_url. Poll https://imgsmaller.com/result/{key} until ready.

Examples: output=jpeg

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=jpeg'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "jpeg"
  }'

Examples: output=jpg

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=jpg'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "jpg"
  }'

Examples: output=png

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=png'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "png"
  }'

Examples: output=avif

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=avif'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "avif"
  }'

Examples: output=webp

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=webp'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "webp"
  }'

Examples: output=original

cURL (multipart)

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'X-API-Key: demo_api_key' \
  -F 'file=@/path/to/image.jpg' \
  -F 'target_size=20KB' \
  -F 'output=original'

# 202 Accepted
{
  "queued": true,
  "progress_key": "abcd1234deadbeef",
  "result_url": "https://imgsmaller.com/result/abcd1234deadbeef",
  "download_url_template": "https://imgsmaller.com/download/{imageId}"
}

JSON body

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_base64": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQA...",
    "target_size": "20KB",
    "output": "original"
  }'

Using file_url

For JSON with file_url, ensure your Dashboard → Allowed Domain is set (exactly one domain). Subdomains are allowed.

curl -X POST 'https://imgsmaller.com/api/v1/compress' \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: demo_api_key' \
  -d '{
    "file_url": "https://cdn.example.com/photo.jpg",
    "target_size": "auto",
    "output": "original"
  }'

# 403 if domain not allowed or not set
{
  "message": "No allowed domain set. Please set your allowed domain in dashboard."
}

Polling for Results

Use the result_url from the 202 response and poll until it returns the final JSON with download info.

curl 'https://imgsmaller.com/result/abcd1234deadbeef'

# Example when still processing
{"status":"processing"}

# Example when done
{
  "status": "done",
  "image_id": 12345,
  "download": "https://imgsmaller.com/download/12345",
  "bytes": 20480,
  "format": "webp"
}

Errors & Edge Cases

  • 401: Missing/Invalid API key.
  • 403: Disallowed or unset file_url domain.
  • 413: File too large (see server’s UPLOAD_MAX_MB).
  • 415/422: Unsupported or invalid image type.
  • 429: Daily limit exceeded (anonymous) or monthly plan limit reached (authenticated).
  • 422 (Allowed domains): Exceeds plan domain limit or invalid domain tokens.
  • 429 (Allowed domains): Domain edits limit reached.
  • 202: Accepted and queued; poll for completion.