Car Image API

กรณีการใช้งาน · การประมูล

ภาพรถสำหรับรายการประมูล

ลงรายการล็อตประมูลได้ก่อนที่ภาพถ่ายจะมาถึง โดยแต่ละล็อตมีภาพสตูดิโอของรุ่นปีนั้นซึ่งระบุว่าเป็นภาพเรนเดอร์จากแคตตาล็อก ผ่าน signed URL ที่หมดอายุพร้อมกับการประมูล

คู่มือการสร้างที่เขียนจากพฤติกรรมของ API ตามเอกสาร โดยไม่ได้ระบุชื่อลูกค้ารายใด เผยแพร่เมื่อ

ปัญหา: การขายเริ่มขึ้นก่อนที่รูปถ่ายจะพร้อม

แคตตาล็อกการประมูลจะเผยแพร่ทันทีที่รถฝากขายเข้ามาครบ โดยมี VIN หมายเลขล็อต และวันประมูลของรถแต่ละคัน ส่วนภาพถ่ายจะมาเมื่อรถถึงลานจอดและช่างภาพไปถึงรถ ซึ่งสำหรับรถบางส่วนในการประมูลนั้นเกิดขึ้นหลังจากเปิดให้เสนอราคาแล้ว ระหว่างนั้นแต่ละล็อตจึงเป็นเพียงกล่องสีเทาข้างข้อความหนึ่งบรรทัด

ภาพเรนเดอร์จากแค็ตตาล็อกช่วยเติมช่องภาพด้วยรุ่นปีที่ถูกต้อง แต่การประมูลก็เป็นที่ที่ภาพเรนเดอร์ต้องไม่ถูกเข้าใจว่าเป็นรถคันจริงเด็ดขาด ผู้ประมูลประเมินราคาจากสภาพรถ และภาพเรนเดอร์ไม่ได้แสดงสภาพใดๆ เลย เพราะภาพนั้นไม่ได้แสดงถึงยานพาหนะคันใดคันหนึ่งที่มีอยู่จริง ทุกอย่างด้านล่างนี้มาจากการยึดถือทั้งสองข้อนี้ไปพร้อมกัน

การผสานรวมมีลักษณะอย่างไร

  • ภาพเรนเดอร์หนึ่งภาพต่อหนึ่งล็อตจาก VIN แสดงเฉพาะจนกว่ารูปถ่ายจริงของล็อตจะมาถึง
  • ตัวเลือกรถจากแคตตาล็อก สำหรับล็อตที่ถอดรหัส VIN ไม่ได้
  • ป้ายกำกับบนรูปภาพ: "ภาพเรนเดอร์จากแค็ตตาล็อก ไม่ใช่รถในล็อตนี้"
  • หนึ่ง URL ต่อหนึ่งล็อต สร้างเพียงครั้งเดียว ภายใต้ Idempotency-Key และใช้งานได้ตลอดช่วงการขาย

ขั้นตอนที่ 1: จาก VIN ของล็อตสู่ id ของรถ

GET /api/v1/vin/{vin} ใช้งานได้ฟรี เมื่อแค็ตตาล็อกมีข้อมูลยานพาหนะนั้น ผลลัพธ์จะมี data.vehicle.id ซึ่งเป็น id คงที่สำหรับจัดเก็บไว้กับล็อต ส่วนรุ่นย่อย ตัวถัง และเครื่องยนต์ที่ถอดรหัสได้จะอยู่ในข้อความของล็อต แค็ตตาล็อกครอบคลุมตั้งแต่ 1990 ถึง 2027 รถรุ่นเก่าในการประมูลจึงเรนเดอร์ได้เหมือนรุ่นใหม่ล่าสุด คู่มือประกันภัยอธิบายการถอดรหัสทีละฟิลด์ และเอกสาร VINครอบคลุม VIN ที่ไม่ครบและข้อผิดพลาด

ถอดรหัสตอนรับรถเข้า
# 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'

ขั้นตอนที่ 2: ไม่มี VIN ที่ถอดรหัสได้ใช่ไหม เลือกรถจากแค็ตตาล็อก

