Una guida pratica scritta a partire dal comportamento documentato dell'API; non nomina alcun cliente. Pubblicato il .
Il problema: si noleggia una categoria, non un'auto
Un cliente del noleggio prenota una categoria, una compatta, un SUV medio, un monovolume, e parte con qualsiasi auto di quella categoria sia disponibile nel piazzale. La pagina di prenotazione ha comunque bisogno di un'immagine per ogni categoria, e la convenzione è un modello rappresentativo con la dicitura "o similare".
Quelle immagini tendono a provenire da dove era possibile trovarle: una foto stampa qui, una foto di un concessionario là, angolazioni diverse, sfondi diversi, auto che riempiono le schede in modo diverso. Una griglia messa insieme così sembra proprio messa insieme. Una pagina della flotta richiede l’opposto: ogni categoria ritratta allo stesso modo, così che l’unica cosa che cambia da una scheda all’altra sia l’auto.
Come si presenta l'integrazione
- Un modello rappresentativo per categoria, salvato come ID veicolo del catalogo, con "o simile" nell'etichetta e mai nell'immagine.
- Un'unica struttura di richiesta per ogni scheda: stessa vista, riquadro, adattamento, ritaglio, margine, vernice, sfondo e formato.
- Al massimo due immagini per categoria: la scheda nella griglia e l'immagine principale nella pagina della categoria.
- In cache, perché la griglia è uguale per ogni visitatore: file sulla sua CDN, oppure URL firmati generati una volta e riutilizzati.
Passo 1: scegliere un modello rappresentativo per ogni categoria, tramite id
Scelga il modello con cui viene venduta ciascuna categoria e ne cerchi l'anno modello attuale. GET /api/v1/vehicles?make=&model= è gratuito e pubblico ed elenca ogni anno di un modello, ciascuno con l'id stabile del veicolo da memorizzare; POST /api/v1/images/resolve fa lo stesso a partire da una frase come "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
};Gli id non cambiano mai, quindi questa mappa è l'unico punto toccato da una modifica della flotta: quando la categoria media passa a un altro modello, o all'anno modello successivo, sostituisca un id e ogni scheda, immagine principale ed email che legge la mappa si adegua.
Passaggio 2: un'unica struttura di richiesta per ogni categoria
Le 9 viste sono inquadrate in modo identico per ogni veicolo del catalogo, ed è questo che permette a una griglia di allinearsi. Il resto della scheda è una manciata di parametri, decisi una volta per tutte:
view=sideper le schede: ogni auto è rivolta nella stessa direzione sulla stessa linea di base. Ogni angolazione del lato sinistro ha un gemello-right(side-right), così le schede possono essere rivolte verso l'interno del layout. La pagina della categoria usafront-3-4, l'angolazione principale.w=640&h=320&fit=contain: esattamente 640×320 per ogni categoria, con l'intera auto visibile. Gli headerX-Image-WidtheX-Image-Heightdella risposta confermano le dimensioni della tela.trim=1&padding=6: ritaglia l'immagine sull'auto prima di adattarla, con un margine pari al 6% del suo lato più lungo, così una Corolla e un Tahoe riempiono le loro schede allo stesso modo invece di fluttuare nel riquadro quadrato di origine.background=f4f4f4appiattisce la card sul grigio della griglia. Lo ometta per mantenere lo sfondo trasparente e lasciar trasparire il colore della card.format=webpper i file salvati;format=autosugli URL firmati, che serve WebP o PNG in base al browser.
# 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: un'unica vernice con nome per tutta la griglia
I 15 preset sono vernici con un nome: white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. Il valore predefinito è silver, e grey viene interpretato come gray. Ne scelga uno per tutte le categorie, così che le schede risultino un insieme coerente; sopra è mostrato white. Ogni preset mantiene il proprio campione di vernice anziché il colore CSS con lo stesso nome (red è #b3151b), e ogni vernice, hex compreso, è una ricolorazione di un’unica vista preparata, quindi ogni vernice corrisponde a un’immagine di veicolo.
Passaggio 4: mettere in cache i file o gli URL
La griglia delle categorie è identica per ogni visitatore, quindi dovrebbe costare quasi nulla per visita. Ci sono due modi per arrivarci:
- Archivi i file. Scarichi ogni scheda e immagine hero una volta con
GET /api/v1/images/care le serva dalla sua CDN come qualsiasi altra risorsa; un piano a pagamento consente copie sui suoi server per servire il suo prodotto finché è attivo (le elimini entro 30 giorni dalla scadenza, oppure acquisti un Image Pack per conservare un set per sempre). Conservi l’ETagdi ogni file: una verifica notturna conIf-None-Matchrisponde304e non costa nulla. Per la flotta qui sopra sono 8 immagini di veicoli del mese, riutilizzabili tutte le volte necessarie. - Oppure generi gli URL firmati una volta e li riutilizzi.
POST /api/v1/image-urlsaccetta fino a 50 immagini per chiamata e restituisce URL senza chiave validi fino a 7 giorni. Un URL con utilizzi illimitati può essere memorizzato nella cache pubblica per tutta la sua validità, quindi quando ogni visitatore carica lo stesso URL, le richieste ripetute arrivano gratuitamente dalla CDN. Aggiungarenew: truee un URL salvato continuerà a funzionare oltre la sua validità; un rinnovo conta l'immagine una volta nel mese in cui avviene, e nient'altro se era già stata conteggiata quel mese, quindi la flotta descritta sopra resta al massimo a 8 immagini di veicoli al mese.
Limiti la chiave che genera gli URL al Suo dominio di prenotazione nella dashboard, e un URL copiato su un altro sito risponderà 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 }))
);Passaggio 5: la conferma della prenotazione
L'email di conferma mostra la categoria prenotata, e le email vengono aperte quando il cliente ne ha il tempo. Generi la sua immagine come URL a rinnovo: ttl_seconds al massimo di 7 giorni, renew: true e renew_days esteso oltre la data di riconsegna. Le settimane in cui nessuno apre l'email non costano nulla, e dopo il noleggio l'URL smette di rinnovarsi. Una Idempotency-Key per prenotazione fa sì che un invio ripetuto riproponga il primo URL invece di generarne un secondo, e salvare l'URL nella prenotazione consente a ogni reinvio successivo di riutilizzarlo. Le nostre email del ciclo di vita funzionano così; la storia sulle email spiega il meccanismo e l'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.webpscrive una scheda in un file;car-image url --batch classes.json --renewgenera un batch di URL. - SDK:
client.vehicles({ make, model })per gli id,client.getImage(…)per i file,client.createImageUrls(…)per gli URL. - MCP:
resolve_vehicleecreate_car_image_urlsconsentono a un assistente di preparare una scheda di categoria a partire da "SUV medio, RAV4 o simile". La configurazione è descritta nella pagina MCP.
Domande frequenti
- La scheda può mostrare l'auto esatta che riceverà il cliente?
- No, e non dovrebbe provarci. Una categoria si noleggia come “o similare”, e un render raffigura marca, modello e anno del catalogo, non un’auto del Suo piazzale. Mostri un modello rappresentativo con “o similare” nell’etichetta. Una volta assegnata un’auto specifica al banco, il suo VIN si decodifica gratuitamente nel veicolo di catalogo corrispondente, se preferisce mostrare quel modello.
- Perché le auto nella griglia non sono in scala?
- Perché trim ritaglia ogni render attorno all'auto e fit=contain la fa riempire la scheda, così una compatta e un SUV full-size riempiono le loro schede allo stesso modo. È questo che mantiene ordinata una griglia. Indichi le dimensioni a parole: il nome della categoria, i posti e i bagagli.
- Quanto costa la griglia delle categorie?
- Una flotta di 4 categorie, ciascuna con una scheda e un'immagine principale, corrisponde a 8 immagini di veicoli al mese, ognuna distribuita tutte le volte che serve e in qualsiasi dimensione. Se archivia i file sulla sua CDN finché un piano a pagamento è attivo, vengono conteggiati solo nel mese in cui li recupera, con verifiche gratuite tramite ETag. Se invece serve URL firmati con rinnovo, le stesse immagini vengono conteggiate una volta in ogni mese in cui le pagine vengono aperte.
- Quale colore di carrozzeria dovrebbe usare la griglia?
- Un unico preset per ogni categoria, così le schede appaiono come un insieme coerente. I 15 preset sono white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple e quello predefinito è silver; va bene anche qualsiasi hex, allo stesso prezzo. Il cliente riceve il colore dell’auto presente nel piazzale, che la scheda non ha mai promesso.
- E se il modello di una categoria non è nel catalogo?
- Un veicolo assente risponde 404 con dei suggerimenti: i veicoli più simili a catalogo, ciascuno con il proprio id. Ne usi uno, oppure richieda il veicolo sulla bacheca pubblica delle richieste. Il catalogo è open source.