Car Image API

Cazuri de utilizare · Licitații

Imagini auto pentru anunțurile de licitație

Listați loturile de licitație înainte de sosirea fotografiilor, fiecare cu o imagine de studio a anului său de model, etichetată ca randare din catalog, prin URL-uri semnate care expiră odată cu vânzarea.

Un ghid de implementare scris pe baza comportamentului documentat al API-ului; nu numește niciun client. Publicat pe .

Problema: vânzarea începe înainte să existe fotografiile

Un catalog de licitație este publicat imediat ce sosesc consignațiile: un VIN, un număr de lot și o dată de vânzare pentru fiecare mașină. Fotografiile vin când mașina ajunge în parc și fotograful ajunge la mașină, ceea ce, pentru o parte din vânzare, se întâmplă după deschiderea licitației. Până atunci, fiecare dintre aceste loturi este o casetă gri lângă un rând de text.

O randare din catalog umple caseta cu anul de model corect. Totuși, o licitație este exact locul unde o randare nu trebuie să treacă niciodată drept mașina: ofertanții evaluează starea, iar o randare nu arată nimic din ea, pentru că nu înfățișează niciun vehicul fizic anume. Tot ce urmează decurge din respectarea ambelor idei în același timp.

Cum arată integrarea

  • O randare per lot pornind de la VIN-ul său, afișată doar până sosesc fotografiile proprii ale lotului.
  • Un selector din catalog pentru loturile al căror VIN nu poate fi decodat.
  • O etichetă pe imagine: „Randare din catalog, nu acest lot”.
  • Un singur URL per lot, generat o singură dată sub un Idempotency-Key, valabil pe toată durata licitației.

Pasul 1: de la VIN-ul lotului la un id de vehicul

GET /api/v1/vin/{vin} este gratuit. Când catalogul conține vehiculul, răspunsul include data.vehicle.id, ID-ul stabil de stocat pe lot; echiparea, caroseria și motorul decodate rămân în textul lotului. Catalogul acoperă perioada de la 1990 până la 2027, astfel încât stocul mai vechi al unei licitații se randează la fel ca cel mai nou. Ghidul pentru asigurări parcurge o decodare câmp cu câmp, iar documentația VIN acoperă VIN-urile parțiale și erorile.

Decodare la preluarea lotului
# 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'

Pasul 2: nu aveți un VIN decodabil? Alegeți vehiculul din catalog

Unele loturi sosesc fără un VIN care poate fi decodat: un vehicul fabricat pentru altă piață, un VIN tastat greșit de sursă, o fișă de consignație cu un an, o marcă și un model și nimic altceva. Adăugați în formularul de consignație trei liste derulante alimentate de GET /api/v1/vehicles, care este gratuit și public: ?year= listează mărcile care au un model în acel an, iar ?year=&makeId= listează modelele acelei mărci, fiecare cu id-ul vehiculului pentru acel an de model.

Anul, apoi marca, apoi modelul
# 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 (prescurtat)
{
  "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"
      },
      "…"
    ]
  }
}

Același catalog este pachetul deschis @meterapp/vehicle-db, așa că listele derulante pot funcționa și offline, pe baza aceleiași liste. În ambele cazuri, lotul ajunge să conțină același tip de id ca un VIN decodat, iar nimic din aval nu mai scrie de mână numele unei mașini.

Când sosește deodată o listă întreagă de consignație, POST /api/v1/vehicles/check citește până la 2.000 intrări per apel, fiecare așa cum apare scrisă în listă și cu numărul lotului ca ref, și răspunde pentru fiecare: o potrivire cu id-ul de stocat, sugestii, nicio potrivire sau un rând invalid. Nimic nu este randat și nimic nu este taxat; detaliile se găsesc în documentația pentru vehicule.

Pasul 3: etichetați randarea drept randare

Puneți eticheta pe imaginea în sine, acolo unde se oprește privirea licitantului, și în textul alternativ, nu doar în descrierea de dedesubt. Starea, kilometrajul, daunele, dotările și culoarea reală a mașinii își au locul în textul lotului și, odată ce există, în fotografii. Când sosesc fotografiile, randarea dispare.

Imaginea lotului până sosesc fotografiile
<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>

Pasul 4: un URL per lot, generat o singură dată

Emiteți URL-ul lotului la preluare cu POST /api/v1/image-urls și un Idempotency-Key format din licitație și lot, din litere, cifre, ., _, : și -. URL-ul contorizează imaginea sa ca imagine de vehicul a lunii când este emis, așa că fără cheie o preluare reîncercată ar emite un al doilea URL. Cu o cheie:

  • Aceeași cheie cu același corp, în decurs de 24 ore, reia primul răspuns, inclusiv același URL, cu Idempotent-Replayed: true și fără o a doua taxare.
  • Aceeași cheie cu un corp diferit returnează 422, iar o reîncercare care o depășește pe prima cerere returnează 409 cu Retry-After. Așadar, fixați tot conținutul corpului, inclusiv durata de valabilitate, la crearea lotului și stocați-l împreună cu lotul.
  • Salvați și URL-ul în lot: cheia protejează reîncercările, iar URL-ul salvat este cel pe care îl citesc paginile pe tot restul licitației.

