Car Image API

Casi d'uso · Aste

Immagini di auto per annunci d'asta

Pubblichi i lotti all'asta prima che arrivino le foto, ognuno con un'immagine in studio del suo anno modello indicata come render di catalogo, tramite URL firmati che scadono con la vendita.

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.

Decodifica all'arrivo del lotto
# 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.

Anno, poi marca, poi 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"
200 OK (estratto)
{
  "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.

L'immagine del lotto finché non arrivano le sue foto
<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: true e senza un secondo addebito.
  • La stessa chiave con un body diverso restituisce un 422, e un nuovo tentativo che supera la prima richiesta restituisce un 409 con un Retry-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.

URL del lotto 117
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 charged

Passaggio 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_seconds al massimo e renew_days che 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 a renews_until.
  • Mantenga max_uses a 0, il valore predefinito: un URL illimitato può essere memorizzato pubblicamente nella cache per tutta la sua durata, mentre uno con limite è private, no-store e 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.
Acquisizione con l'SDK TypeScript
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 arrive

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

Continui a leggere

Storia di un cliente · Marketplace automobilisticiCome inserire un'immagine da studio dell'auto in ogni annuncio del marketplaceUn annuncio ha bisogno di un'immagine prima che il venditore ne carichi una. I marketplace popolano un intero catalogo con una sola angolazione e una sola vernice, poi mantengono la stessa struttura di richiesta per ogni nuovo anno modello.