Car Image API
Documentation

Image Packs

Buy a number of images once, prepare them in batches with a webhook as each car is ready, and host them on your own servers for good.

What a pack is

An Image Pack is a one-time purchase of a number of images at one quality, open to every account beside any plan, Free included. One image is one vehicle in one view, delivered in any color, size and format. Every color is included because each view is stored with a paint mask. You have 30 days to prepare, re-request, upgrade and re-download the pack's images, with webhooks for updates to them. The images are yours to self-host on your own servers and CDN forever: you never need to delete them, even after a plan ends (plan images, by contrast, are deleted within 30 days after the plan ends; see the license). A pack does not use the plan's monthly vehicle images.

ImagesStandard (1×)Enhanced (2×)Premium (4×)
100$49 ($0.49 each)$99 ($0.99 each)$199 ($1.99 each)
500$149 ($0.298 each)$299 ($0.598 each)$599 ($1.198 each)
2,500$499 ($0.2 each)$999 ($0.4 each)$1,999 ($0.8 each)
10,000$1,499 ($0.15 each)$2,999 ($0.3 each)$5,999 ($0.6 each)

Standard is our first render, made quickly. Enhanced and Premium take a second, higher-quality pass (quality). Every account may buy a pack: GET /api/v1/packs lists the ones on sale, each with a checkout_url that opens Stripe Checkout. Every pack endpoint below is free; the pack is paid once at Checkout.

Quote a list first (free)

POST/api/v1/packs/quote
images:readfree

Send the same body as a batch. The answer says how many images are already stored at that quality (ready in seconds), how many need a new drawing or only the higher-quality pass, how long that takes, and the smallest pack that holds them. Vehicles the catalog does not carry come back in refused with suggestions.

Send a batch

POST/api/v1/packs/{id}/batches
images:readfree; each new vehicle view uses one image of the pack
POST /api/v1/packs/{id}/batches body
ParameterTypeDescription
items
array
Up to 5,000 images in all. Each item is a vehicle (vehicle, a veh_… id, or make, model and year) and its views: one image each, front-3-4 when it lists none. An optional ref is echoed if the entry is refused.
quality
string
The pack's quality (the default) or a lower one: standard, enhanced or premium.
webhook_url
string
Optional public HTTPS URL that receives one POST pack.batch.completed, besides your webhook endpoints. webhook_secret signs it.
bash
curl --fail-with-body \
  -X POST https://carimage.dev/api/v1/packs/pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c/batches \
  -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: catalog-2026-10-23" \
  -d '{"quality":"enhanced","items":[{"vehicle":"veh_errc87t1jgata","views":["front-3-4","rear-3-4"]},{"make":"honda","model":"civic","year":2024}],"webhook_url":"https://example.com/hooks/carimage"}'
202 Accepted
{
  "data": {
    "id": "pbt_2b4c6d8e0f1a3b5c7d9e1f3a5b7c9d1e",
    "object": "pack_batch",
    "status": "queued",
    "quality": "enhanced",
    "items": 3,
    "images_charged": 3,
    "pack": {
      "id": "pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c",
      "object": "image_pack",
      "images_included": 500,
      "images_used": 3,
      "images_remaining": 497,
      "quality": "enhanced",
      "window_ends_at": "2026-11-22T12:00:00.000Z",
      "window_open": true
    }
  },
  "eta": {
    "typical_seconds": 228,
    "per_image_seconds": 76,
    "images_stored": 1,
    "images_to_draw": 2,
    "exact": true
  },
  "why_it_takes_time": "We create a paint mask for each car so it can be shown in any color you request. Standard quality is the default because it is quick. Enhanced and Premium take another, longer pass. We'll send a webhook when each car is ready.",
  "why_it_takes_time_url": "https://carimage.dev/docs/packs#timing",
  "request_id": "req_01j9x…"
}
  • Every vehicle is read first, with the same rules as a coverage check. If any entry names a vehicle the catalog does not carry, the whole batch is refused with 422 vehicles_not_found, each with suggestions, and nothing is used. We never substitute another car.
  • A vehicle view the pack already holds is not charged again, and an image that cannot be made goes back to the pack (image_returned: true).
  • Too few images left answers 409 pack_exhausted with images_needed and images_remaining; nothing is used. Send an Idempotency-Key: a retry returns the first batch.

