Car Image API

Cas d’usage · Location de voitures

Images de voitures pour les pages de flotte de location

Présentez chaque catégorie de location de la même façon : un modèle représentatif par catégorie, un cadrage identique avec trim, padding et fit, une teinte nommée et des URL que vous mettez en cache.

Un guide d’intégration rédigé à partir du comportement documenté de l’API ; il ne cite aucun client. Publié le .

Le problème : vous louez une catégorie, pas une voiture

Un client de location réserve une catégorie (citadine compacte, SUV intermédiaire, monospace) et repart avec n’importe quelle voiture de cette catégorie disponible sur le parc. La page de réservation a tout de même besoin d’une image pour chaque catégorie, et l’usage veut un modèle représentatif accompagné de la mention « ou similaire ».

Ces images proviennent généralement de partout où l’on a pu les trouver : une photo presse ici, une photo de concessionnaire là, des angles différents, des arrière-plans différents, des voitures qui occupent leur carte différemment. Une grille constituée ainsi a l’air rafistolée. Ce qu’il faut à une page de flotte, c’est l’inverse : chaque catégorie représentée de la même manière, pour que seule la voiture change d’une carte à l’autre.

À quoi ressemble l’intégration

  • Un modèle représentatif par catégorie, conservé sous forme d’identifiant de véhicule du catalogue, avec « ou similaire » dans le libellé et jamais dans l’image.
  • Une seule forme de requête pour chaque fiche : la même vue, le même cadre, le même ajustement, le même recadrage, la même marge, la même peinture, le même arrière-plan et le même format.
  • Deux images par catégorie au maximum : la carte dans la grille et l’image principale sur la page de la catégorie.
  • Mis en cache, car la grille est la même pour chaque visiteur : fichiers sur votre CDN, ou URL signées émises une fois et réutilisées.

Étape 1 : choisissez un modèle représentatif par catégorie, par identifiant

Choisissez le modèle sous lequel chaque catégorie est commercialisée et recherchez son année-modèle actuelle. GET /api/v1/vehicles?make=&model= est gratuit et public, et liste toutes les années d’un modèle, chacune avec l’identifiant de véhicule stable que vous stockerez ; POST /api/v1/images/resolve fait de même à partir d’une expression comme « 2026 toyota rav4 ».

L’identifiant d’une année-modèle
# 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
};

Les identifiants ne changent jamais : cette table est donc le seul endroit touché par un changement de flotte. Quand la catégorie intermédiaire passe à un autre modèle, ou à l'année-modèle suivante, remplacez un identifiant, et chaque carte, visuel principal et e-mail qui lit la table suit.

Étape 2 : un seul format de requête pour toutes les catégories

Les 8 vues de caméra sont cadrées de façon identique pour chaque véhicule du catalogue, ce qui permet à une grille de s’aligner. Le reste de la vignette se résume à quelques paramètres, fixés une fois pour toutes :

  • view=side pour les cartes : chaque voiture est orientée dans le même sens, sur la même ligne de base. Chaque angle côté gauche a un jumeau -right (side-right), pour que les cartes puissent être orientées vers l’intérieur de la mise en page. La page de catégorie utilise front-3-4, l’angle vedette.
  • w=640&h=320&fit=contain : exactement 640×320 pour chaque catégorie, avec la voiture entièrement visible. Les en-têtes X-Image-Width et X-Image-Height de la réponse confirment le canevas.
  • trim=1&padding=6 : recadre sur la voiture avant de l’ajuster, avec une marge de 6 % de son plus grand côté, pour qu’une Corolla et un Tahoe remplissent leurs cartes de la même façon au lieu de flotter dans le cadre carré d’origine.
  • background=f4f4f4 place la carte sur le gris de la grille. Omettez-le pour conserver le fond transparent et laisser apparaître la couleur de la carte.
  • format=webp pour les fichiers stockés ; format=auto sur les URL signées, qui sert du WebP ou du PNG selon le navigateur.
Une fiche et un visuel principal pour une catégorie
# 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

Étape 3 : une seule peinture nommée pour toute la grille

