Car Image API

Casos de uso · Aluguel de carros

Imagens de carros para páginas de frotas de locação

Mostre todas as categorias de locação da mesma forma: um modelo representativo por categoria, enquadramento idêntico com recorte, margem e ajuste, uma cor de pintura nomeada e URLs que você armazena em cache.

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".

O ID de um ano-modelo
# 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
};

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=side para 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 usa front-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çalhos X-Image-Width e X-Image-Height da 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=f4f4f4 aplica ao card o mesmo cinza da grade. Omita esse parâmetro para manter o fundo transparente e deixar a cor do card aparecer.
  • format=webp para arquivos armazenados; format=auto em URLs assinadas, que entrega WebP ou PNG conforme o navegador.
Um card e um banner principal para uma categoria
# 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

Passo 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/car e 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 o ETag de cada arquivo: uma nova verificação noturna com If-None-Match responde 304 e 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-urls aceita 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. Adicione renew: true e 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.

As URLs da grade, geradas uma única vez, com o SDK em TypeScript
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.

Uma URL renovável para uma confirmação
// 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 e MCP

  • CLI: npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webp grava um card em um arquivo; car-image url --batch classes.json --renew gera um lote de URLs.
  • SDK: client.vehicles({ make, model }) para os IDs, client.getImage(…) para arquivos, client.createImageUrls(…) para URLs.
  • MCP: resolve_vehicle e create_car_image_urls permitem 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.

Continue lendo

História de cliente · Ferramentas para desenvolvedoresComo incorporar imagens de carros em e-mails com URLs assinadas que nunca quebramNossos próprios e-mails de ciclo de vida incorporam a primeira renderização exata de cada cliente como uma URL assinada ativa, que se renova sozinha por um ano. Veja como isso funciona e como replicar.