Um guia de implementação escrito com base no comportamento documentado da API; não cita nenhum cliente. Publicado em .
O problema: você aluga uma categoria, não um carro
Um cliente de locadora reserva uma categoria — um compacto, um SUV médio, uma minivan — e sai com qualquer carro dessa categoria que estiver no pátio. A página de reserva ainda precisa de uma imagem para cada categoria, e a convenção é usar um modelo representativo com as palavras "ou similar".
Essas imagens costumam vir de onde quer que cada uma pudesse ser encontrada: uma foto de imprensa aqui, uma foto de concessionária ali, ângulos diferentes, fundos diferentes, carros que preenchem seus cards de maneiras diferentes. Uma grade montada assim parece montada. O que uma página de frota pede é o oposto: todas as categorias apresentadas da mesma forma, para que a única coisa que mude de um card para outro seja o carro.
Como fica a integração
- Um modelo representativo por categoria, guardado como id de veículo do catálogo, com "ou similar" no rótulo e nunca na imagem.
- Um único formato de requisição para todos os cards: a mesma vista, caixa, ajuste, recorte, preenchimento, cor, fundo e formato.
- No máximo duas imagens por categoria: o card na grade e a imagem de destaque na página da categoria.
- Em cache, porque a grade é a mesma para todos os visitantes: arquivos na sua CDN ou URLs assinadas geradas uma vez e reutilizadas.
Etapa 1: escolha um modelo representativo por categoria, pelo id
Escolha o modelo sob o qual cada categoria é vendida e consulte o ano-modelo atual. GET /api/v1/vehicles?make=&model= é gratuito e público e lista todos os anos de um modelo, cada um com o id estável do veículo que você vai armazenar; POST /api/v1/images/resolve faz o mesmo a partir de uma 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
};Os ids nunca mudam, então este mapa é o único lugar afetado por uma mudança na frota: quando a categoria intermediária passar para outro modelo, ou para o próximo ano-modelo, substitua um id e todos os cards, imagens de destaque e e-mails que leem o mapa acompanham a mudança.
Passo 2: um formato de requisição para todas as categorias
As 8 vistas de câmera são enquadradas de forma idêntica para todos os veículos do catálogo, e é isso que deixa uma grade alinhada. O resto do cartão é um punhado de parâmetros, definidos uma única vez:
view=sidepara os cards: todos os carros ficam voltados para o mesmo lado, sobre a mesma linha de base. Cada ângulo do lado esquerdo tem um gêmeo-right(side-right), para que os cards fiquem voltados para dentro do layout. A página da categoria usafront-3-4, o ângulo principal.w=640&h=320&fit=contain: exatamente 640×320 para todas as categorias, com o carro inteiro visível. Os cabeçalhosX-Image-WidtheX-Image-Heightda resposta confirmam as dimensões.trim=1&padding=6: recorta a imagem até o carro antes de ajustá-lo, com 6% do lado mais longo como margem, para que um Corolla e um Tahoe preencham seus cards da mesma forma, em vez de flutuarem no quadro quadrado de origem.background=f4f4f4aplica ao card o mesmo cinza da grade. Omita esse parâmetro para manter o fundo transparente e deixar a cor do card aparecer.format=webppara arquivos armazenados;format=autoem URLs assinadas, que entrega WebP ou PNG conforme o 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.webpPasso 3: uma cor nomeada para toda a grade
As 15 predefinições são cores nomeadas: white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. O padrão é silver, e grey é lido como gray. Escolha uma para todas as categorias para que os cards formem um conjunto; white é mostrada acima. Cada predefinição mantém sua própria amostra de pintura, em vez da cor CSS de mesmo nome (red é #b3151b), e toda cor, inclusive um hex, é uma recoloração de uma única renderização neutra, por isso o custo é o mesmo: 1 crédito.
Etapa 4: armazene em cache os arquivos ou as URLs
A grade de categorias é idêntica para todos os visitantes, então deve custar quase nada por visita. Há duas formas de chegar lá:
- Armazene os arquivos. Busque cada card e imagem de destaque uma vez com
GET /api/v1/images/care sirva-os pela sua CDN como qualquer outro asset; um plano pago permite manter cópias nos seus próprios servidores para atender ao seu produto, e elas mantêm a licença depois que o plano termina. Guarde oETagde cada arquivo: uma nova verificação noturna comIf-None-Matchresponde304e não custa nada. Para a frota acima, isso dá 8 créditos, uma única vez. - Ou gere URLs assinadas uma vez e reutilize-as.
POST /api/v1/image-urlsaceita até 50 imagens por chamada e retorna URLs sem chave válidas por até 7 dias. Uma URL com usos ilimitados pode ser armazenada em cache publicamente durante sua validade; assim, quando todos os visitantes carregam a mesma URL, as repetições vêm da CDN sem custo. Adicionerenew: truee uma URL armazenada continua funcionando após a validade, a 1 crédito por imagem para cada semana adicional em que for carregada: no máximo 8 créditos por semana para a frota acima.
Restrinja a chave que emite as URLs ao seu domínio de reservas no painel, e uma URL copiada para outro site 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 }))
);Etapa 5: a confirmação da reserva
O e-mail de confirmação mostra a categoria reservada, e os e-mails são abertos quando o locatário tiver tempo. Gere a imagem como uma URL renovável: ttl_seconds no máximo de 7 dias, renew: true e renew_days estendendo-se além da data de devolução. Semanas em que ninguém abre o e-mail não custam nada, e após a locação a URL deixa de ser renovada. Uma Idempotency-Key por reserva faz com que um envio repetido reutilize a primeira URL em vez de gerar uma segunda, e armazenar a URL na reserva permite que todo reenvio posterior a reutilize. Nossos próprios e-mails de ciclo de vida funcionam assim; o caso do e-mail mostra o mecanismo e o 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 e MCP
- CLI:
npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webpgrava um card em um arquivo;car-image url --batch classes.json --renewgera um lote de URLs. - SDK:
client.vehicles({ make, model })para os IDs,client.getImage(…)para arquivos,client.createImageUrls(…)para URLs. - MCP:
resolve_vehicleecreate_car_image_urlspermitem que um assistente monte um cartão de categoria a partir de "SUV médio, RAV4 ou similar". A configuração está na página do MCP.
Perguntas frequentes
- O cartão pode mostrar exatamente o carro que o cliente vai receber?
- Não, e nem deveria tentar. Uma categoria é alugada como “ou similar”, e uma renderização retrata uma marca, um modelo e um ano do catálogo, não um carro do seu pátio. Mostre um modelo representativo com “ou similar” no rótulo. Quando um carro específico for atribuído no balcão, o VIN dele é decodificado gratuitamente para o veículo correspondente no catálogo, caso você prefira mostrar esse modelo.
- Por que os carros da grade não estão em escala?
- Porque trim recorta cada renderização no contorno do carro e fit=contain faz com que ele preencha o card, então um compacto e um SUV grande preenchem seus cards da mesma forma. É isso que mantém a grade organizada. Informe o tamanho em palavras: o nome da categoria, os assentos e as malas.
- Quanto custa a grade de categorias?
- Uma frota de 4 categorias, com um cartão e uma imagem de destaque para cada uma, custa 8 créditos. Armazene os arquivos na sua CDN e essa é a conta inteira, com novas verificações gratuitas por ETag. Se preferir servir URLs assinadas renováveis, o custo é de no máximo 8 créditos por semana, apenas nas semanas em que as páginas forem abertas.
- Qual pintura usar na grade?
- Uma cor predefinida para todas as categorias, para que os cards formem um conjunto. As 15 cores predefinidas são white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple, e a padrão é silver; qualquer código hex também funciona, pelo mesmo preço. O locatário recebe a cor que está no pátio, algo que o card nunca prometeu.
- E se o modelo de uma categoria não estiver no catálogo?
- Um veículo que não está no catálogo responde 404 com sugestões: os veículos mais próximos do catálogo, cada um com seu id. Use um deles ou peça o veículo no quadro público de solicitações. O catálogo é de código aberto.