Les 15 préréglages sont des peintures nommées : white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. La valeur par défaut est silver, et grey est interprété comme gray. Choisissez-en une pour chaque catégorie afin que les fiches forment un ensemble ; white est présenté ci-dessus. Chaque préréglage conserve sa propre teinte de peinture plutôt que la couleur CSS du même nom (red correspond à #b3151b), et chaque peinture, y compris une valeur hexadécimale, est une recoloration d'un même rendu neutre : elle coûte donc toujours 1 crédit.

Étape 4 : mettre en cache les fichiers ou les URL

La grille des catégories est identique pour chaque visiteur : elle ne devrait donc presque rien coûter par visite. Deux façons d’y parvenir :

  • Stockez les fichiers. Récupérez chaque carte et chaque visuel principal une seule fois avec GET /api/v1/images/car et servez-les depuis votre CDN comme n'importe quel autre fichier ; un forfait payant autorise des copies sur vos propres serveurs pour servir votre produit, et elles conservent leur licence après la fin du forfait. Conservez l’ETag de chaque fichier : une revérification nocturne avec If-None-Match répond 304 et ne coûte rien. Pour la flotte ci-dessus, cela représente 8 crédits, une seule fois.
  • Ou émettez des URL signées une fois et réutilisez-les. POST /api/v1/image-urls accepte jusqu’à 50 images par appel et renvoie des URL sans clé valables jusqu’à 7 jours. Une URL à utilisations illimitées peut être mise en cache publiquement pendant sa durée de validité : lorsque chaque visiteur charge la même URL, les chargements suivants proviennent gratuitement du CDN. Ajoutez renew: true et une URL enregistrée continue de fonctionner au-delà de sa durée de validité, à raison de 1 crédit par image pour chaque semaine supplémentaire où elle est chargée : au maximum 8 crédits par semaine pour la flotte ci-dessus.

Limitez la clé qui génère les URL à votre domaine de réservation dans le tableau de bord : une URL copiée sur un autre site renverra alors 403.

Les URL de la grille, générées une seule fois, avec le SDK 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 }))
);

Étape 5 : la confirmation de réservation

L'e-mail de confirmation montre la catégorie réservée, et les e-mails sont ouverts quand le locataire en a le temps. Générez son image sous forme d'URL renouvelable : ttl_seconds au maximum de 7 jours, renew: true, et renew_days allant au-delà de la date de restitution. Les semaines où personne n'ouvre l'e-mail ne coûtent rien, et après la location, l'URL cesse de se renouveler. Une Idempotency-Key par réservation fait qu'un envoi relancé rejoue la première URL au lieu d'en générer une deuxième, et enregistrer l'URL dans la réservation permet de la réutiliser à chaque renvoi ultérieur. Nos propres e-mails de cycle de vie fonctionnent ainsi ; le cas de l'e-mail détaille le mécanisme et le HTML.

Une URL renouvelable par confirmation
// 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 et MCP

  • CLI : npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webp écrit une vignette dans un fichier ; car-image url --batch classes.json --renew génère un lot d’URL.
  • SDK : client.vehicles({ make, model }) pour les identifiants, client.getImage(…) pour les fichiers, client.createImageUrls(…) pour les URL.
  • MCP : resolve_vehicle et create_car_image_urls permettent à un assistant de rédiger une fiche de catégorie à partir de « SUV intermédiaire, RAV4 ou similaire ». La configuration est décrite sur la page MCP.

Questions fréquentes

La fiche peut-elle montrer la voiture exacte que le client recevra ?
Non, et ce n’est pas son rôle. Une catégorie se loue « ou similaire », et un rendu représente une marque, un modèle et une année du catalogue, pas une voiture de votre parc. Affichez un modèle représentatif avec « ou similaire » dans la légende. Une fois qu’une voiture précise est attribuée au comptoir, son VIN se décode gratuitement en son véhicule du catalogue si vous préférez afficher ce modèle.
Pourquoi les voitures de la grille ne sont-elles pas à l’échelle ?
Parce que trim recadre chaque rendu sur la voiture et que fit=contain l’agrandit pour remplir la vignette : une compacte et un grand SUV remplissent ainsi leur vignette de la même manière. C’est ce qui garde une grille nette. Exprimez la taille avec des mots : le nom de la catégorie, le nombre de places et de bagages.
Combien coûte la grille des catégories ?
Une flotte de 4 catégories, avec une vignette et une image principale pour chacune, revient à 8 crédits. Stockez les fichiers sur votre CDN et c’est toute la facture, les revérifications par ETag étant gratuites. Servez plutôt des URL signées renouvelables et cela coûte au plus 8 crédits par semaine, uniquement pour les semaines où les pages sont ouvertes.
Quelle peinture utiliser pour la grille ?
Une seule couleur prédéfinie pour toutes les catégories, afin que les cartes forment un ensemble. Les 15 couleurs prédéfinies sont white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple, et la couleur par défaut est silver ; tout code hex fonctionne aussi, au même prix. Le client reçoit la couleur disponible sur le parc, ce que la carte n’a jamais promis.
Et si le modèle d’une catégorie n’est pas dans le catalogue ?
Un véhicule absent du catalogue renvoie une 404 avec des suggestions : les véhicules du catalogue les plus proches, chacun avec son identifiant. Utilisez l'un d'eux ou demandez le véhicule sur le tableau public des demandes. Le catalogue est open source.

Poursuivre la lecture

Témoignage client · Outils pour développeursComment intégrer des images de voitures dans vos e-mails avec des URL signées qui ne cassent jamaisNos propres e-mails de cycle de vie intègrent le tout premier rendu de chaque client sous forme d’URL signée active qui se renouvelle d’elle-même pendant un an. Voici comment cela fonctionne et comment le reproduire.