Car Image API

Toepassingen · Veilingen

Autoafbeeldingen voor veilingkavels

Zet veilingkavels online voordat de foto's er zijn, elk met een studioafbeelding van het modeljaar, gelabeld als catalogusrender, via ondertekende URL's die met de veiling verlopen.

Een implementatiegids op basis van het gedocumenteerde gedrag van de API; er wordt geen klant genoemd. Gepubliceerd op .

Het probleem: de veiling is live voordat de foto's er zijn

Een veilingcatalogus gaat online zodra de inzendingen binnen zijn: per auto een VIN, een kavelnummer en een veilingdatum. De foto's komen pas als de auto op het terrein staat en de fotograaf bij de auto is, wat voor een deel van een veiling pas gebeurt nadat het bieden is geopend. Tot die tijd is elk van die kavels een grijs vak naast een regel tekst.

Een catalogusrender vult het vak met het juiste modeljaar. Maar een veiling is ook precies de plek waar een render nooit voor de echte auto mag doorgaan: bieders prijzen de staat in, en een render toont die niet, omdat hij geen specifiek fysiek voertuig afbeeldt. Alles hieronder volgt uit het tegelijk vasthouden aan beide.

Hoe de integratie eruitziet

  • Een render per kavel op basis van het VIN, alleen getoond tot de eigen foto's van de kavel binnen zijn.
  • Een cataloguskiezer voor de kavels waarvan het VIN niet kan worden gedecodeerd.
  • Een label op de afbeelding: "Catalogusrender, niet deze kavel".
  • Eén URL per kavel, één keer aangemaakt onder een Idempotency-Key, geldig zolang de veiling loopt.

Stap 1: van de VIN van de kavel naar een voertuig-id

GET /api/v1/vin/{vin} is gratis. Als de catalogus het voertuig bevat, bevat het antwoord data.vehicle.id, de stabiele id om bij de kavel op te slaan; de gedecodeerde uitvoering, carrosserie en motor blijven in de tekst van de kavel. De catalogus loopt van 1990 tot 2027, dus de oudere voorraad van een veiling wordt net zo gerenderd als de nieuwste. De verzekeringsgids loopt een decodering veld voor veld door, en de VIN-documentatie behandelt gedeeltelijke VIN's en fouten.

Decoderen bij binnenkomst
# 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'

Stap 2: geen decodeerbaar VIN? Kies het voertuig uit de catalogus

Sommige kavels komen binnen zonder VIN die te decoderen is: een voertuig gebouwd voor een andere markt, een VIN die de bron verkeerd heeft ingetypt, een inbrengformulier met een jaar, een merk en een model en verder niets. Geef het inbrengformulier drie keuzelijsten die gevuld worden door GET /api/v1/vehicles, dat gratis en openbaar is: ?year= toont de merken met een model in dat jaar, en ?year=&makeId= toont de modellen van dat merk, elk met het voertuig-id van dat modeljaar.

Bouwjaar, dan merk, dan model
# 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 (ingekort)
{
  "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"
      },
      "…"
    ]
  }
}

Dezelfde catalogus is het open pakket @meterapp/vehicle-db, zodat de keuzelijsten ook offline met precies dezelfde lijst kunnen werken. Hoe dan ook krijgt de kavel hetzelfde soort id als een gedecodeerd VIN, en verderop in de keten hoeft niets een autonaam uit te schrijven.

Als een volledige inzendlijst in één keer binnenkomt, leest POST /api/v1/vehicles/check tot 2.000 regels per aanroep, elk zoals de lijst het spelt en met het kavelnummer als ref, en beantwoordt elke regel: een match met de id om op te slaan, suggesties, geen resultaat of een ongeldige regel. Er wordt niets gerenderd en niets in rekening gebracht; de vehicles-documentatie bevat de details.

Stap 3: label de render als render

Plaats het label op de afbeelding zelf, waar het oog van een bieder valt, en in de alt-tekst, niet alleen in de beschrijving eronder. Staat, kilometerstand, schade, opties en de lak van de auto horen in de kaveltekst en, zodra ze er zijn, op de foto's. Zodra de foto's binnen zijn, verdwijnt de render.

De afbeelding van de kavel tot de foto's binnen zijn
<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>

Stap 4: één URL per kavel, één keer aangemaakt

Maak de URL van de kavel bij de intake aan met POST /api/v1/image-urls en een Idempotency-Key samengesteld uit de veiling en de kavel, met letters, cijfers, ., _, : en -. De URL telt de afbeelding als voertuigafbeelding van de maand op het moment dat hij wordt aangemaakt, dus zonder sleutel zou een herhaalde intake een tweede URL aanmaken. Met een sleutel:

  • Dezelfde sleutel met dezelfde body binnen 24 uur herhaalt het eerste antwoord, inclusief dezelfde URL, met Idempotent-Replayed: true en zonder dat er opnieuw wordt afgerekend.
  • Dezelfde sleutel met een andere body geeft een 422, en een nieuwe poging die het eerste verzoek inhaalt, geeft een 409 met een Retry-After. Leg daarom alles in de body vast, de levensduur inbegrepen, wanneer het kavel wordt aangemaakt, en sla het op bij het kavel.
  • Sla de URL ook op bij het kavel: de sleutel beveiligt nieuwe pogingen, en de opgeslagen URL is wat de pagina's de rest van de veiling gebruiken.

