compresso.Войти

Compresso API один запрос, лёгкая картинка

Отправьте изображение и получите сжатое прямо в ответе. Та же попиксельная проверка качества, что и на сайте, теперь из ваших скриптов, сборок и бэкендов. Бесплатно до 100 изображений в сутки.

Быстрый старт

  1. Войдите по email и скопируйте API-ключ в личном кабинете.
  2. Выполните команду ниже со своим ключом и любым файлом PNG, JPEG или WebP.
  3. photo-min.png и есть сжатая копия. Это вся интеграция.
curl
curl https://api.compresso.space/v1/compress \
  --user api:YOUR_API_KEY \
  --data-binary @photo.png \
  --output photo-min.png \
  --fail-with-body

Если что-то пошло не так, curl завершится с ошибкой, а в photo-min.png окажется короткое JSON-сообщение: что случилось и как это исправить.

В Windows PowerShell пишите curl.exe вместо curl: там curl является псевдонимом другой команды.

Авторизация

Каждый запрос требует API-ключ. Передайте его через HTTP Basic auth, с любым именем пользователя и ключом в качестве пароля (curl --user api:ВАШ_КЛЮЧ), или в заголовке Authorization: Bearer. Оба способа работают везде.

Запросы принимаются только по HTTPS. Обычный HTTP отклоняется с ошибкой https_required, без перенаправления. Если ключ хоть раз ушёл по HTTP, отзовите его в кабинете и создайте новый.

Храните ключи на сервере. API отклоняет запросы со страниц в браузере (browser_not_supported), поэтому ключ не может попасть к вашим посетителям. У аккаунта может быть до 10 активных ключей, любой можно отозвать в любой момент.

curl https://api.compresso.space/v1/usage --user api:YOUR_API_KEY

Сжатие изображений

Отправьте изображение методом POST на /v1/compress. Тело запроса: сами байты файла, либо форма multipart/form-data с изображением в поле file. Формат определяется по содержимому файла, поэтому Content-Type при отправке байтов не важен.

Успешный ответ и есть сжатое изображение: статус 200 и тот же формат, что вы отправили. Сохраните тело ответа как двоичный файл. Отдельного шага скачивания нет.

# raw bytes
curl https://api.compresso.space/v1/compress \
  --user api:YOUR_API_KEY \
  --data-binary @photo.png \
  --output photo-min.png \
  --fail-with-body

# or as a form upload (field "file")
curl https://api.compresso.space/v1/compress \
  --user api:YOUR_API_KEY \
  --form file=@photo.png \
  --output photo-min.png \
  --fail-with-body

Заголовки ответа

Content-Typeimage/png, image/jpeg или image/webp, как у исходного файла.
Original-SizeРазмер загруженного файла в байтах.
Compressed-SizeРазмер возвращённого изображения в байтах.
Compression-CountСколько сжатий аккаунт использовал за сегодня (UTC), включая это.
Compression-LimitВаш суточный лимит.
Compression-ResetКогда счётчик обнулится: ближайшие 00:00 UTC, например 2026-09-19T00:00:00Z.
Request-IdУкажите его, если пишете нам о конкретном запросе.

Проверка расхода

GET /v1/usage возвращает расход аккаунта, ничего не сжимая. Так удобно проверить, что ключ работает. Этот запрос не расходует лимит.

curl
curl https://api.compresso.space/v1/usage --user api:YOUR_API_KEY
Ответ
{
  "ok": true,
  "plan": "free",
  "compression_count": 3,
  "compression_limit": 100,
  "compression_reset": "2026-09-19T00:00:00Z",
  "key": "csk_…a1b2"
}

Сжатие папки

Отправляйте изображения по одному: у каждого аккаунта одновременно сжимается одно изображение и ещё одно ждёт, поэтому параллельные загрузки получат rate_limited. Если API отвечает 429 или 503 с заголовком Retry-After, подождите указанное число секунд и повторите. Без Retry-After повторять не нужно.

// Compress every PNG/JPEG/WebP in ./images into ./images-min, one at a time.
import { mkdir, readdir, readFile, writeFile } from "node:fs/promises"
import path from "node:path"

const KEY = process.env.COMPRESSO_API_KEY
const IN = "images"
const OUT = "images-min"
await mkdir(OUT, { recursive: true })

for (const name of await readdir(IN)) {
  if (!/\.(png|jpe?g|webp)$/i.test(name)) continue
  const body = await readFile(path.join(IN, name))

  for (;;) {
    const res = await fetch("https://api.compresso.space/v1/compress", {
      method: "POST",
      headers: { Authorization: `Bearer ${KEY}` },
      body,
    })
    if (res.ok) {
      await writeFile(path.join(OUT, name), Buffer.from(await res.arrayBuffer()))
      console.log(name, res.headers.get("Original-Size"), "->", res.headers.get("Compressed-Size"))
      break
    }
    const err = await res.json()
    // Retry only when the API says so, and only for short waits.
    const wait = Number(res.headers.get("Retry-After"))
    if (wait > 0 && wait <= 60) {
      await new Promise((r) => setTimeout(r, wait * 1000))
      continue
    }
    console.error(name, err.error, err.message)
    if (res.status === 429 || res.status === 503) process.exit(1) // limit or long outage
    break
  }
}

