Car Image API

お客様事例 · ディーラー・輸入・VIN ツール

販売店向けソフトウェアで、VINや在庫リストから全車両の画像を用意する方法

ディーラー向けツールや輸入ツールが、VINや在庫表の1行からすべてのレコードにスタジオ画像を表示するまでの流れ:無料VINデコード、resolve、安定したID、署名付きURL。

課題:写真が用意される何か月も前から、記録にはVINがある

CRM、ERP、ディーラー管理システム(DMS)の在庫レコードは、VIN、在庫番号、価格から始まります。写真が入るのは撮影担当者が来たときで、在庫によっては写真がまったく入らないこともあります。輸送中の車両、まだ再整備中の下取り車、DMS の画像フィードのどのモデル名とも一致しない輸入車、誰もプレス写真のライセンスを取得していない1990年代の車などです。そのレコードを表示するあらゆる画面、つまり営業担当者の一覧、仕入れ担当者の査定、顧客向けの見積もりには、代わりにグレーのプレースホルダーが表示されます。

このAPIを利用しているディーラー向けツールや輸入車向けツールは、その仮画像を記録に既にある情報から埋めています。VINがあれば、無料のデコードを1回行うだけで画像が手に入ります。在庫表の1行しかなくても、フリーテキストのresolveで特定できます。いずれの場合も記録には安定した車両IDが保持され、すべての画面で同じ車が同じように表示されます。

ディーラー向けインテグレーションの構成

  • 登録時にデコード。VINはレコード作成時に1回だけデコードされ、カタログの車両IDがその横に保存されます。後続の処理でメーカー名やモデル名を記述することはありません。
  • 一覧用と詳細用にビューを1つずつ。在庫一覧には横長の枠で真横からのsideを、詳細ページと見積もりにはfront-3-4を使います。
  • 幅広い年式。輸入車や中古車の在庫は1990年代までさかのぼりますが、新着車両と同じようにレンダリングできます。カタログは 1990 年から現行モデルイヤーまでを網羅し、日本国内専用モデルも含まれます。
  • アプリ内では署名付き URL。CRM はブラウザなので、サーバーが発行したキー不要の署名付き URL を読み込みます。1 回の呼び出しで最大 50 件、1 週間より長く残るレコードについては更新されます。

ステップ1:VINを無料でデコードする

GET /api/v1/vin/{vin}は無料で、APIキーだけで利用できます。デコードされた年式、メーカー、モデル、トリム、ボディクラス、エンジンなど、NHTSAのvPICデータにあるすべての属性を返し、カタログにその車両がある場合は、安定したIDと既製のimage_pathを含むvehicleオブジェクトも返します。部分的なVINにも対応しています。5文字以上で、不明な位置ごとに*を使い、任意でyearのヒントを追加できます。

デコード
curl -s -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/vin/1HGCM82633A004352"
200 OK(一部省略)
{
  "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…"
}

ステップ1b:在庫表の1行しか情報がない場合

輸入在庫は、スプレッドシートで届くことがよくあります。年式、メーカー、オークション会社が使った表記そのままのモデル名、グレードやトリムコードなどです。POST /api/v1/images/resolveは無料で、結果は決定的です。フレーズから年式・カラー・ビューを表す語を抜き出し、残りの語でカタログを検索して、そのまま判断に使える信頼度とともに正確なパラメータを返します。

在庫表の1行から車両を特定
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"}'
200 OK(一部省略)
{
  "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…"
}

車両は正しく特定されています(2019年式 Toyota Voxy)が、confidence は low です。「ZS」はカタログが認識していないグレードで、それを除外してマッチングする必要があったためです。一括インポートでは、high は完了として扱い、medium と low は candidates リストとともに担当者の確認に回してください。シートに年式とメーカーが別々の列で入っている場合は、それらを year と make フィールドとして送り、query にはモデルだけを残してください。マッチングの精度が大きく向上します。車両に関する語を含まないフレーズは 400 になり、一致するモデルがないメーカーは 404 となってそのメーカーの年式一覧が返されるため、ユーザーにモデルを尋ねることができます。

ステップ2:車両 ID をレコードに保存する

どの経路で取得した場合でも、vehicle.id(または params.vehicle_id)を在庫レコードに通常の文字列カラムとして保存してください。この ID は決定的かつ永続的で、どのデプロイでも、どのカタログリリース後でも同じ車両には同じ ID が割り当てられるため、外部キーとして安全に使えます。以降の画像リクエストはすべて vehicle=veh_… となり、スペルミスが起こり得ません。また、メーカーがメーカー名を変更したり、データソースが登録し直したりしても、保存済みの URL が壊れることはありません。

ステップ3:一覧用に1ビュー、詳細ページ用に1ビュー

