Car Image API

Сценарии использования · Прокат автомобилей

Изображения автомобилей для страниц прокатного автопарка

Показывайте все классы проката единообразно: одна типичная модель на класс, одинаковое кадрирование с параметрами trim, padding и fit, один именованный цвет и URL, которые можно кешировать.

Руководство по интеграции, написанное на основе документированного поведения API; конкретные клиенты в нём не упоминаются. Опубликовано .

Проблема: вы арендуете класс, а не автомобиль

Клиент проката бронирует класс — компактный автомобиль, среднеразмерный кроссовер, минивэн — и уезжает на любом автомобиле этого класса, который есть на стоянке. Странице бронирования всё равно нужно изображение для каждого класса, и по сложившейся практике это одна типичная модель с пометкой «или аналогичный».

Такие изображения обычно берутся откуда придётся: здесь пресс-фото, там снимок дилера, разные ракурсы, разные фоны, автомобили по-разному заполняют карточку. Собранная так сетка и выглядит сборной. Странице автопарка нужно обратное: каждый класс показан одинаково, и от карточки к карточке меняется только сам автомобиль.

Как выглядит интеграция

  • Одна представительная модель на класс, сохранённая как идентификатор автомобиля из каталога; пометка «или аналогичный» — в подписи, но никогда на изображении.
  • Одна структура запроса для всех карточек: одинаковые ракурс, рамка, вписывание, обрезка, отступы, цвет, фон и формат.
  • Не более двух изображений на класс: карточка в сетке и главное изображение на странице класса.
  • Кешируются, потому что сетка одинакова для всех посетителей: файлы на вашем CDN или подписанные URL, созданные один раз и используемые повторно.

Шаг 1: выберите типичную модель для каждого класса по id

Выберите модель, под которой продаётся каждый класс, и найдите её текущий модельный год. GET /api/v1/vehicles?make=&model= — бесплатный публичный запрос, который возвращает все годы одной модели, каждый со стабильным id автомобиля, который вы сохраните; POST /api/v1/images/resolve делает то же самое по фразе вроде «2026 toyota rav4».

id одного модельного года
# one model's years, each with its vehicle id (free, public)
curl -s "https://carimage.dev/api/v1/vehicles?make=toyota&model=rav4" | jq -c '.data.vehicles[] | select(.year == 2026)'
# {"year":2026,"id":"veh_e5w75c93f6cvk"}
fleet.ts
// One representative model per class: its current model year, by catalog id.
// "or similar" lives in the label; the picture never promises the car on the lot.
export const CLASS_IMAGES = {
  compact:        { vehicle: "veh_fy7r2yvwt4p1v", label: "Toyota Corolla or similar" },    // 2026 Toyota Corolla
  "midsize-suv":  { vehicle: "veh_e5w75c93f6cvk", label: "Toyota RAV4 or similar" },       // 2026 Toyota RAV4
  "fullsize-suv": { vehicle: "veh_9mzh9ejqjye43", label: "Chevrolet Tahoe or similar" },   // 2026 Chevrolet Tahoe
  minivan:        { vehicle: "veh_9jck7rrybf35p", label: "Chrysler Pacifica or similar" }, // 2026 Chrysler Pacifica
};

Id никогда не меняются, поэтому изменения автопарка затрагивают только эту таблицу соответствий: когда класс среднеразмерных автомобилей переходит на другую модель или на следующий модельный год, замените один id — и все карточки, главные баннеры и письма, читающие таблицу, обновятся следом.

Шаг 2: один формат запроса для всех классов

Все ракурсы камеры (9) кадрируются одинаково для каждого автомобиля в каталоге — благодаря этому сетка выглядит ровно. Остальное в карточке — несколько параметров, которые задаются один раз:

  • view=side для карточек: все автомобили смотрят в одну сторону и стоят на одной базовой линии. У каждого ракурса левой стороны есть зеркальный -right (side-right), чтобы карточки были обращены внутрь макета. На странице класса используется front-3-4 — главный ракурс.
  • w=640&h=320&fit=contain: ровно 640×320 для каждого класса, автомобиль виден целиком. Заголовки ответа X-Image-Width и X-Image-Height подтверждают размер холста.
  • trim=1&padding=6: обрезка по автомобилю перед вписыванием с отступом в 6% от его длинной стороны, чтобы Corolla и Tahoe одинаково заполняли свои карточки, а не терялись в квадратном исходном кадре.
  • background=f4f4f4 заливает карточку тем же серым, что и сетка. Если не указывать этот параметр, фон останется прозрачным и сквозь него будет виден цвет карточки.
  • format=webp для сохраняемых файлов; format=auto для подписанных URL — он отдаёт каждому браузеру WebP или PNG.