Un catalog întreg importat dintr-odată poate genera URL-uri pentru până la 50 loturi per apel, cu o cheie pentru fiecare pachet; fiecare URL din răspuns indică vehiculul și opțiunile pentru care a fost generat.

URL-ul lotului 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

Pasul 5: potriviți durata de valabilitate a URL-ului cu licitația

ttl_seconds acceptă până la 604800 (7 zile); o valoare mai mare este redusă la această limită. Pentru o licitație care se încheie în aceeași săptămână, setați-l la timpul rămas până la închidere. Astfel, imaginea provizorie nu mai funcționează odată cu încheierea licitării, iar după aceea URL-ul răspunde cu 403.

  • O licitație cu durată limitată mai lungă de 7 zile: emiteți URL-ul cu renew: true, ttl_seconds la valoarea maximă și renew_days acoperind durata licitației. O reînnoire contorizează imaginea o singură dată în luna în care are loc și nimic în plus dacă a fost deja contorizată în acea lună; săptămânile în care nimeni nu deschide lotul nu se contorizează deloc, iar reînnoirea se oprește la renews_until.
  • Păstrați max_uses la 0, valoarea implicită: un URL nelimitat poate fi stocat public în cache pe toată durata sa de valabilitate, în timp ce unul limitat este private, no-store și trimite fiecare încărcare către serverul de origine.
  • Restricționați cheia de generare la domeniile licitației dumneavoastră din panoul de control: o imagine de lot copiată pe alt site răspunde cu 403.
Preluarea loturilor cu SDK-ul 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

Alegeți planul după mărimea licitației

Fiecare lot reprezintă o imagine de vehicul — vehiculul său, în vopseaua și vederea sa —, cu excepția cazului în care două loturi au toate trei elementele în comun, iar fiecare plan include un număr de imagini de vehicul pe lună: Free 100, Pro 2.500 și Business 10.000; Enterprise se negociază. O imagine deja contorizată luna aceasta este întotdeauna servită, iar o cerere grupată care ar depăși alocarea este refuzată integral, înainte de a se contoriza ceva, cu planul și alocarea incluse în răspuns. Dimensionați planul în funcție de loturile pe care le listați într-o lună. Povestea marketplace explică cum să eșalonați un import mare în limitele de rată și de randare.

Întrebări frecvente

Poate rămâne randarea afișată după ce sosesc fotografiile lotului?
Înlocuiți-o. Randarea ține locul anului modelului, iar un ofertant nu ar trebui să se întrebe niciodată care imagine este mașina scoasă la vânzare. Dacă o pagină o păstrează ca referință, eticheta rămâne alături de ea.
Ce se întâmplă cu URL-ul după vânzare?
Expiră la sfârșitul duratei de valabilitate sau când un URL cu reînnoire ajunge la capătul perioadei de reînnoire, după care răspunde cu 403. Până atunci, lotul are propriile fotografii sau un rezultat, iar arhiva vânzării ar trebui să afișeze fotografiile. Revocarea cheii care a generat URL-urile le invalidează pe toate deodată.
O reîncercare a primit răspunsul 422. De ce?
Același Idempotency-Key a revenit cu un corp diferit. Cauza obișnuită este o durată de valabilitate recalculată după ceas în momentul reîncercării. Stabiliți durata de valabilitate la crearea lotului și stocați-o; astfel, reîncercarea trimite același corp și redă primul răspuns.
Poate randarea să redea culoarea lotului?
Da: parametrul color acceptă oricare dintre numele predefinite sau un cod hex, astfel încât imaginea poate corespunde culorii din fișa de consignație, fără cost suplimentar. Rămâne totuși modelul în acea culoare, nu lotul, așa că eticheta rămâne.
Cât costă o licitație cu 400 loturi?
400 de imagini de vehicul din lună: 1 imagine de vehicul pe lot când URL-ul acestuia este emis, iar o emitere reîncercată nu mai contorizează nimic. Fiecare încărcare pe durata de valabilitate a URL-ului este gratuită. Planurile includ Free 100, Pro 2.500 și Business 10.000 imagini de vehicul pe lună, iar loturile care au în comun vehiculul, vopseaua și vederea se contorizează o singură dată.

Citiți în continuare

Poveste de client · Marketplace-uri autoCum să puneți o imagine auto de studio pe fiecare anunț din marketplaceUn anunț are nevoie de o imagine înainte ca vânzătorul să încarce una. Platformele de tip marketplace completează un întreg catalog cu un singur unghi și o singură culoare de vopsea, apoi păstrează aceeași structură a cererii pentru fiecare an-model nou.