Car Image API

Clienti · Siti di annunci e cataloghi per l'acquisto di auto

Come inserire un'immagine da studio dell'auto in ogni annuncio del marketplace

Come i siti di annunci e i cataloghi per l'acquisto di auto generano un'immagine principale per ogni anno modello su scala di catalogo: ID dei veicoli, inquadratura, ritmo delle richieste, caching e codice.

Il problema: un annuncio ha bisogno di un’immagine prima che il venditore ne carichi una

Un sito di annunci o un catalogo per l'acquisto di auto vive o muore con la sua griglia. Ogni scheda ha bisogno di un'immagine dal momento in cui l'annuncio esiste, e la foto del venditore arriva più tardi, se arriva, da un'angolazione casuale in un vialetto qualsiasi. La fotografia stock ha il problema opposto: esiste uno scatto stampa con licenza per le auto più popolari negli anni più popolari, con l'angolazione e lo sfondo scelti dal costruttore, e per nient'altro. Un catalogo che copre dal 1990 all'anno modello corrente ha decine di migliaia di lacune.

Ciò che vogliono i team che costruiscono questi siti è noioso nel senso migliore del termine: un'immagine da studio per anno modello, la stessa angolazione e la stessa vernice per tutte, trasparente così da adattarsi a qualsiasi sfondo della scheda, abbastanza leggera da essere servita diecimila volte al giorno.

Com'è fatta un'integrazione di catalogo

Le integrazioni di catalogo oggi attive sull’API hanno tutte la stessa struttura, che si tratti di un sito di annunci che popola le proprie inserzioni, di un’app per l’acquisto di auto che genera le schede di confronto o di un’app mobile che mostra un’immagine principale per ogni veicolo:

  • Un backfill, poi un flusso costante. Migliaia di render in poche ore per coprire il catalogo, poi una manciata al giorno man mano che arrivano nuovi anni modello e nuove richieste.
  • Un'angolazione, un colore o una breve palette. La maggior parte sceglie front-3-4 o side in argento o bianco. Un catalogo di shopping che permette all'utente di scegliere il colore genera alcuni colori predefiniti per veicolo; ognuno è un'immagine di veicolo in più, non una nuova pipeline.
  • WebP in un riquadro fisso. Da 512 a 1024 pixel di larghezza, consegnati esattamente nel riquadro usato dalla scheda, così il front end non deve mai ritagliare né aggiungere bande vuote.
  • Archiviati per id veicolo. I render finiscono nell'object store o nella CDN del team, oppure le pagine caricano URL firmati; in entrambi i casi la chiave è l'id stabile veh_… del catalogo, non una stringa marca-modello-anno.

Il resto di questa pagina descrive quella pipeline, passo dopo passo, con il codice. Presuppone una chiave API con lo scope images:read e un piano dimensionato sul catalogo (vedere le FAQ).

Passo 1: elencare il catalogo per id, mai in base alla grafia

Il problema più comune nella creazione di un catalogo non è il rendering, è l'ortografia. Una build che genera le stringhe di marca e modello da un altro database può spendere la maggior parte delle richieste in 404 vehicle_not_found: gratuite, ma ognuna è un round trip sprecato, e il risultato è una griglia piena di buchi. La soluzione è lasciare che sia il catalogo a dirle cosa esiste. GET /api/v1/vehicles è gratuito, non richiede una chiave e ogni modello restituito ha un id veicolo stabile (veh_ più 13 caratteri) che non cambia mai tra un deploy e l'altro né tra le release del catalogo. Salvi quell'id nell'annuncio e lo usi per il render.

Elencare un anno modello
# every make with a 2024 model year (free, no key)
curl -s "https://carimage.dev/api/v1/vehicles?year=2024"

# every 2024 model of one make, each with the id you will store
curl -s "https://carimage.dev/api/v1/vehicles?year=2024&makeId=584"
200 OK (estratto)
{
  "data": {
    "year": 2024,
    "make_id": 584,
    "models": [
      {
        "name": "718",
        "slug": "718",
        "vehicle_type": "Passenger Car",
        "id": "veh_b4bf090fyb53k"
      },
      {
        "name": "911",
        "slug": "911",
        "vehicle_type": "Passenger Car",
        "id": "veh_78qtwrgh37bkr"
      }
    ]
  }
}

