Car Image API

Bruksområder · Bilutleie

Bilbilder for sider om leiebilparken

Vis alle leiebilklasser på samme måte: én representativ modell per klasse, identisk utsnitt med trim, padding og fit, én navngitt lakkfarge og URL-er som kan hurtigbufres.

En byggeguide skrevet ut fra API-ets dokumenterte virkemåte; den nevner ingen kunder. Publisert .

Problemet: man leier en klasse, ikke en bil

En leiebilkunde bestiller en klasse – en kompaktbil, en mellomstor SUV, en flerbruksbil – og kjører av gårde i den bilen i klassen som står på plassen. Bestillingssiden trenger likevel et bilde for hver klasse, og vanlig praksis er én representativ modell med ordene «eller lignende».

Slike bilder kommer gjerne fra der hvert enkelt tilfeldigvis var å finne: et pressebilde her, et forhandlerbilde der, ulike vinkler, ulike bakgrunner og biler som fyller kortene sine ulikt. Et rutenett satt sammen på den måten ser sammensatt ut. Det en flåteside trenger, er det motsatte: hver klasse vist på samme måte, slik at det eneste som endrer seg fra kort til kort, er bilen.

Slik ser integrasjonen ut

  • Én representativ modell per klasse, lagret som en kjøretøy-ID fra katalogen, med «eller tilsvarende» i etiketten og aldri i bildet.
  • Én forespørselsform for alle kort: samme visning, boks, tilpasning, beskjæring, utfylling, lakk, bakgrunn og format.
  • Maks to bilder per klasse: kortet i rutenettet og toppbildet på klassesiden.
  • Bufret, fordi rutenettet er likt for alle besøkende: filer på CDN-en din, eller signerte URL-er som lages én gang og gjenbrukes.

Trinn 1: velg en representativ modell per klasse, etter id

Velg modellen hver klasse selges under, og slå opp gjeldende årsmodell. GET /api/v1/vehicles?make=&model= er gratis og offentlig og lister opp alle årganger av én modell, hver med den stabile kjøretøy-ID-en du skal lagre; POST /api/v1/images/resolve gjør det samme ut fra en frase som «2026 toyota rav4».

ID-en for ett modellår
# one model's years, each with its vehicle id (free, public)
curl -s "https://carimage.dev/api/v1/vehicles?make=toyota&model=rav4" | jq -c '.data.vehicles[] | select(.year == 2026)'
# {"year":2026,"id":"veh_e5w75c93f6cvk"}
fleet.ts
// One representative model per class: its current model year, by catalog id.
// "or similar" lives in the label; the picture never promises the car on the lot.
export const CLASS_IMAGES = {
  compact:        { vehicle: "veh_fy7r2yvwt4p1v", label: "Toyota Corolla or similar" },    // 2026 Toyota Corolla
  "midsize-suv":  { vehicle: "veh_e5w75c93f6cvk", label: "Toyota RAV4 or similar" },       // 2026 Toyota RAV4
  "fullsize-suv": { vehicle: "veh_9mzh9ejqjye43", label: "Chevrolet Tahoe or similar" },   // 2026 Chevrolet Tahoe
  minivan:        { vehicle: "veh_9jck7rrybf35p", label: "Chrysler Pacifica or similar" }, // 2026 Chrysler Pacifica
};

Id-ene endres aldri, så denne tilordningen er det eneste stedet en flåteendring berører: når mellomklassen bytter til en annen modell, eller til neste årsmodell, bytter du ut én id, og alle kort, toppbilder og e-poster som leser tilordningen, følger etter.

Trinn 2: én forespørselsform for alle klasser

De 9 kameravinklene har identisk utsnitt for hvert kjøretøy i katalogen, og det er det som får et rutenett til å stå på linje. Resten av kortet er en håndfull parametere som bestemmes én gang:

  • view=side for kortene: alle bilene vender samme vei på samme grunnlinje. Hver vinkel fra venstre side har en -right-tvilling (side-right), slik at kortene kan vende inn mot oppsettet. Klassesiden bruker front-3-4, hovedvinkelen.
  • w=640&h=320&fit=contain: nøyaktig 640×320 for hver klasse, med hele bilen synlig. X-Image-Width og X-Image-Height i svaret bekrefter lerretet.
  • trim=1&padding=6: Beskjær til bilen før den tilpasses, med 6 % av den lengste siden som marg, slik at en Corolla og en Tahoe fyller kortene sine likt i stedet for å sveve i den kvadratiske kilderammen.
  • background=f4f4f4 legger kortet flatt på rutenettets egen grå farge. Utelat den for å beholde den transparente bakgrunnen og la kortets farge skinne gjennom.
  • format=webp for lagrede filer; format=auto på signerte URL-er, som leverer WebP eller PNG til hver nettleser.
