Dealer & VIN tools
Decode a VIN for free, then follow image_path to the render.
/api/v1/vin/{vin}Decode, then follow image_path
A stock record has a VIN long before it has a photo. Decoding one costs nothing and needs only your key: the answer carries the year, make, model, trim and body, and data.vehicle names the catalog vehicle with its stable id and a ready-made image_path. Add the view and the size your record shows to that path and the picture is one credit.
# decode: free
curl --fail-with-body \
-H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/vin/1HGCM82633A004352"
# → data.vehicle.image_path: "/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3"
# the picture for the stock record: 1 credit
curl --fail-with-body \
-H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
"https://carimage.dev/api/v1/images/car?vehicle=veh_3qfyk22gfhsx3&view=front-3-4&w=640&h=480&trim=1&format=webp" \
--output stock-8812.webpPartial VINs and cars the catalog lacks
A stock sheet often carries the first characters only. Send * for each unknown position (at least five known ones) and ?year= when you know the model year; the serial number never changes what the car is (partial VINs). A 200 with vehicle: null means the decode worked but the catalog does not carry that make, model and year: resolve it by name or ask the person, and never substitute a body style or a nearby model. A 404 means NHTSA has no record of the pattern, which a car built for another market can be.
One view per stock record
Store data.vehicle.id on the record next to the VIN, decode once rather than on every page view, and render the same view and size for every car so the inventory grid reads as one set. A CRM that runs in a browser cannot hold the key: mint signed URLs where the key lives and put those on the record instead.
trim and body_class next to the image rather than claiming the render depicts them.The long version, from the stock sheet to the CRM: the dealer software story.