Что происходит с изображением

  • PNG, JPEG и WebP сжимаются тем же движком и с той же попиксельной проверкой качества, что на compresso.space. Результат визуально неотличим от оригинала.
  • Формат и размеры в пикселях не меняются. Ничего не уменьшается и не конвертируется.
  • В сжатых изображениях нет метаданных (EXIF, GPS, данных камеры). Фото сначала поворачиваются по EXIF-ориентации, поэтому остаются в правильном положении.
  • Если изображение нельзя уменьшить без видимой разницы, вы получите исходный файл без изменений, вместе с метаданными, со статусом 200. Такой запрос тоже считается сжатием.
  • Изображения обрабатываются в памяти, не записываются на диск и не хранятся. Само изображение никогда не попадает в логи: для статистики мы сохраняем только размеры и формат.

Частые ошибки

  • curl -d портит двоичные файлы. Всегда используйте --data-binary @файл или --form file=@файл.
  • Не отправляйте base64, data:-ссылку или JSON со ссылкой на картинку. Отправляйте байты файла.
  • В axios нужен responseType: "arraybuffer", иначе изображение прочитается как текст и испортится.
  • В Python requests сохраняйте res.content (байты), а не res.text.
  • Вызывайте API с сервера или из скриптов сборки, а не из JavaScript на странице: браузеры отклоняются намеренно.

Лимиты

Бесплатные сжатия100 на аккаунт в сутки, сброс в 00:00 UTC
Размер файладо 16 МБ на изображение
Разрешениедо 16 мегапикселей
Параллельные запросы1 в работе и 1 в ожидании на аккаунт
Частота запросов60 запросов в минуту на аккаунт
На сеть500 сжатий в сутки с одного IP-адреса по всем ключам
API-ключидо 10 активных ключей на аккаунт
Таймаутставьте таймаут клиента не меньше 120 секунд

Ошибки

Любая ошибка приходит в JSON: {"ok": false, "error": "код", "message": "...", "docs": "...", "request_id": "..."}. В message объяснено, что случилось и что делать, поэтому выводите его.

Правило повторов: если 429 или 503 пришли с заголовком Retry-After, подождите указанное число секунд и повторите. Без Retry-After автоматически не повторяйте.

КодHTTPЧто это значитПовторять?
https_required400Запрос пришёл по обычному HTTP. Используйте https://api.compresso.space/v1.Нет
input_missing400Тело запроса пустое. Отправьте байты изображения.Нет
invalid_multipart400Форма собрана неправильно. Пусть её соберёт ваш HTTP-клиент, или отправьте байты напрямую.Нет
invalid_image400Файл обрезан или повреждён. В curl используйте --data-binary, а не -d.Нет
unauthorized401Нет ключа, ключ неполный или с ошибкой, неизвестен или отозван. В message сказано, что именно.Нет
browser_not_supported403Запрос пришёл со страницы в браузере. Вызывайте API с сервера.Нет
not_found404Такого адреса нет. В API есть POST /v1/compress, GET /v1/usage и GET /v1/openapi.json.Нет
method_not_allowed405Неверный HTTP-метод для этого адреса. Правильный указан в заголовке Allow.Нет
file_too_large413Файл больше 16 МБ.Нет
image_too_large413Изображение больше 16 мегапикселей. Молча оно не уменьшается.Нет
unsupported_format415Это не PNG, JPEG или WebP. В message указан определённый формат.Нет
animated_unsupported415Анимированные изображения не поддерживаются.Нет
daily_limit_exceeded429Суточный лимит исчерпан. Он обнулится в 00:00 UTC, см. Compression-Reset.Нет
rate_limited429Слишком много запросов одновременно или за минуту. Подождите Retry-After секунд.Да, после Retry-After
server_busy503Сервер занят другой работой. Подождите Retry-After секунд.Да, после Retry-After
daily_capacity_reached503Общий суточный объём API исчерпан. Он обнулится в 00:00 UTC.Да, после Retry-After
api_disabled503API временно выключен на обслуживание. Попробуйте позже.Позже
compress_failed500Неожиданная ошибка на нашей стороне. Повторите один раз, затем напишите нам с request_id.Один раз

OpenAPI

Полное машиночитаемое описание API лежит по адресу https://api.compresso.space/v1/openapi.json (OpenAPI 3.1, ключ не нужен). Импортируйте его в Postman или Insomnia или сгенерируйте по нему клиент.

Изменения

  • Вышел API v1: /v1/compress, /v1/usage, 100 бесплатных сжатий в сутки.