บางล็อตมาโดยไม่มี VIN ที่ถอดรหัสได้ เช่น รถที่ผลิตสำหรับตลาดอื่น VIN ที่แหล่งข้อมูลพิมพ์ผิด หรือใบฝากขายที่มีเพียงปี ยี่ห้อ และรุ่น โดยไม่มีข้อมูลอื่น ให้เพิ่มดรอปดาวน์สามรายการในแบบฟอร์มฝากขาย โดยดึงข้อมูลจาก GET /api/v1/vehicles ซึ่งใช้ได้ฟรีและเป็นสาธารณะ: ?year= แสดงรายการยี่ห้อที่มีรุ่นในปีนั้น และ ?year=&makeId= แสดงรายการรุ่นของยี่ห้อนั้น แต่ละรุ่นพร้อม vehicle id ของรุ่นปีนั้น

ปี ตามด้วยยี่ห้อ แล้วจึงเป็นรุ่น
# 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 (แสดงบางส่วน)
{
  "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"
      },
      "…"
    ]
  }
}

แค็ตตาล็อกเดียวกันนี้คือแพ็กเกจโอเพนซอร์ส @meterapp/vehicle-db ดังนั้นดรอปดาวน์จึงทำงานแบบออฟไลน์กับรายการเดียวกันได้ด้วย ไม่ว่าจะใช้วิธีใด ล็อตจะได้ id ชนิดเดียวกับ VIN ที่ถอดรหัสแล้ว และไม่มีขั้นตอนใดถัดไปที่ต้องสะกดชื่อรถเอง

เมื่อได้รับเอกสารรายการรถฝากขายทั้งชุดในคราวเดียว POST /api/v1/vehicles/check จะอ่านได้สูงสุด 2,000 รายการต่อการเรียกหนึ่งครั้ง โดยแต่ละรายการสะกดตามที่เขียนในเอกสารและใช้หมายเลขล็อตเป็น ref แล้วตอบกลับทุกรายการ: รายการที่ตรงกันพร้อม id ที่ควรจัดเก็บ รายการแนะนำ รายการที่ไม่พบ หรือแถวที่ไม่ถูกต้อง โดยไม่มีการเรนเดอร์และไม่มีการเรียกเก็บเงิน ดูรายละเอียดได้ในเอกสาร vehicles

ขั้นตอนที่ 3: ระบุให้ชัดว่าภาพเรนเดอร์เป็นภาพเรนเดอร์

ใส่ป้ายกำกับไว้บนภาพโดยตรงตรงจุดที่สายตาผู้ประมูลมองไป และใส่ในข้อความ alt ด้วย ไม่ใช่แค่ในคำอธิบายด้านล่าง สภาพรถ เลขไมล์ ความเสียหาย อุปกรณ์เสริม และสีจริงของรถควรอยู่ในข้อความของล็อต และในรูปถ่ายเมื่อมีแล้ว เมื่อรูปถ่ายมาถึง ให้นำภาพเรนเดอร์ออก

ภาพของล็อตจนกว่ารูปถ่ายจริงจะมาถึง
<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>

ขั้นตอนที่ 4: หนึ่ง URL ต่อหนึ่งล็อต สร้างเพียงครั้งเดียว

สร้าง URL ของล็อตตอนรับเข้าระบบด้วย POST /api/v1/image-urls และ Idempotency-Key ที่สร้างจากการประมูลและล็อต โดยใช้ตัวอักษร ตัวเลข ., _, : และ - URL จะนับภาพเป็นภาพรถยนต์ของเดือนเมื่อสร้างขึ้น ดังนั้นหากไม่มีคีย์ การรับเข้าที่ลองใหม่จะสร้าง URL ที่สองขึ้นมา เมื่อมีคีย์:

  • หากใช้คีย์เดียวกันกับ body เดียวกันภายใน 24 ชั่วโมง ระบบจะส่งการตอบกลับครั้งแรกซ้ำ รวมถึง URL เดิม พร้อม Idempotent-Replayed: true และไม่มีการเรียกเก็บเงินครั้งที่สอง
  • คีย์เดียวกันที่มี body ต่างกันจะได้ 422 และการลองใหม่ที่แซงหน้าคำขอแรกจะได้ 409 พร้อม Retry-After ดังนั้นให้กำหนดทุกอย่างใน body ให้ตายตัว รวมถึงอายุการใช้งาน ตั้งแต่ตอนสร้างล็อต และจัดเก็บไว้คู่กับล็อตนั้น
  • จัดเก็บ URL ไว้กับล็อตด้วย: คีย์ช่วยป้องกันปัญหาจากการลองซ้ำ และ URL ที่จัดเก็บไว้คือสิ่งที่หน้าเว็บจะอ่านตลอดช่วงที่เหลือของการประมูล

