Una guida pratica scritta a partire dal comportamento documentato dell'API; non nomina alcun cliente. Pubblicato il .
Il problema: la vendita è attiva prima delle foto
Un catalogo d'asta viene pubblicato non appena arrivano i conferimenti: un VIN, un numero di lotto e una data di vendita per ogni auto. Le foto arrivano quando l'auto raggiunge il piazzale e il fotografo raggiunge l'auto, il che, per una parte della vendita, avviene dopo l'apertura delle offerte. Fino ad allora ciascuno di quei lotti è un riquadro grigio accanto a una riga di testo.
Un render di catalogo riempie lo spazio con l'anno modello giusto. Ma un'asta è anche proprio il luogo in cui un render non deve mai essere scambiato per l'auto: gli offerenti valutano le condizioni, e un render non ne mostra nessuna, perché non raffigura alcun veicolo fisico specifico. Tutto ciò che segue nasce dal tenere presenti entrambe le cose.
Come si presenta l'integrazione
- Un render per lotto dal suo VIN, mostrato solo finché non arrivano le foto del lotto.
- Un selettore dal catalogo per i lotti il cui VIN non si decodifica.
- Un'etichetta sull'immagine: "Render da catalogo, non questo lotto".
- Un URL per lotto, generato una sola volta con un
Idempotency-Key, valido per tutta la durata della vendita.
Passaggio 1: dal VIN del lotto a un ID veicolo
GET /api/v1/vin/{vin} è gratuito. Quando il catalogo contiene il veicolo, la risposta include data.vehicle.id, l'id stabile da memorizzare sul lotto; allestimento, carrozzeria e motore decodificati restano nel testo del lotto. Il catalogo copre gli anni dal 1990 al 2027, quindi i veicoli più datati di un'asta vengono renderizzati come i più recenti. La guida per le assicurazioni illustra una decodifica campo per campo e la documentazione VIN tratta VIN parziali ed errori.
# the lot's VIN to the vehicle id the lot stores (free); nothing printed means no catalog match
npx @meterapp/car-image vin "$LOT_VIN" --json | jq -r '.data.vehicle.id // empty'Passo 2: nessun VIN decodificabile? Scegliere il veicolo dal catalogo
Alcuni lotti arrivano senza un VIN decodificabile: un veicolo costruito per un altro mercato, un VIN digitato male dalla fonte, una scheda di conferimento con anno, marca e modello e nient'altro. Doti il modulo di conferimento di tre menu a tendina alimentati da GET /api/v1/vehicles, gratuito e pubblico: ?year= elenca le marche con un modello in quell'anno e ?year=&makeId= elenca i modelli di quella marca, ciascuno con l'id del veicolo per quell'anno modello.
# every make with a 2006 model year (free, public)
curl -s "https://carimage.dev/api/v1/vehicles?year=2006"
# {"data":{"year":2006,"makes":[…,{"id":476,"name":"DODGE","slug":"dodge"},…]},…}
# that make's 2006 models, each with the id of its 2006 model year
curl -s "https://carimage.dev/api/v1/vehicles?year=2006&makeId=476"{
"data": {
"year": 2006,
"make_id": 476,
"models": [
{
"name": "Caliber",
"slug": "caliber",
"vehicle_type": "Passenger Car",
"id": "veh_294vq81yq0d3y"
},
{
"name": "Charger",
"slug": "charger",
"vehicle_type": "Passenger Car",
"id": "veh_96j8z47jqfd4r"
},
"…"
]
}
}Lo stesso catalogo è il pacchetto open @meterapp/vehicle-db, quindi i menu a tendina possono funzionare anche offline sulla stessa identica lista. In entrambi i casi il lotto contiene lo stesso tipo di id di un VIN decodificato e nessun componente a valle deve scrivere per esteso il nome di un'auto.
Quando arriva un'intera distinta di conferimento in una volta, POST /api/v1/vehicles/check legge fino a 2000 voci per chiamata, ciascuna scritta come nella distinta e con il numero di lotto come ref, e risponde a ognuna: una corrispondenza con l'id da salvare, suggerimenti, nessun risultato o una riga non valida. Non viene generato alcun render e non viene addebitato nulla; i dettagli sono nella documentazione dei veicoli.
Passo 3: indicare che il render è un render
Inserisca l'etichetta sull'immagine stessa, dove cade lo sguardo dell'offerente, e nel testo alternativo, non solo nella descrizione sottostante. Condizioni, chilometraggio, danni, optional e il colore effettivo dell'auto vanno nel testo del lotto e, quando ci sono, nelle foto. Quando arrivano le foto, il render va rimosso.
<figure class="lot-image">
<img src="https://carimage.dev/api/v1/delivery/eyJhbGciOi…" width="800" height="450"
alt="Catalog render of a 2006 Dodge Charger, not a photo of lot 117">
<span class="lot-image__badge">Catalog render, not this lot</span>
</figure>
<p>Photos of this lot are on their way. Condition, mileage and damage are in the report.</p>Passaggio 4: un URL per lotto, generato una sola volta
Generi l'URL del lotto al momento dell'acquisizione con POST /api/v1/image-urls e una Idempotency-Key ricavata dall'asta e dal lotto, con lettere, cifre, ., _, : e -. L'URL conta la sua immagine come immagine di veicolo del mese quando viene generato, quindi senza una chiave un'acquisizione ripetuta genererebbe un secondo URL. Con una chiave:
- La stessa chiave con lo stesso corpo della richiesta entro 24 ore ripete la prima risposta, URL compreso, con
Idempotent-Replayed: truee senza un secondo addebito. - La stessa chiave con un body diverso restituisce un
422, e un nuovo tentativo che supera la prima richiesta restituisce un409con unRetry-After. Quindi fissi tutto nel body, durata inclusa, quando il lotto viene creato, e lo memorizzi insieme al lotto. - Salvi l'URL anche sul lotto: la chiave protegge i tentativi ripetuti e l'URL salvato è ciò che le pagine leggono per il resto dell'asta.
Un intero catalogo importato in una volta può generare fino a 50 lotti per chiamata, con una chiave per batch; ogni URL nella risposta riporta il veicolo e le opzioni per cui è stato generato.
curl --fail-with-body -X POST https://carimage.dev/api/v1/image-urls \
-H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: sale-2026-10-14:lot-117" \
-d '{"images":[{"vehicle":"veh_96j8z47jqfd4r","view":"side","width":800,"height":450,"fit":"contain","trim":true,"padding":6,"format":"auto"}],"ttl_seconds":259200}'
# run it again: the same URL comes back with Idempotent-Replayed: true, and nothing more is chargedPassaggio 5: adeguare la durata dell’URL alla vendita
ttl_seconds arriva fino a 604800 (7 giorni); un valore più lungo viene ridotto a quel limite. Per una vendita che si chiude entro la settimana, lo imposti sul tempo rimanente fino alla chiusura. Il segnaposto smette così di funzionare quando terminano le offerte, e da quel momento l’URL risponde 403.
- Una vendita a tempo più lunga di 7 giorni: generi l'URL con
renew: true,ttl_secondsal massimo erenew_daysche copra la durata della vendita. Un rinnovo conta l'immagine una volta nel mese in cui avviene, e nient'altro se era già stata conteggiata quel mese; le settimane in cui nessuno apre il lotto non contano nulla, e il rinnovo si ferma arenews_until. - Mantenga
max_usesa 0, il valore predefinito: un URL illimitato può essere memorizzato pubblicamente nella cache per tutta la sua durata, mentre uno con limite èprivate, no-storee invia ogni caricamento all’origine. - Limiti la chiave di generazione ai domini della sua asta nella dashboard: un'immagine di un lotto copiata su un altro sito risponde
403.
import { CarImageClient, type ImageParams } from "@meterapp/car-image-sdk";
const client = new CarImageClient({ apiKey: process.env.CAR_IMAGE_API_KEY });
const lotImage = (vehicle: string): ImageParams => ({
vehicle, view: "side", width: 800, height: 450, fit: "contain", trim: true, padding: 6, format: "auto",
});
// How long the lot's URL lives, decided once from the sale's close.
function lifetime(closesAt: Date) {
const seconds = secondsUntil(closesAt);
return seconds <= 604800
? { ttlSeconds: Math.max(seconds, 60) } // closes within the week
: { ttlSeconds: 604800, renew: true, renewDays: Math.min(daysUntil(closesAt), 365) }; // a longer timed sale
}
// At intake, once per lot. The lifetime is stored with the lot, so a retry sends
// the same body and replays the first answer instead of minting a second URL.
lot.imageLifetime ??= lifetime(sale.closesAt);
const { data: [placeholder] } = await client.createImageUrls(lotImage(lot.vehicleId), {
...lot.imageLifetime,
idempotencyKey: `${sale.id}:lot-${lot.number}`,
});
lot.placeholderUrl = placeholder.url; // replaced by the lot's own photos when they arriveUn piano adatto alle dimensioni dell'asta
Ogni lotto è un'immagine di veicolo, cioè il suo veicolo nella sua vernice e vista, a meno che due lotti non condividano tutti e tre gli elementi, e ogni piano include un certo numero di immagini di veicoli al mese: Free 100, Pro 2500 e Business 10.000; Enterprise è negoziato. Un'immagine già conteggiata questo mese viene sempre servita, e un batch che supererebbe la quota viene rifiutato per intero, prima che venga conteggiato qualsiasi cosa, con il piano e la quota indicati nella risposta. Dimensioni il piano in base ai lotti che pubblica in un mese. La storia del marketplace spiega come distribuire una grande importazione entro i limiti di frequenza e di rendering.
Domande frequenti
- Il render può restare online quando arrivano le foto del lotto?
- Lo sostituisca. Il render è un segnaposto per l'anno modello e un offerente non dovrebbe mai chiedersi quale immagine sia l'auto in vendita. Se una pagina lo mantiene come riferimento, l'etichetta deve restare con esso.
- Cosa succede all'URL dopo la vendita?
- Scade quando termina la sua durata, o quando un URL a rinnovo automatico raggiunge la fine del rinnovo, e a quel punto risponde 403. Per allora il lotto ha le sue foto o un esito, e l'archivio della vendita dovrebbe mostrare le foto. Revocando la chiave che ha generato gli URL, li si disattiva tutti in una volta.
- Un nuovo tentativo ha restituito 422. Perché?
- Lo stesso header Idempotency-Key è tornato con un corpo diverso. La causa abituale è una durata ricalcolata dall'orologio al momento del nuovo tentativo. Fissi la durata quando viene creato il lotto e la memorizzi: così il nuovo tentativo invia lo stesso corpo e restituisce di nuovo la prima risposta.
- Il render può mostrare il colore della carrozzeria del lotto?
- Sì: color accetta uno qualsiasi dei nomi predefiniti o un hex, così l'immagine può corrispondere al colore indicato nella scheda di conferimento senza costi aggiuntivi. Resta comunque il modello in quel colore, non il lotto, quindi la dicitura rimane.
- Quanto costa un'asta di 400 lotti?
- 400 immagini di veicoli del mese: 1 immagine di veicolo per lotto quando ne viene generato l’URL, e un nuovo tentativo di generazione non conta nulla in più. Ogni caricamento entro la durata dell’URL è gratuito. I piani includono Free 100, Pro 2500 e Business 10.000 immagini di veicoli al mese, e i lotti che condividono veicolo, vernice e vista contano una volta sola.