在庫一覧は横長で高さが低いため、2:1 の枠に真横からのビューを使うのが一般的です。すべての車両が同じ向きで、同じベースラインに並びます。trim=1&padding=6 はフィットさせる前に車体に合わせてトリミングするため、Hilux でも Yaris でも行を同じように埋められます。fit=contain は透明な余白を付けてキャンバスをちょうど 640×320 に保ちます。詳細ページでは front-3-4 を 1024 で使用し、両者はキャッシュを共有します。ペイントカラーを指定しなかった場合は、どちらもシルバーになります。

1件のレコードの一覧用画像
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.webp

ステップ4:署名付き URL で CRM に表示する

CRM はブラウザで動作しますが、ブラウザに API キーを持たせてはいけません。画面に在庫を 1 ページ分一覧表示するとき、サーバーが POST /api/v1/image-urls でレコードごとに署名付き URL を 1 つ発行し(1 回の呼び出しで最大 50 件、1 件につき 1 クレジット)、ページはそれを通常の画像と同じように読み込みます。何か月も在庫に残るレコードでは、次の 2 つの設定が重要です:

  • ttl_seconds: 604800とrenew: trueを指定すると、URLは7日間のTTLを過ぎても使い続けられ、実際に誰かがその記録を開いた週ごとに1クレジットが追加でかかります。誰もその車を見なかった週は無料です。
  • 同期の各ページに Idempotency-Key を 1 つ設定します。再試行されたリクエストは最初のレスポンスを再生し、二重に発行されることはありません。

ダッシュボードで発行用キーをCRMのオリジンに制限すると、他のサイトに流出したURLは403を返します。キーを失効させると、そのキーで発行したすべてのURLが無効になります。残高が尽きた場合、更新は402を返しますが、クレジットが追加され次第、同じURLが再び機能します。自動チャージを使えば、この障害は起こりません。ライフサイクルの詳細は署名付きURLのドキュメントをご覧ください。

TypeScript SDKによる入庫処理と在庫リスト
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、MCP

npx @meterapp/car-image
# 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, … })、client.createImageUrls(…)。
  • MCP: decode_vin、resolve_vehicle、get_car_image、create_car_image_urls はコアツールセットに含まれているため、在庫システムをコンテキストに持つアシスタントは、レコード上の VIN から「在庫 4471 の写真」という依頼に応えられます。セットアップ方法は MCP ページに、デコーダーのフィールドとエラーは VIN ドキュメントに記載しています。

よくある質問

すべての在庫レコードに写真を付けると、費用はいくらですか?
VIN デコードは無料です。車両・ビュー・ペイントカラーの組み合わせごとに最初の画像は1クレジットで、以降は全ユーザー向けにキャッシュされます。If-None-Match による再確認は無料です。署名付き URL は発行時に1クレジットかかり、renew: true を指定した場合は、実際に開かれた週ごとにさらに1クレジットかかります。数千台の在庫を持つディーラーグループなら、最初に数千クレジットを使うだけで、その後はほとんどかかりません。
VIN はデコードできたのに vehicle が null です。どうすればよいですか?
デコーダーはメーカー、モデル、年式を特定できましたが、その組み合わせがカタログに登録されていません。トレーラー、一部の商用シャシー、まだソースに登録されていない車名などが該当します。デコードされたフィールドを表示し、表記が異なる可能性に備えて GET /api/v1/vehicles?q= でカタログを検索したうえで、リクエストボードで車両をリクエストしてください。POST /api/v1/requests は、重複を作成せず、既存のオープンなリクエストに賛成票を加えます。
VIN デコードは輸入車や米国で販売されていない車両にも対応していますか?
デコーダーは NHTSA の vPIC データを使用しているため、NHTSA に届け出ているメーカーの VIN は完全にデコードされます。米国向けの認証を受けていない車両は、メーカーと年式のみでモデルが特定できないことが多く、まったくデコードできない場合もあります。そのような在庫車は、車検証などの登録書類から特定してください。カタログ自体は1990年以降の全世界の車両を網羅しており、トヨタ Voxy のような日本国内専用車も含まれています。
レンダリング画像には、車両レコードに記載されたトリムが反映されますか?
いいえ。カタログはメーカー、モデル、年式をキーにしているため、EX-V6クーペとLXセダンは同じ2003年式Accordとしてレンダリングされます。デコード結果のtrimとbody_classは画像の横にテキストとして表示し、レンダリング画像を特定の個体として説明しないでください。
ディーラーのWebサイトでもCRMと同じURLを使えますか?
許可オリジンにそのサイトを登録したキーで発行すると、他のサイトからブラウザで読み込まれた URL は 403 origin_not_allowed を返します。メールクライアントなど Referer のない読み込みは通過します。CRM とウェブサイトで 1 つのキーと 1 組の URL を共有することも、どちらか一方だけを無効化できるようにそれぞれ別のキーを使うこともできます。