Bij het in één keer importeren van een hele catalogus kunt u tot 50 kavels per aanroep aanmaken, met één sleutel per batch; elke URL in het antwoord vermeldt het voertuig en de opties waarvoor hij is aangemaakt.

URL van kavel 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

Stap 5: stem de levensduur van de URL af op de veiling

ttl_seconds loopt tot 604800 (7 dagen); een langere waarde wordt daartoe ingekort. Stel het voor een veiling die binnen de week sluit in op de resterende tijd tot de sluiting. De placeholder werkt dan niet meer zodra het bieden stopt, en daarna geeft de URL 403 terug.

  • Een veiling met tijdslimiet die langer duurt dan 7 dagen: maak de URL aan met renew: true, ttl_seconds op het maximum en renew_days voor de duur van de veiling. Een verlenging telt de afbeelding één keer in de maand waarin die valt, en niets extra als de afbeelding die maand al was geteld; weken waarin niemand de kavel opent, tellen niet mee, en de verlenging stopt bij renews_until.
  • Houd max_uses op 0, de standaardwaarde: een onbeperkte URL is gedurende zijn hele levensduur openbaar cachebaar, terwijl een begrensde URL private, no-store is en elke keer laden naar de origin stuurt.
  • Beperk de sleutel waarmee u URL's aanmaakt tot de domeinen van uw veiling in het dashboard: een kavelafbeelding die naar een andere site is gekopieerd, geeft 403 terug.
Kavels invoeren met de TypeScript SDK
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

Kies een plan dat past bij de omvang van de veiling

Elke kavel is één voertuigafbeelding, het voertuig in zijn lak en weergave, tenzij twee kavels alle drie gemeen hebben, en elk abonnement bevat een aantal voertuigafbeeldingen per maand: Free 100, Pro 2.500 en Business 10.000; over Enterprise wordt onderhandeld. Een afbeelding die deze maand al is geteld, wordt altijd geleverd, en een batch die het tegoed zou overschrijden, wordt in zijn geheel geweigerd voordat er iets wordt geteld, met het abonnement en het tegoed in het antwoord. Stem het abonnement af op het aantal kavels dat u per maand aanbiedt. Het verhaal over marktplaatsen beschrijft hoe u een grote import doseert binnen de rate- en renderlimieten.

Veelgestelde vragen

Kan de render blijven staan zodra de foto's van de kavel binnen zijn?
Vervang hem. De render is een tijdelijke afbeelding voor het bouwjaar, en een bieder mag zich nooit hoeven afvragen welke afbeelding de auto is die wordt verkocht. Als een pagina hem ter referentie bewaart, gaat het label mee.
Wat gebeurt er met de URL na de veiling?
De URL verloopt wanneer de geldigheidsduur afloopt, of wanneer een zichzelf vernieuwende URL het einde van zijn vernieuwingsperiode bereikt, en geeft dan 403 terug. Tegen die tijd heeft de kavel eigen foto's of een uitslag, en het archief van de veiling hoort de foto's te tonen. Als u de sleutel intrekt waarmee de URL's zijn aangemaakt, vervallen ze allemaal tegelijk.
Een nieuwe poging gaf 422 terug. Waarom?
Dezelfde Idempotency-Key kwam terug met een andere body. De gebruikelijke oorzaak is een geldigheidsduur die op het moment van de nieuwe poging opnieuw op basis van de klok wordt berekend. Leg de geldigheidsduur vast wanneer de kavel wordt aangemaakt en sla die op; dan verstuurt de nieuwe poging dezelfde body en krijgt u het eerste antwoord opnieuw terug.
Kan de render de lakkleur van de kavel tonen?
Ja: color accepteert elk van de vooraf ingestelde namen of een hexwaarde, zodat de afbeelding zonder extra kosten kan overeenkomen met de lak op het inbrengformulier. Het blijft het model in die lakkleur, niet de kavel zelf, dus het label blijft staan.
Wat kost een veiling van 400 kavels?
400 voertuigafbeeldingen van de maand: 1 voertuigafbeelding per kavel wanneer de URL ervan wordt aangemaakt, en een herhaalde aanmaak telt niets extra. Elke keer laden binnen de geldigheidsduur van de URL is gratis. Abonnementen bevatten per maand: Free 100, Pro 2.500 en Business 10.000 voertuigafbeeldingen, en kavels met hetzelfde voertuig, dezelfde lak en hetzelfde aanzicht tellen één keer.

Lees verder

Klantverhaal · AutomarktplaatsenZo zet u bij elke marktplaatsadvertentie een studioafbeelding van de autoEen advertentie heeft een afbeelding nodig voordat de verkoper er zelf een uploadt. Marktplaatsen vullen een hele catalogus aan met één hoek en één lakkleur, en houden daarna dezelfde opbouw van het verzoek aan voor elk nieuw modeljaar.