Why it takes a moment

Every batch answer carries this text in why_it_takes_time. Its eta comes from waits measured on our production traffic, never a fixed promise: per_image_seconds for one image drawn (and, above Standard, upgraded), and typical_seconds for the batch, with images made several at a time. Images that are already stored at the quality you asked for are ready in seconds, and we never draw them again.

Know when each car is ready

Each finished image sends image.ready to your webhook endpoints, with the pack, batch and item and the URL that downloads it; the last one sends pack.batch.completed. During the pack's 30 days you also get image.upgraded, image.issue_reported, image.issue_resolved and image.replaced for its images, whatever your plan. Or poll GET /api/v1/packs/{id}/batches/{batch_id} (free; items in request order, limit up to 500 and after to page).

image.ready
{
  "id": "evt_5d2a8c1e4b7f0a3d6c9e2b5f8a1d4c7e",
  "type": "image.ready",
  "created_at": "2026-10-23T12:03:41.204Z",
  "data": {
    "object": "image",
    "vehicle": {
      "id": "veh_errc87t1jgata",
      "make": "toyota",
      "model": "camry",
      "year": 2025
    },
    "view": "rear-3-4",
    "color": null,
    "quality": "enhanced",
    "sha256": "9b2e…",
    "url": "https://carimage.dev/api/v1/packs/pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c/images/8a1f3c52-6d0e-4c1b-9f3a-2b7d5e9c0a14",
    "pack": {
      "id": "pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c",
      "batch_id": "pbt_2b4c6d8e0f1a3b5c7d9e1f3a5b7c9d1e",
      "item_id": "8a1f3c52-6d0e-4c1b-9f3a-2b7d5e9c0a14"
    }
  }
}

Download

GET/api/v1/packs/{id}/images/{item_id}
images:readfree

One image in any color, size and format, with the delivery parameters of GET /api/v1/images/car: color, w, h, format, fit, background, trim, shadow. The URL names its vehicle and view. Store what it returns and serve it from your own servers.

bash
curl -s -H "Authorization: Bearer $CAR_IMAGE_API_KEY" \
  "https://carimage.dev/api/v1/packs/pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c/images/8a1f3c52-6d0e-4c1b-9f3a-2b7d5e9c0a14?color=red&w=800&format=webp" -o camry-rear-red.webp

Manifest

GET/api/v1/packs/{id}/manifest
images:readfree

Every image the pack delivered, one row per vehicle view: vehicle, view, quality, the SHA-256 of the delivered bytes and its download URL. JSON, or ?format=csv.

Export as ZIP files

POST/api/v1/packs/{id}/exports
images:readfree, 10 a month

Every delivered image in one color (silver by default, neutral for the unpainted base), format (png or webp) and optional width, as ZIP files of 250 images each with the manifest in the first. They are built in the background: pack.export.ready says when, with links valid for 7 days, and GET /api/v1/packs/{id}/exports/{export_id} answers the same. A pack may be exported 10 times a calendar month, during its window and after.

After the 30 days

Three days before the end you get pack.window.ending and an email; at the end, pack.window.ended. From then on the pack takes no new batches, re-requests or upgrades, and sends no update webhooks for its images. Nothing changes about your license: you keep using and self-hosting the images for good. The pack stays in your archive: the manifest, downloads of the exact bytes it delivered (in any color and size, up to 600 an hour) and ZIP exports. A new pack or a subscription brings updates back.

From the CLI and the SDK

bash
npx @meterapp/car-image packs                    # your packs, and the ones you can buy
npx @meterapp/car-image packs quote cars.csv --views front-3-4,rear-3-4
npx @meterapp/car-image packs batch pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c cars.csv --views front-3-4,rear-3-4 --wait
npx @meterapp/car-image packs manifest pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c --out manifest.csv
npx @meterapp/car-image packs export pck_7c1e9a4b2d6f4e0a8b3c5d7e9f1a2b4c --color white --format webp --wait

The SDK (@meterapp/car-image-sdk) has listPacks, quotePack, createPackBatch, getPackBatch, downloadPackImage, getPackManifest and createPackExport, and exports PACK_PRICES.