Problemet: posten har et VIN måneder før den har et bilde
En lagerpost i et CRM, et ERP eller et forhandlersystem (DMS) begynner livet som et VIN, et lagernummer og en pris. Bildet kommer når fotografen kommer, og for noen biler kommer det aldri: en bil under transport, en innbyttebil som fortsatt klargjøres, en import med et modellnavn som ikke matcher noe i DMS-ens bildefeed, en bil fra 1990-tallet som ingen har lisensiert et pressebilde av. Alle skjermer som viser posten – selgerens liste, innkjøperens takst, kundens tilbud – viser en grå plassholder i stedet.
Forhandler- og importverktøyene på API-et fyller den plassholderen ut fra det posten allerede har. Har den et VIN, er bildet én gratis dekoding unna. Har den bare en linje i en lagerliste, kommer fritekst-resolve dit. Uansett ender posten opp med en stabil kjøretøy-ID, og hver skjerm rendrer samme bil på samme måte.
Slik ser en forhandlerintegrasjon ut
- Dekod ved registrering. VIN-en dekodes én gang, når oppføringen opprettes, og katalogens kjøretøy-ID lagres ved siden av den. Ingenting senere i flyten staver et merke eller en modell.
- Én visning for listen, én for detaljsiden. En rett
sidei en bred ramme for lagerlister,front-3-4for detaljsiden og tilbudet. - Mange årganger. Importbiler og bruktbiler går tilbake til 1990-tallet, og de renderes på samme måte som nyankomne biler: katalogen spenner fra 1990 til gjeldende årsmodell, inkludert modeller for det japanske hjemmemarkedet.
- Signerte URL-er i appen. CRM-et kjører i nettleseren, så det laster nøkkelfrie signerte URL-er utstedt av serveren, opptil femti per kall, og fornyer dem for poster som lever lenger enn en uke.
Trinn 1: dekod VIN-en – gratis
GET /api/v1/vin/{vin} koster ingenting og krever bare en API-nøkkel. Det returnerer dekodet årsmodell, merke, modell, utstyrsnivå, karosseriklasse, motor og alle andre attributter NHTSAs vPIC-data kjenner til, og, når katalogen har kjøretøyet, et vehicle-objekt med stabil ID og en ferdig image_path. Delvise VIN-er fungerer også: minst fem tegn, * for hver ukjent posisjon, pluss et valgfritt year-hint.
curl -s -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/vin/1HGCM82633A004352"{
"data": {
"vin": "1HGCM82633A004352",
"valid": true,
"year": 2003,
"make": "Honda",
"model": "Accord",
"trim": "EX-V6",
"body_class": "Coupe",
"vehicle": {
"id": "veh_3qfyk22gfhsx3",
"make": "Honda",
"model": "Accord",
"year": 2003,
"image_path": "/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3"
}
},
"request_id": "req_01j9x…"
}trim og body_class som tekst på oppføringen og vis dem ved siden av bildet, i stedet for å hevde at bildet viser dem. En VIN med feil i kontrollsifferet dekodes likevel, med valid: false og feilen oppført, så en feilskrevet lagerliste er ikke en blindvei.Trinn 1b: når alt du har, er en linje på en lagerliste
Importbiler kommer ofte som et regneark: et årstall, et merke, et modellnavn stavet slik auksjonshuset nå enn gjorde det, en grad- eller utstyrskode. POST /api/v1/images/resolve er gratis og deterministisk: Det trekker ut ord for årstall, farge og visning fra frasen, søker i katalogen med resten og returnerer eksakte parametere med en konfidensverdi du kan handle ut fra.
curl -s -X POST https://carimage.dev/api/v1/images/resolve \
-H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "2019 toyota voxy zs side"}'{
"data": {
"params": {
"vehicle_id": "veh_9w0nvw7jphp6r",
"make": "toyota",
"model": "voxy",
"year": 2019,
"view": "side",
"color": "silver"
},
"display": {
"make_name": "TOYOTA",
"model_name": "VOXY"
},
"confidence": "low",
"image_path": "/api/v1/images/car?make=toyota&model=voxy&year=2019&view=side&color=silver"
},
"request_id": "req_01j9x…"
}Kjøretøyet er riktig (2019 Toyota Voxy), men konfidensen er low, fordi «ZS» er en utstyrsgrad katalogen ikke kjenner, og den måtte matches utenom den. I en batchimport bør du behandle high som ferdig, og legge medium og low frem for et menneske sammen med candidates-listen. Når arket allerede har årsmodell og merke i egne kolonner, send dem som feltene year og make, og la bare modellen stå i query; da blir treffet mye renere. En frase uten kjøretøyord gir 400, og et merke uten matchende modell gir 404 som lister opp merkets årsmodeller, slik at du kan be om modellen.
Trinn 2: lagre kjøretøy-ID-en på posten
Uansett hvilken vei du kom dit, lagrer du vehicle.id (eller params.vehicle_id) på lagerposten som en vanlig strengkolonne. Den er deterministisk og permanent: samme kjøretøy har samme ID ved hver utrulling og etter hver katalogutgivelse, så den er trygg å bruke som fremmednøkkel. Fra da av er hver bildeforespørsel vehicle=veh_…, som ikke kan staves feil, og et merke som omdøpes av en produsent eller omklassifiseres av en kilde, ødelegger aldri en lagret URL.
Trinn 3: én visning for listen, én for detaljsiden
Lagerlister er brede og lave, så den rette sidevisningen i en 2:1-boks er det vanlige valget: alle enhetene vender samme vei og står på samme grunnlinje. trim=1&padding=6 beskjærer til bilen før tilpasning, så en Hilux og en Yaris fyller raden på samme måte; fit=contain holder lerretet på nøyaktig 640×320 med transparente marger. Detaljsiden bruker front-3-4 i 1024, og de to deler hurtigbuffer: en lakkfarge du ikke har angitt, blir sølv på begge.
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3&view=side&w=640&h=320&fit=contain&trim=1&padding=6&format=webp" \
-o stock-4471.webpTrinn 4: vis det i CRM-et via signerte URL-er
CRM-et kjører i en nettleser, og en nettleser må aldri ha API-nøkkelen. Når en skjerm viser en side med lagerbiler, lager serveren én signert URL per post med POST /api/v1/image-urls (opptil femti per kall; bildet til hver URL telles som et kjøretøybilde for måneden), og siden laster dem som et hvilket som helst bilde. To innstillinger er viktige for en post som blir liggende på lager i flere måneder:
ttl_seconds: 604800medrenew: true: URL-en fortsetter å fungere etter TTL-en på sju dager, og en fornyelse teller bildet én gang i måneden den faller i, og ikke noe mer hvis det allerede er telt den måneden. Måneder der ingen ser på bilen, teller ingenting.- En
Idempotency-Keyper side i synkroniseringen: en gjentatt forespørsel spiller av det første svaret og oppretter ingenting to ganger.
Begrens nøkkelen som genererer URL-ene, til CRM-ets opprinnelse i dashbordet, så svarer en URL som lekker til et annet nettsted, med 403. Tilbakekaller du nøkkelen, blir alle URL-ene den har generert, ugyldige. Hvis abonnementets kjøretøybilder for måneden er brukt opp, svarer en fornyelse med 402, og den samme URL-en fungerer igjen når kvoten nullstilles eller abonnementet oppgraderes. Hele livssyklusen finner du i dokumentasjonen for signerte URL-er.
import { CarImageClient } from "@meterapp/car-image-sdk";
const client = new CarImageClient({ apiKey: process.env.CAR_IMAGE_API_KEY });
// On intake: VIN in, vehicle id on the record. Free.
const { data: decoded } = await client.decodeVin(stock.vin);
if (decoded.vehicle) {
stock.vehicleId = decoded.vehicle.id; // veh_…, permanent; the record never spells a car again
stock.trim = decoded.trim; // shown next to the image, never claimed by it
}
// When the CRM draws the stock list: one signed URL per record, up to fifty per call.
// The browser loads them; the key never leaves the server.
const { data: urls } = await client.createImageUrls(
page.map((row) => ({
vehicle: row.vehicleId, view: "side",
width: 640, height: 320, fit: "contain", trim: true, padding: 6, format: "auto",
})),
{ ttlSeconds: 604_800, renew: true, renewDays: 365, idempotencyKey: `stock-list:${syncRunId}:${pageIndex}` }
);CLI, SDK og MCP
# decode for free; the output names the vehicle id and a ready-to-run image command
npx @meterapp/car-image vin 1HGCM82633A004352
npx @meterapp/car-image vin 1HGCM82633A004352 --json | jq -r .data.vehicle.id
# a partial VIN from a faded door sticker: at least five characters, * for each unknown position
npx @meterapp/car-image vin "1HGCM826*3A" --year 2003
# the list image for one record
npx @meterapp/car-image get --vehicle veh_3qfyk22gfhsx3 --view side --width 640 --height 320 --fit contain --trim --padding 6 --format webp --out stock-4471.webp- SDK:
client.decodeVin(vin, { year? }),client.resolve(query),client.getImage({ vehicle, … })ogclient.createImageUrls(…), som ovenfor. - MCP:
decode_vin,resolve_vehicle,get_car_imageogcreate_car_image_urlser med i kjerneverktøysettet, så en assistent med lagersystemet i kontekst kan svare på «bilde av lagernummer 4471» ut fra VIN-et i registeret. Oppsettet står på MCP-siden; dekoderens felt og feil står i VIN-dokumentasjonen.
Ofte stilte spørsmål
- Hva koster det å ha et bilde på hver bil i lagerbeholdningen?
- VIN-dekodingen er gratis. Hvert kjøretøy i hver lakk og visning er ett kjøretøybilde, som telles én gang i måneden uansett hvor ofte det vises og i hvilken størrelse; å sjekke det på nytt med If-None-Match er gratis. En signert URL teller bildet sitt når den lages, og med renew: true én gang til i hver senere måned den åpnes. En forhandlergruppe med noen tusen biler på lager viser noen tusen kjøretøybilder i måneden, så tilpass planen til lagerbeholdningen som vises.
- VIN-en dekodes, men vehicle er null. Hva nå?
- Dekoderen kjente merke, modell og år, men katalogen har ingen oppføring for den kombinasjonen: en tilhenger, enkelte nyttekjøretøychassis, en modellbetegnelse kildene ikke har registrert ennå. Vis de dekodede feltene, søk i katalogen med GET /api/v1/vehicles?q= i tilfelle stavemåten er annerledes, og be om kjøretøyet på forespørselstavlen; POST /api/v1/requests gir en stemme til en åpen forespørsel i stedet for å lage et duplikat.
- Dekker VIN-dekoding importbiler og kjøretøy som aldri er solgt i USA?
- Dekoderen bruker NHTSAs vPIC-data, så en VIN fra en produsent som registrerer seg hos NHTSA, dekodes fullstendig. Et kjøretøy som aldri er sertifisert for USA, dekodes ofte til en produsent og et årstall uten modell, og noen dekodes ikke i det hele tatt. For slike biler kan du heller slå opp fra vognkortet: selve katalogen er verdensomspennende, fra 1990, og modeller for det japanske hjemmemarkedet, som Toyota Voxy, er med.
- Viser renderingen utstyrsnivået på oppføringen?
- Nei. Katalogen bruker merke, modell og årsmodell som nøkkel, så en EX-V6 coupé og en LX sedan gjengis som den samme 2003 Accord. Behold trim og body_class fra dekodingen som tekst ved siden av bildet, og beskriv aldri renderingen som den konkrete bilen.
- Kan forhandlerens nettsted bruke de samme URL-ene som CRM-systemet?
- Generer dem fra en nøkkel der nettstedet står blant de tillatte opprinnelsene, så svarer en URL som en nettleser laster fra et annet nettsted, med 403 origin_not_allowed. Lastinger uten Referer, for eksempel fra en e-postklient, slipper gjennom. CRM-et og nettstedet kan dele én nøkkel og ett sett URL-er, eller bruke hver sin nøkkel slik at hver av dem kan tilbakekalles for seg.