Et kort og et toppbilde for én klasse
# the class card: the same box, view, crop, paint and backdrop for every class
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/images/car?vehicle=veh_e5w75c93f6cvk&view=side&color=white&w=640&h=320&fit=contain&trim=1&padding=6&background=f4f4f4&format=webp" \
  -o midsize-suv-card.webp

# the class page's hero: the three-quarter view, the full width the API delivers
curl --fail-with-body -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/images/car?vehicle=veh_e5w75c93f6cvk&view=front-3-4&color=white&w=1024&format=webp" \
  -o midsize-suv-hero.webp

Trinn 3: én navngitt lakkfarge for hele rutenettet

De 15 forhåndsvalgene er navngitte lakker: white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple. Standard er silver, og grey tolkes som gray. Velg én for hver klasse, slik at kortene fremstår som et sett; white vises ovenfor. Hvert forhåndsvalg har sin egen lakkprøve i stedet for CSS-fargen med samme navn (red er #b3151b), og hver lakk, også en hex-verdi, er en omfarging av én klargjort visning, så hver lakk er ett kjøretøybilde.

Trinn 4: cache filene eller URL-ene

Klasserutenettet er likt for alle besøkende, så det bør koste nesten ingenting per besøk. Det finnes to måter å oppnå det på:

  • Lagre filene. Hent hvert kortbilde og hovedbilde én gang med GET /api/v1/images/car, og server dem fra ditt eget CDN som alle andre ressurser. En betalt plan tillater kopier på dine egne servere for å betjene produktet ditt så lenge planen er aktiv (slett dem innen 30 dager etter at den avsluttes, eller kjøp en Image Pack for å beholde et sett for alltid). Ta vare på hver fils ETag: En nattlig kontroll med If-None-Match får svaret 304 og koster ingenting. For flåten ovenfor blir det 8 kjøretøybilder i måneden, som kan gjenbrukes så ofte som nødvendig.
  • Eller lag signerte URL-er én gang og gjenbruk dem. POST /api/v1/image-urls tar opptil 50 bilder per kall og returnerer URL-er uten nøkkel som varer i opptil 7 dager. En URL med ubegrenset antall bruk kan bufres offentlig i hele levetiden, så når alle besøkende laster den samme URL-en, kommer gjentatte visninger gratis fra CDN-et. Legg til renew: true, så fortsetter en lagret URL å virke etter levetiden; en fornyelse teller bildet én gang i måneden den skjer, og ingenting mer hvis det allerede er telt den måneden, så flåten ovenfor holder seg på høyst 8 kjøretøybilder i måneden.

Begrens nøkkelen som genererer URL-ene, til bestillingsdomenet ditt i dashbordet, så svarer en URL som kopieres til et annet nettsted, med 403.

Rutenettets URL-er, opprettet én gang, med TypeScript-SDK-en
import { CarImageClient, type ImageParams } from "@meterapp/car-image-sdk";
import { CLASS_IMAGES } from "./fleet";

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

// Framed once, for every class.
const card = (vehicle: string): ImageParams => ({
  vehicle, view: "side", color: "white", width: 640, height: 320,
  fit: "contain", trim: true, padding: 6, background: "#f4f4f4", format: "auto",
});
const hero = (vehicle: string): ImageParams => ({ vehicle, view: "front-3-4", color: "white", width: 1024, format: "auto" });

// Every visitor sees the same grid: mint the URLs once and serve the stored ones.
// renew keeps each URL working past its 7-day lifetime, one credit per image
// for each further week in which it is loaded.
const classes = Object.entries(CLASS_IMAGES);
const { data } = await client.createImageUrls(
  classes.flatMap(([, entry]) => [card(entry.vehicle), hero(entry.vehicle)]),
  { ttlSeconds: 604800, renew: true, idempotencyKey: "class-grid-2026-10" }
);
await saveClassImages(
  classes.map(([key], index) => ({ key, card: data[2 * index].url, hero: data[2 * index + 1].url, renewsUntil: data[2 * index].renews_until }))
);

Trinn 5: bestillingsbekreftelsen

Bekreftelses-e-posten viser klassen som ble bestilt, og e-poster åpnes når leietakeren får tid til dem. Lag bildet som en fornyende URL: ttl_seconds på maksimumet på 7 dager, renew: true og renew_days som varer forbi returdatoen. Uker der ingen åpner e-posten, koster ingenting, og etter leieperioden slutter URL-en å fornye seg. En Idempotency-Key per bestilling gjør at et nytt sendeforsøk gjenbruker den første URL-en i stedet for å lage en ny, og når URL-en lagres på bestillingen, kan alle senere utsendelser bruke den på nytt. Våre egne livssyklus-e-poster fungerer slik; e-posthistorien beskriver mekanismen og HTML-en.

En selvfornyende URL for én bekreftelse
// The booking confirmation: opened today, again at the counter, maybe never.
const { data: [classImage] } = await client.createImageUrls(card(booking.classVehicle), {
  ttlSeconds: 604800,
  renew: true,
  // A week past the return date, and no renewals after it (365 days at most).
  renewDays: Math.min(daysUntil(booking.returnDate) + 7, 365),
  // A retried send replays the first URL instead of minting a second one.
  idempotencyKey: `booking:${booking.id}:class`,
});
booking.classImageUrl = classImage.url; // later resends reuse it

CLI, SDK og MCP

  • CLI: npx @meterapp/car-image get --vehicle veh_… --view side --width 640 --height 320 --fit contain --trim --padding 6 --out card.webp skriver et kort til en fil; car-image url --batch classes.json --renew genererer en serie URL-er.
  • SDK: client.vehicles({ make, model }) for id-ene, client.getImage(…) for filer, client.createImageUrls(…) for URL-er.
  • MCP: resolve_vehicle og create_car_image_urls lar en assistent lage et utkast til et klassekort fra "mellomstor SUV, RAV4 eller tilsvarende". Oppsett er beskrevet på MCP-siden.

Ofte stilte spørsmål

Kan kortet vise nøyaktig den bilen leietakeren får?
Nei, og det bør det heller ikke prøve på. En bilklasse leies ut som «eller tilsvarende», og en rendering viser et merke, en modell og en årsmodell fra katalogen, ikke en bil på parkeringsplassen din. Vis én representativ modell med «eller tilsvarende» i etiketten. Når en bestemt bil er tildelt ved skranken, kan VIN-nummeret dens dekodes gratis til kjøretøyet i katalogen hvis du heller vil vise den modellen.
Hvorfor er ikke bilene i rutenettet i riktig målestokk?
Fordi trim beskjærer hver rendering til bilen og fit=contain fyller kortet med den, så en kompaktbil og en fullstørrelses-SUV fyller kortene sine på samme måte. Det er det som holder rutenettet ryddig. Oppgi størrelsen i ord: klassenavnet, antall seter og antall bagger.
Hva koster klasserutenettet?
En bilpark på 4 klasser med ett kort og ett hovedbilde hver utgjør 8 kjøretøybilder i måneden, hvert levert så ofte det trengs i hvilken som helst størrelse. Lagrer du filene på CDN-et ditt mens et betalt abonnement er aktivt, telles de bare i måneden du henter dem, med gratis nye kontroller via ETag. Bruker du i stedet fornyende signerte URL-er, telles de samme bildene én gang i hver måned sidene åpnes.
Hvilken lakkfarge bør rutenettet bruke?
Én forhåndsdefinert farge for alle klasser, slik at kortene fremstår som et sett. De 15 forhåndsdefinerte fargene er white, black, gray, silver, blue, red, green, brown, beige, tan, orange, yellow, gold, burgundy, purple, og standardfargen er silver. Enhver hex-kode fungerer også, til samme pris. Leietakeren får fargen bilen på plassen har, noe kortet aldri lovet.
Hva om modellen for en bilklasse ikke finnes i katalogen?
Et kjøretøy som ikke finnes, gir 404 med forslag: de nærmeste kjøretøyene i katalogen, hver med sin id. Bruk ett av dem, eller be om kjøretøyet på den offentlige forespørselstavlen. Katalogen er åpen kildekode.

Les videre

Kundehistorie · UtviklerverktøySlik bygger du inn bilbilder i e-post med signerte URL-er som aldri slutter å virkeVåre egne livssyklus-e-poster bygger inn hver kundes nøyaktige første rendering som en levende signert URL som fornyer seg selv i ett år. Slik fungerer det, og slik kopierer du det.