Una guía de implementación escrita a partir del comportamiento documentado de la API; no menciona a ningún cliente. Publicado el .
El problema: se alquila una categoría, no un vehículo
Un cliente de alquiler reserva una categoría (un compacto, un SUV mediano, un monovolumen) y se lleva el coche de esa categoría que esté disponible en ese momento. Aun así, la página de reservas necesita una imagen para cada categoría, y la convención es mostrar un modelo representativo con las palabras "o similar".
Esas imágenes suelen venir de donde se haya podido encontrar cada una: una foto de prensa aquí, una foto de concesionario allá, distintos ángulos, distintos fondos, coches que llenan sus tarjetas de forma diferente. Una cuadrícula montada así se nota montada. Lo que necesita una página de flota es lo contrario: todas las categorías representadas de la misma manera, para que lo único que cambie de una tarjeta a otra sea el coche.
Cómo es la integración
- Un modelo representativo por categoría, guardado como id de vehículo del catálogo, con "o similar" en la etiqueta y nunca en la imagen.
- Una misma forma de solicitud para todas las tarjetas: la misma vista, caja, ajuste, recorte, margen, pintura, fondo y formato.
- Dos imágenes por categoría como máximo: la tarjeta de la cuadrícula y la imagen principal de la página de la categoría.
- En caché, porque la cuadrícula es la misma para todos los visitantes: archivos en su CDN, o URL firmadas generadas una vez y reutilizadas.
Paso 1: elija un modelo representativo por categoría, por id
Elija el modelo con el que se comercializa cada categoría y consulte su año de modelo actual. GET /api/v1/vehicles?make=&model= es gratuito y público, y enumera todos los años de un modelo, cada uno con el id de vehículo estable que usted guardará; POST /api/v1/images/resolve hace lo mismo a partir de una frase como "2026 toyota rav4".
# 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"}// 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
};Los ids nunca cambian, así que este mapa es el único lugar al que afecta un cambio de flota: cuando la categoría intermedia pase a otro modelo, o al siguiente año de modelo, sustituya un id y todas las tarjetas, imágenes principales y correos que leen el mapa se actualizarán.
Paso 2: un mismo formato de solicitud para todas las categorías
Las 8 vistas de cámara se encuadran de forma idéntica para todos los vehículos del catálogo, y eso es lo que hace que una cuadrícula quede alineada. El resto de la tarjeta son unos pocos parámetros que se deciden una sola vez:
view=sidepara las tarjetas: todos los coches miran hacia el mismo lado sobre la misma línea base. Cada ángulo del lado izquierdo tiene un gemelo-right(side-right), para que las tarjetas puedan mirar hacia el interior del diseño. La página de la categoría usafront-3-4, el ángulo principal.w=640&h=320&fit=contain: exactamente 640×320 para cada categoría, con el coche entero visible. Las cabecerasX-Image-WidthyX-Image-Heightde la respuesta confirman el lienzo.trim=1&padding=6: recorta la imagen al coche antes de ajustarla, con un 6 % de su lado más largo como margen, para que un Corolla y un Tahoe llenen sus tarjetas de la misma forma en lugar de flotar en el encuadre cuadrado original.background=f4f4f4integra la tarjeta en el propio gris de la cuadrícula. Omítalo para mantener el fondo transparente y dejar que se vea el color de la tarjeta.format=webppara archivos almacenados;format=autoen URL firmadas, que sirve WebP o PNG según el navegador.
# 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.webpPaso 3: un único color con nombre para toda la cuadrícula
Los 15 colores predefinidos son pinturas con nombre: white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. El predeterminado es silver, y grey se interpreta como gray. Elija uno para todas las categorías para que las tarjetas formen un conjunto; arriba se muestra white. Cada color predefinido mantiene su propia muestra de pintura en lugar del color CSS del mismo nombre (red es #b3151b), y cada pintura, incluido un hex, es un recoloreado de un único render neutro, así que cuesta lo mismo: 1 crédito.
Paso 4: almacene en caché los archivos o las URL
La cuadrícula de categorías es idéntica para todos los visitantes, así que cada visita debería costar casi nada. Hay dos formas de lograrlo:
- Guarde los archivos. Obtenga cada tarjeta e imagen principal una sola vez con
GET /api/v1/images/cary sírvalas desde su CDN como cualquier otro recurso; un plan de pago permite tener copias en sus propios servidores para servir su producto, y conservan su licencia cuando el plan termina. Guarde elETagde cada archivo: una comprobación nocturna conIf-None-Matchresponde304y no cuesta nada. Para la flota anterior son 8 créditos, una sola vez. - O genere URL firmadas una vez y reutilícelas.
POST /api/v1/image-urlsadmite hasta 50 imágenes por llamada y devuelve URL sin clave que duran hasta 7 días. Una URL de usos ilimitados se puede almacenar en caché públicamente durante su vida útil, así que cuando todos los visitantes cargan la misma URL, las repeticiones salen gratis de la CDN. Añadarenew: truey una URL guardada seguirá funcionando después de su vida útil, a 1 crédito por imagen por cada semana adicional en la que se cargue: como máximo 8 créditos a la semana para la flota anterior.
Restrinja la clave que genera las URL a su dominio de reservas en el panel, y una URL copiada en otro sitio responderá 403.
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 }))
);Paso 5: la confirmación de la reserva
El correo de confirmación muestra la categoría reservada, y los correos se abren cuando el cliente llega a ellos. Genere su imagen como una URL que se renueva: ttl_seconds en el máximo de 7 días, renew: true y renew_days hasta después de la fecha de devolución. Las semanas en que nadie abre el correo no cuestan nada, y tras el alquiler la URL deja de renovarse. Una Idempotency-Key por reserva hace que un envío reintentado repita la primera URL en lugar de generar una segunda, y guardar la URL en la reserva permite que cada reenvío posterior la reutilice. Nuestros propios correos de ciclo de vida funcionan así; la historia del correo explica el mecanismo y el HTML.
// 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 itCLI, SDK y MCP
- CLI:
npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webpescribe una tarjeta en un archivo;car-image url --batch classes.json --renewemite un lote de URL. - SDK:
client.vehicles({ make, model })para los id,client.getImage(…)para archivos yclient.createImageUrls(…)para URL. - MCP:
resolve_vehicleycreate_car_image_urlspermiten que un asistente redacte una tarjeta de categoría a partir de "SUV mediano, RAV4 o similar". La configuración está en la página de MCP.
Preguntas frecuentes
- ¿Puede la tarjeta mostrar el vehículo exacto que recibirá el cliente?
- No, y no debería intentarlo. Una categoría se alquila como «o similar», y un render representa una marca, un modelo y un año del catálogo, no un coche de su flota. Muestre un modelo representativo con «o similar» en la etiqueta. Cuando se asigne un coche concreto en el mostrador, su VIN se decodifica gratis a su vehículo del catálogo si prefiere mostrar ese modelo.
- ¿Por qué los coches de la cuadrícula no están a escala?
- Porque trim recorta cada render al contorno del coche y fit=contain hace que este llene la tarjeta, de modo que un compacto y un SUV grande llenan sus tarjetas de la misma manera. Eso es lo que mantiene ordenada una cuadrícula. Indique el tamaño con palabras: el nombre de la categoría, las plazas y las maletas.
- ¿Cuánto cuesta la cuadrícula de categorías?
- Una flota de 4 categorías con una tarjeta y una imagen principal cada una cuesta 8 créditos. Guarde los archivos en su CDN y esa es toda la factura, con revalidaciones gratuitas por ETag. Si en su lugar sirve URL firmadas renovables, cuesta como máximo 8 créditos a la semana, solo en las semanas en que se abren las páginas.
- ¿Qué color de pintura debe usar la cuadrícula?
- Un mismo color predefinido para todas las categorías, para que las tarjetas se vean como un conjunto. Los 15 colores predefinidos son white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple, y el predeterminado es silver; también sirve cualquier código hexadecimal, al mismo precio. El cliente recibe el color que haya en la flota disponible, algo que la tarjeta nunca prometió.
- ¿Y si el modelo de una categoría no está en el catálogo?
- Un vehículo que no existe responde 404 con sugerencias: los vehículos del catálogo más cercanos, cada uno con su id. Use uno de ellos o solicite el vehículo en el tablón público de solicitudes. El catálogo es de código abierto.