การนำเข้าแคตตาล็อกทั้งหมดในครั้งเดียวสามารถสร้าง URL ได้สูงสุด 50 ล็อตต่อการเรียกหนึ่งครั้ง โดยใช้คีย์หนึ่งคีย์ต่อแบตช์ และแต่ละ URL ในผลลัพธ์จะระบุรถและตัวเลือกที่ใช้สร้าง URL นั้นกลับมาด้วย

URL ของล็อต 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

ขั้นตอนที่ 5: กำหนดอายุของ URL ให้ตรงกับช่วงการขาย

ttl_seconds กำหนดได้สูงสุด 604800 (7 วัน) หากตั้งค่านานกว่านั้นจะถูกปรับลงเป็นค่าสูงสุด สำหรับการประมูลที่ปิดภายในสัปดาห์ ให้ตั้งค่าเป็นเวลาที่เหลือจนถึงเวลาปิด จากนั้นภาพตัวแทนจะหยุดทำงานพร้อมกับการประมูล และหลังจากนั้น URL จะตอบกลับด้วย 403

  • การขายแบบจำกัดเวลาที่นานกว่า 7 วัน: สร้างด้วย renew: true ตั้ง ttl_seconds เป็นค่าสูงสุด และตั้ง renew_days ให้ครอบคลุมช่วงการขาย การต่ออายุจะนับภาพหนึ่งครั้งในเดือนที่เกิดการต่ออายุ และไม่นับเพิ่มหากภาพนั้นถูกนับไปแล้วในเดือนนั้น สัปดาห์ที่ไม่มีใครเปิดดูล็อตจะไม่ถูกนับเลย และการต่ออายุจะหยุดที่ renews_until
  • ตั้ง max_uses ไว้ที่ 0 ซึ่งเป็นค่าเริ่มต้น: URL ที่ไม่จำกัดจำนวนครั้งจะแคชแบบสาธารณะได้ตลอดอายุการใช้งาน ส่วน URL ที่จำกัดจำนวนครั้งจะเป็น private, no-store และทุกการโหลดจะถูกส่งไปที่ต้นทาง
  • จำกัดคีย์ที่ใช้สร้าง URL ให้ใช้ได้เฉพาะโดเมนของเว็บประมูลของคุณบนแดชบอร์ด: ภาพของล็อตที่ถูกคัดลอกไปใช้บนเว็บไซต์อื่นจะตอบกลับ 403
การรับข้อมูลรถเข้าระบบด้วย 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

วางแผนให้รองรับขนาดของการประมูล

แต่ละล็อตคือภาพรถหนึ่งภาพ ซึ่งก็คือรถของล็อตนั้นในสีและมุมมองของมัน เว้นแต่สองล็อตจะมีทั้งสามอย่างเหมือนกัน และแต่ละแพ็กเกจมีภาพรถจำนวนหนึ่งต่อเดือน: Free 100, Pro 2,500 และ Business 10,000 ส่วน Enterprise สามารถเจรจาได้ ภาพที่ถูกนับแล้วในเดือนนี้จะให้บริการได้เสมอ และชุดคำขอที่จะเกินโควตาจะถูกปฏิเสธทั้งชุดก่อนที่จะมีการนับใดๆ โดยคำตอบจะระบุแพ็กเกจและโควตาไว้ เลือกแพ็กเกจให้เหมาะกับจำนวนล็อตที่คุณลงประกาศในหนึ่งเดือน เรื่องราวของมาร์เก็ตเพลส อธิบายวิธีกำหนดจังหวะการนำเข้าจำนวนมากภายใต้ขีดจำกัดอัตราคำขอและการเรนเดอร์

