Документация для разработчиков

Оптимизация изображений

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

Картинки — самая тяжёлая часть письма, и вес влияет не только на трафик: часть почтовых клиентов обрезает письмо целиком, а на мобильном интернете тяжёлая вёрстка просто не догружается. Эндпоинт прогоняет изображение через тот же конвейер, который DashaMail применяет к загрузкам в файловый менеджер.

Что происходит с картинкой:

  • Геометрия. Если ширина больше 1600 px, изображение ужимается до этого потолка с сохранением пропорций. Прозрачность, анимация и ориентация из EXIF сохраняются.
  • Пережатие. Кодек переупаковывает файл и снимает метаданные. По умолчанию — без потерь: пиксели остаются прежними до единого.

Формат никогда не меняется. JPEG остаётся JPEG, PNG — PNG. Это сделано намеренно: в письмах не работают ни WebP, ни AVIF, а подменить формат по согласованию с клиентом нельзя — в письме зашит статический адрес картинки.

Метод ничего не сохраняет: ни в вашем файловом менеджере, ни где-либо ещё результат не остаётся. Это чистое преобразование «прислали — получили обратно».

Оптимизировать изображение #

POST /images/optimize

Принимает JPEG, PNG или GIF и возвращает облегчённую версию в том же формате вместе со статистикой: сколько весило, сколько стало и какие шаги сработали.

Если ужать не удалось — картинка уже оптимальна, нужного кодека нет на сервере или результат получился больше исходника, — метод возвращает файл без изменений и changed: false. Ошибкой это не считается.

Как передать картинку. Либо полем image в JSON — строка base64, допускается префикс data:image/png;base64,. Либо как файл в multipart/form-data, поле file:

curl -X POST 'https://api.dashamail.com/v2/images/optimize' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -F 'file=@photo.jpg'

Второй способ предпочтителен для крупных файлов: base64 раздувает тело запроса примерно на треть.

Параметры строки запроса

ПараметрТипОписание
responsestringСо значением binary метод отдаёт сами байты картинки с соответствующим Content-Type, а статистику кладёт в заголовки X-Imageopt-Original-Size, X-Imageopt-Size и X-Imageopt-Saved-Bytes. По умолчанию ответ приходит в обычном JSON-конверте.

Параметры тела запроса

ПараметрТипОписание
imagestringКартинка в base64. Не нужен, если файл передан через multipart/form-data.
resizeфлагУжимать ли по ширине. По умолчанию включено; 0 оставит исходную геометрию и выполнит только пережатие.
max_widthintegerДругой потолок ширины вместо 1600 px. Допустимо от 16 до 20000.
lossyфлагРазрешить пережатие с потерями. Даёт заметно меньший файл ценой небольшой потери качества; по умолчанию выключено.

Что возвращается

Оптимизированную картинку в base64 (поле image) и статистику обработки. Поле steps показывает, что сработало на каждом из двух шагов, — полезно, когда результат не совпал с ожиданием.

Возможные ошибки

HTTPcodeКогда возникает
422 3 Картинка не передана, image не является корректным base64, формат не JPEG/PNG/GIF либо max_width вне диапазона 16–20000
413 26 Картинка тяжелее 20 МиБ
curl -X POST 'https://api.dashamail.com/v2/images/optimize' \
  -H 'Authorization: Bearer YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{
  "image": "iVBORw0KGgoAAAANSUhEUgAAA…",
  "lossy": 1
}'
<?php
$ch = curl_init('https://api.dashamail.com/v2/images/optimize');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_CUSTOMREQUEST  => 'POST',
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer YOUR_API_KEY',
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
            'image' => 'iVBORw0KGgoAAAANSUhEUgAAA…',
            'lossy' => 1,
        ], JSON_UNESCAPED_UNICODE),
]);

$response = json_decode(curl_exec($ch), true);
$status   = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);

if ($status >= 400) {
    throw new RuntimeException($response['error']['message']);
}
print_r($response['response']['data']);
import requests

response = requests.post(
    'https://api.dashamail.com/v2/images/optimize',
    headers={'Authorization': 'Bearer YOUR_API_KEY'},
    json={
        'image': 'iVBORw0KGgoAAAANSUhEUgAAA…',
        'lossy': 1,
    },
)

response.raise_for_status()
print(response.json()['response']['data'])
const response = await fetch('https://api.dashamail.com/v2/images/optimize', {
  method: 'POST',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
  "image": "iVBORw0KGgoAAAANSUhEUgAAA…",
  "lossy": 1
}),
});

const payload = await response.json();
if (!response.ok) throw new Error(payload.error.message);
console.log(payload.response.data);
Ответ HTTP 200
{
  "response": {
    "msg": {
      "err_code": 0,
      "text": "OK",
      "type": "message"
    },
    "data": {
      "format": "png",
      "mime": "image/png",
      "changed": true,
      "steps": {
        "resize": "already_narrow",
        "compress": "pngquant"
      },
      "width": 900,
      "height": 600,
      "original_width": 900,
      "original_height": 600,
      "original_size": 812345,
      "size": 279431,
      "saved_bytes": 532914,
      "saved_percent": 65.6,
      "image": "iVBORw0KGgoAAAANSUhEUgAAA…"
    }
  }
}

DashaMail хранит и защищает ваши данные на территории Российской Федерации

Подробнее...