Карточка и главное изображение для одного класса
# the class card: the same box, view, crop, paint and backdrop for every class
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/images/car?vehicle=veh_e5w75c93f6cvk&view=side&color=white&w=640&h=320&fit=contain&trim=1&padding=6&background=f4f4f4&format=webp" \
  -o midsize-suv-card.webp

# the class page's hero: the three-quarter view, the full width the API delivers
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/images/car?vehicle=veh_e5w75c93f6cvk&view=front-3-4&color=white&w=1024&format=webp" \
  -o midsize-suv-hero.webp

Шаг 3: один именованный цвет для всей сетки

Пресеты (всего 15) — это именованные цвета кузова: white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. По умолчанию используется silver, а grey читается как gray. Выберите один цвет для всех классов, чтобы карточки смотрелись единым набором; выше показан white. У каждого пресета свой образец краски, а не одноимённый цвет CSS (red — это #b3151b), и любой цвет, включая hex, — это перекраска одного подготовленного ракурса, поэтому каждый цвет — одно изображение автомобиля.

Шаг 4: кэшируйте файлы или URL

Сетка классов одинакова для всех посетителей, поэтому каждое посещение должно обходиться почти бесплатно. Добиться этого можно двумя способами:

  • Храните файлы у себя. Загрузите каждую карточку и главное изображение один раз через GET /api/v1/images/car и отдавайте их со своего CDN, как любой другой ресурс; платный тариф разрешает хранить копии на собственных серверах для работы вашего продукта, пока он активен (удалите их в течение 30 дней после окончания тарифа или купите Image Pack, чтобы сохранить набор навсегда). Сохраняйте ETag каждого файла: ночная повторная проверка с If-None-Match возвращает 304 и ничего не стоит. Для описанного выше автопарка это 8 изображений автомобилей за месяц с неограниченным повторным использованием.
  • Или создайте подписанные URL один раз и используйте их повторно. POST /api/v1/image-urls принимает до 50 изображений за вызов и возвращает URL без ключа, которые действуют до 7 дн. URL с неограниченным числом использований можно публично кэшировать в течение срока его действия, поэтому, когда все посетители загружают один и тот же URL, повторные загрузки бесплатно отдаются из CDN. Добавьте renew: true, и сохранённый URL продолжит работать после истечения срока; продление засчитывает изображение один раз в том месяце, на который оно приходится, и ничего сверх того, если оно уже было учтено в этом месяце, поэтому описанный выше автопарк остаётся в пределах не более 8 изображений автомобилей в месяц.

Ограничьте ключ, которым создаются URL, доменом вашего сайта бронирования в панели управления — и URL, скопированный на другой сайт, будет возвращать 403.

URL для сетки, созданные один раз, с помощью TypeScript SDK
import { CarImageClient, type ImageParams } from "@meterapp/car-image-sdk";
import { CLASS_IMAGES } from "./fleet";

const client = new CarImageClient({ apiKey: process.env.CAR_IMAGE_API_KEY });

// Framed once, for every class.
const card = (vehicle: string): ImageParams => ({
  vehicle, view: "side", color: "white", width: 640, height: 320,
  fit: "contain", trim: true, padding: 6, background: "#f4f4f4", format: "auto",
});
const hero = (vehicle: string): ImageParams => ({ vehicle, view: "front-3-4", color: "white", width: 1024, format: "auto" });

// Every visitor sees the same grid: mint the URLs once and serve the stored ones.
// renew keeps each URL working past its 7-day lifetime, one credit per image
// for each further week in which it is loaded.
const classes = Object.entries(CLASS_IMAGES);
const { data } = await client.createImageUrls(
  classes.flatMap(([, entry]) => [card(entry.vehicle), hero(entry.vehicle)]),
  { ttlSeconds: 604800, renew: true, idempotencyKey: "class-grid-2026-10" }
);
await saveClassImages(
  classes.map(([key], index) => ({ key, card: data[2 * index].url, hero: data[2 * index + 1].url, renewsUntil: data[2 * index].renews_until }))
);

Шаг 5: подтверждение бронирования

В письме-подтверждении показан забронированный класс, а письма арендатор открывает тогда, когда до них доходят руки. Создайте изображение как продлеваемый URL: ttl_seconds на максимуме (7 дн.), renew: true и renew_days с запасом после даты возврата. Недели, когда письмо никто не открывает, ничего не стоят, а после аренды URL перестаёт продлеваться. Idempotency-Key для каждого бронирования приводит к тому, что при повторной отправке возвращается первый URL, а не создаётся второй, а URL, сохранённый в бронировании, можно использовать при всех последующих отправках. Так устроены и наши собственные служебные письма; механизм и HTML описаны в истории о письмах.

Обновляемый URL для одного подтверждения
// The booking confirmation: opened today, again at the counter, maybe never.
const { data: [classImage] } = await client.createImageUrls(card(booking.classVehicle), {
  ttlSeconds: 604800,
  renew: true,
  // A week past the return date, and no renewals after it (365 days at most).
  renewDays: Math.min(daysUntil(booking.returnDate) + 7, 365),
  // A retried send replays the first URL instead of minting a second one.
  idempotencyKey: `booking:${booking.id}:class`,
});
booking.classImageUrl = classImage.url; // later resends reuse it

CLI, SDK и MCP

  • CLI: npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webp записывает карточку в файл; car-image url --batch classes.json --renew создаёт пакет URL.
  • SDK: client.vehicles({ make, model }) для id, client.getImage(…) для файлов, client.createImageUrls(…) для URL.
  • MCP: resolve_vehicle и create_car_image_urls позволяют ассистенту подготовить карточку класса по запросу «среднеразмерный SUV, RAV4 или аналог». Настройка описана на странице MCP.

Часто задаваемые вопросы

Может ли карточка показать именно тот автомобиль, который получит арендатор?
Нет, и пытаться не стоит. Класс сдаётся в аренду с оговоркой «или аналогичный», а рендер изображает марку, модель и год из каталога, а не автомобиль с вашей стоянки. Покажите одну типичную модель с пометкой «или аналогичный» в подписи. Когда за стойкой клиенту назначат конкретный автомобиль, его VIN бесплатно декодируется в автомобиль из каталога, если вы хотите показать именно эту модель.
Почему автомобили в сетке не в масштабе?
Потому что trim обрезает каждый рендер по контуру автомобиля, а fit=contain заполняет им карточку, поэтому компактный и полноразмерный SUV заполняют свои карточки одинаково. Именно это сохраняет сетку аккуратной. Указывайте размер словами: название класса, число мест и вместимость багажа.
Сколько стоит сетка классов?
Для автопарка, где число классов — 4, с карточкой и главным изображением для каждого, нужно 8 изображений автомобилей в месяц, и каждое можно получать сколько угодно раз в любом размере. Храните файлы в своём CDN, пока действует платный план, — тогда они учитываются только в том месяце, когда вы их загружаете, а повторные проверки по ETag бесплатны. Если же отдавать вместо этого обновляемые подписанные URL, те же изображения учитываются один раз в каждом месяце, в котором открываются страницы.
Какой цвет кузова использовать в сетке?
Один пресет для всех классов, чтобы карточки смотрелись как единый набор. Доступные пресеты (15): white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple, по умолчанию — silver; подойдёт и любой hex-код по той же цене. Арендатор получит автомобиль того цвета, который есть на стоянке, — карточка цвет и не обещала.
Что делать, если модели класса нет в каталоге?
Если автомобиля нет в каталоге, API отвечает 404 с подсказками: ближайшими автомобилями из каталога, каждый со своим id. Используйте один из них или запросите автомобиль на публичной доске запросов. Каталог распространяется с открытым исходным кодом.

Читайте также

История клиента · Инструменты для разработчиковКак встраивать изображения автомобилей в письма с помощью подписанных URL, которые никогда не ломаютсяВ наши собственные письма жизненного цикла встроен точный первый рендер каждого клиента в виде живого подписанного URL, который сам продлевается в течение года. Рассказываем, как это работает и как сделать так же.