คำถามที่พบบ่อย

ยังคงแสดงภาพเรนเดอร์ไว้ได้หรือไม่ เมื่อมีภาพถ่ายของล็อตแล้ว
ให้แทนที่ ภาพเรนเดอร์เป็นเพียงภาพแทนของรุ่นปีนั้น และผู้ประมูลไม่ควรต้องสงสัยว่าภาพใดคือรถที่กำลังขายอยู่ หากหน้าใดยังเก็บภาพไว้เพื่ออ้างอิง ต้องแสดงป้ายกำกับไปด้วย
URL จะเป็นอย่างไรหลังการขาย
URL จะหมดอายุเมื่อสิ้นสุดอายุการใช้งาน หรือเมื่อ URL แบบต่ออายุได้ถึงสิ้นสุดช่วงการต่ออายุ จากนั้นจะตอบกลับด้วย 403 ถึงตอนนั้นล็อตก็จะมีภาพถ่ายของตัวเองหรือมีผลการประมูลแล้ว และหน้าเก็บถาวรของการประมูลควรแสดงภาพถ่ายจริง การเพิกถอนคีย์ที่ใช้สร้าง URL จะทำให้ URL ทั้งหมดใช้งานไม่ได้ในทันที
การลองใหม่ได้รับการตอบกลับเป็น 422 เพราะอะไร
มีการส่ง Idempotency-Key เดิมมาอีกครั้งพร้อม body ที่ต่างไป สาเหตุที่พบบ่อยคืออายุของ URL ถูกคำนวณใหม่จากเวลาปัจจุบันในขณะที่ลองใหม่ ให้กำหนดอายุให้ตายตัวตั้งแต่ตอนสร้างล็อตและจัดเก็บไว้ แล้วการลองใหม่จะส่ง body เดิมและได้รับคำตอบแรกซ้ำกลับมา
ภาพเรนเดอร์แสดงสีของรถในล็อตได้หรือไม่
ได้ color รับได้ทั้งชื่อสีที่กำหนดไว้ล่วงหน้าหรือค่า hex ภาพจึงตรงกับสีในเอกสารฝากขายได้โดยไม่มีค่าใช้จ่ายเพิ่ม แต่ภาพยังคงเป็นรุ่นรถในสีนั้น ไม่ใช่รถคันที่นำมาประมูล จึงยังต้องมีป้ายกำกับ
การประมูล 400 ล็อตมีค่าใช้จ่ายเท่าใด
นับเป็นภาพรถยนต์ 400 ภาพของเดือน: ภาพรถยนต์ 1 ภาพต่อล็อตเมื่อสร้าง URL ของล็อตนั้น และการสร้างซ้ำจะไม่นับเพิ่มอีก การโหลดทุกครั้งภายในอายุของ URL ไม่มีค่าใช้จ่าย แพ็กเกจรวมภาพรถยนต์ต่อเดือน ได้แก่ Free 100 ภาพ, Pro 2,500 ภาพ และ Business 10,000 ภาพ และล็อตที่ใช้รถ สี และมุมมองเดียวกันจะนับเพียงครั้งเดียว

อ่านต่อ

เรื่องราวลูกค้า · มาร์เก็ตเพลสยานยนต์วิธีใส่ภาพรถสไตล์สตูดิโอให้กับทุกประกาศบนมาร์เก็ตเพลสประกาศขายต้องมีรูปภาพตั้งแต่ก่อนที่ผู้ขายจะอัปโหลดรูปเอง มาร์เก็ตเพลสจึงเติมรูปให้ทั้งแค็ตตาล็อกด้วยมุมกล้องเดียวและสีเดียว จากนั้นใช้รูปแบบคำขอเดิมกับรถทุกรุ่นปีใหม่