?make=porsche&model=911 elenca ogni anno di un modello con un ID per anno, e ?q= esegue una ricerca a testo libero quando un venditore digita un nome. Lo stesso catalogo è pubblicato come pacchetto open @meterapp/vehicle-db, quindi menu a tendina e convalida possono funzionare offline sull'identico elenco. In ogni caso, alla fine di questo passaggio avrà un elenco di ID, e nessun passaggio a valle dovrà mai più scrivere il nome di un'auto.

Gli annunci che indicano già le loro auto con la grafia di un altro database vengono mappati con una sola chiamata: POST /api/v1/vehicles/check ne legge fino a 2000 come farebbe un render e risponde a ciascuno con il relativo ID veicolo, con i veicoli reali più vicini quando il catalogo non contiene quell'auto, oppure con un mancato riscontro da saltare in ogni vista e colore. car-image check listings.csv --out checked.csv riscrive gli ID nel file. È gratuito e sostituisce la scoperta delle lacune un 404 alla volta.

Passaggio 2: un’unica struttura di richiesta per ogni inserzione

Definisca la scheda una volta e la codifichi nella query string. Tutto ciò che segue vehicle= qui sotto è una scelta di inquadratura da fare una sola volta per l’intero catalogo:

Un’immagine per l’inserzione
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/images/car?vehicle=veh_78qtwrgh37bkr&view=front-3-4&color=silver&w=800&h=600&fit=contain&trim=1&padding=8&format=webp" \
  -o veh_78qtwrgh37bkr.webp
  • w=800&h=600&fit=contain restituisce esattamente 800×600 con l'auto interamente visibile e un margine trasparente attorno, così ogni scheda ha la stessa area. fit=cover invece riempie il riquadro e ritaglia al centro.
  • trim=1&padding=8 ritaglia l’immagine sul contorno dell’auto prima di adattarla, con un margine pari all’8% del lato più lungo, così una Suburban e una Miata riempiono il riquadro allo stesso modo invece di fluttuare nell’inquadratura originale.
  • color=silver è il valore predefinito e il neutro più sicuro; qualsiasi dei 15 preset o qualsiasi codice hex conta allo stesso modo, un’immagine di veicolo.
  • format=webp è la codifica più compatta con canale alfa senza perdita. Quando un browser carica direttamente l'URL (URL firmati, passaggio 4), format=auto negozia WebP o PNG per ogni client.

La risposta include ETag, X-Image-Source (cache o generated) e X-Vehicle-Id, il veicolo del catalogo servito. Conservi l'ETag insieme al file: una richiesta successiva con If-None-Match risponde 304 e non costa nulla; è così che una risincronizzazione notturna resta gratuita.

Passaggio 3: scaglionare il backfill entro i limiti

Tre limiti determinano un backfill, e ognuno si segnala negli header invece di fallire in silenzio:

  • Richieste al minuto. 120 per chiave sui piani Free e Pro, 600 su Business, 1200 su Enterprise, più un limite per account su tutte le chiavi. Ogni risposta autenticata include RateLimit-Remaining; una risposta 429 include Retry-After. Da quattro a otto richieste contemporanee sono più che sufficienti.
  • Nuove viste dei veicoli. La prima richiesta per una vista di un veicolo che non abbiamo ancora preparato richiede un po' di tempo, mentre la prepariamo affinché possa essere mostrata in qualsiasi colore; ogni richiesta successiva, in qualsiasi colore, viene servita dalla cache. La preparazione di nuove viste attinge alla quota dell'account del budget giornaliero di rendering (2% su Free, 10% su Pro, 25% su Business, 50% su Enterprise). Superata la quota, un nuovo render risponde 429 con code: account_generation_cap e reset_at (mezzanotte UTC), non viene addebitato nulla e le immagini in cache continuano a essere servite. Un backfill di grandi dimensioni richiede qualche sera, non una sola.
  • Immagini di veicoli al mese. Free ne include 100, Pro 2500, Business 10.000; per Enterprise la quota si negozia. Oltre questa soglia, una richiesta per un’immagine non ancora conteggiata questo mese risponde 402 (plan_image_limit) e non conteggia nulla; un’immagine già conteggiata questo mese viene sempre servita, così una griglia live non si interrompe mai.

Gli errori di rendering (502) restituiscono automaticamente la relativa immagine di veicolo, le richieste simultanee per la stessa nuova variante condividono un unico render e un semplice GET può essere ripetuto in sicurezza. L'SDK ripete automaticamente le richieste con 429 e 503, rispettando Retry-After, e non ripete mai un 402.

Un backfill riprendibile con l’SDK TypeScript
import { CarImageClient, CarImageError } from "@meterapp/car-image-sdk";

const client = new CarImageClient({ apiKey: process.env.CAR_IMAGE_API_KEY });

// One make, one model year: the ids are what you store and what you render by.
const { data } = await client.vehicles({ year: 2024, makeId: 584 });
const queue = data.models.flatMap((model) => (model.id ? [model.id] : []));

// Four in flight stays well inside 120 requests a minute, and a cold render
// that takes a few seconds never holds up the rest of the batch.
await Promise.all(
  Array.from({ length: 4 }, async () => {
    for (let id = queue.shift(); id; id = queue.shift()) {
      try {
        const image = await client.getImage({
          vehicle: id, view: "front-3-4", color: "silver",
          width: 800, height: 600, fit: "contain", trim: true, padding: 8, format: "webp",
        });
        await store(id, image.bytes, image.etag); // your object store or CDN, keyed by vehicle id
      } catch (error) {
        // 429 and 503 were already retried with Retry-After; a 404 is a vehicle to request, not a failure.
        if (error instanceof CarImageError && error.status === 404) continue;
        throw error;
      }
    }
  })
);

Passaggio 4: distribuirla dalla propria CDN o tramite URL firmati

Ci sono due buoni modi per mostrare l'immagine a un acquirente, e i cataloghi realizzati li usano entrambi:

  • Memorizzi i byte. Scriva ogni render nel Suo object store o CDN sotto il relativo id veicolo e lo serva come qualsiasi altro asset. È la soluzione giusta per una griglia visualizzata milioni di volte: nessuna chiamata a noi per ogni caricamento, e la licenza di un piano a pagamento copre le copie che conserva per servire il Suo prodotto.
  • Generi URL firmati. POST /api/v1/image-urls accetta fino a cinquanta immagini per chiamata, conta l'immagine di ogni URL come immagine di veicolo del mese quando viene generato e restituisce URL senza chiave che il browser carica direttamente. Imposti ttl_seconds fino a sette giorni; aggiunga renew: true per le pagine di annunci che restano online più a lungo (un rinnovo conta l'immagine una volta nel mese in cui avviene, e nulla di più se era già stata conteggiata in quel mese). Limiti la chiave alle origini del Suo sito nella dashboard: un URL copiato altrove risponderà 403.

Invii un Idempotency-Key per ogni pagina di annunci quando genera URL in blocco: una chiamata ripetuta con la stessa chiave e lo stesso body riproduce la prima risposta e non conteggia nulla di nuovo.

listings.json — cinquanta alla volta, inquadrati come nel passaggio 2
{
  "images": [
    {
      "vehicle": "veh_78qtwrgh37bkr",
      "view": "front-3-4",
      "color": "silver",
      "width": 800,
      "height": 600,
      "fit": "contain",
      "trim": true,
      "padding": 8,
      "format": "auto"
    },
    {
      "vehicle": "veh_b4bf090fyb53k",
      "view": "front-3-4",
      "color": "silver",
      "width": 800,
      "height": 600,
      "fit": "contain",
      "trim": true,
      "padding": 8,
      "format": "auto"
    }
  ]
}

Quando un veicolo non è nel catalogo

Prima si cerca: GET /api/v1/vehicles?q= trova un modello per nome, prefisso o corrispondenza approssimativa, e POST /api/v1/images/resolve trasforma una frase libera in parametri esatti con un livello di confidenza su cui basarsi. Ciò che manca ancora va sulla bacheca delle richieste: POST /api/v1/requests crea la richiesta oppure, se ne esiste già una aperta per la stessa marca, modello e anno, aggiunge un voto invece di duplicarla. Il catalogo stesso è open source e le aggiunte arrivano a tutti i clienti.

CLI, SDK e MCP

L'intera pipeline si esegue dalla CLI senza scrivere codice, ed è così che sono stati popolati diversi cataloghi presenti sull'API:

npx @meterapp/car-image
# One file per vehicle id. Re-running skips what exists, so a stopped backfill resumes.
while read -r id; do
  [ -f "cdn/$id.webp" ] || npx @meterapp/car-image get --vehicle "$id" \
      --view front-3-4 --color silver --width 800 --height 600 --fit contain \
      --trim --padding 8 --format webp --out "cdn/$id.webp"
done < vehicle-ids.txt

# Or fifty signed URLs in one call, for a page of listings the browser loads itself.
npx @meterapp/car-image url --batch listings.json --ttl 604800 --renew --json
  • SDK: client.vehicles({ year, makeId }) per elencare, client.getImage({ vehicle, … }) per generare il render, client.createImageUrls(…) per lotti di URL firmati. Consulti la documentazione sulle immagini per tutti i parametri.
  • MCP: un assistente collegato a https://carimage.dev/api/mcp ha lo stesso catalogo (search_vehicles, resolve_vehicle) e gli stessi render (get_car_image, create_car_image_urls): è lo strumento giusto per un curatore che aggiunge un veicolo a mano e quello sbagliato per un backfill di migliaia di veicoli. Per quello usi la CLI o l'SDK e riservi l'assistente ai casi rimasti. La configurazione è nella pagina MCP.

Domande frequenti

Quale angolazione usare per un annuncio?
front-3-4 è l'angolazione predefinita e la classica inquadratura principale, con il muso a sinistra. Ogni angolazione del lato sinistro dell'auto ha un gemello -right (front-3-4-right, side-right, rear-3-4-right), così una scheda può essere rivolta verso l'interno del layout anziché verso l'esterno. Ne scelga una e la mantenga: la coerenza tra gli annunci è gran parte del valore.
Quanto costa un catalogo di 20.000 annunci?
20.000 immagini di veicoli al mese se ogni annuncio mostra un veicolo in un colore e una vista, ciascuna distribuita tutte le volte necessarie in qualsiasi dimensione; gli annunci che condividono veicolo, colore e vista sono un’unica immagine, e la riverifica con If-None-Match è gratuita. Pro include 2500 immagini di veicoli al mese e Business 10.000, quindi un catalogo di queste dimensioni richiede Enterprise, oppure un Image Pack una tantum da conservare e ospitare in autonomia per sempre. Un backfill oltre la quota risponde 402 e non conteggia nulla.
Possiamo conservare i file sulla nostra CDN?
Sì. Un piano a pagamento concede in licenza i render per l'uso all'interno del suo prodotto, comprese le copie sui suoi server o sulla sua CDN, senza attribuzione, finché il piano è attivo; entro 30 giorni dalla sua scadenza, le copie archiviate vengono eliminate (le immagini di un Image Pack possono essere conservate per sempre). La licenza non consente di offrirle come libreria, feed o dataset a sé stanti. È un piano attivo a generare i render dell'anno modello successivo.
Cosa succede quando nel catalogo arriva un nuovo anno modello?
Il catalogo @meterapp/vehicle-db viene aggiornato man mano che le fonti pubblicano, e gli id esistenti non cambiano mai. Elenchi il nuovo anno, generi i render per gli id che non ha ancora e lasci invariato il resto. Le richieste includono un ETag; una richiesta ripetuta con If-None-Match risponde 304 e non costa nulla.
Perché alcune delle nostre stringhe di marca e modello restituiscono 404?
Perché sono stati scritti secondo un altro database. Il catalogo accetta nomi, slug e molte varianti di badge e carrozzeria, ma una stringa mai vista restituisce un 404 vehicle_not_found (gratuito, ma è una richiesta sprecata). Enumeri il catalogo e memorizzi i suoi id invece di tradurre le Sue stringhe, poi cerchi o risolva quelle rimaste fuori.