Access JP auctions data

A read-only REST API over Japanese auction vehicle listings. Search and filter inventory, read normalized vehicle records, and download images watermarked with your own branding.

Base URL
https://carstack.dev/v1
Auth
Bearer token
Format
JSON, UTF-8
Methods
GET only

Authentication

Every request requires the API key issued to your organization, sent as an HTTP Bearer token. Keys are prefixed csk_live_.

Authorization: Bearer csk_live_your_api_key

Store the key server-side

A key identifies one partner and controls which branding is burned into image responses. Never ship it in browser or mobile client code. Rotating a key replaces it immediately; the previous value stops working and cannot be recovered.

Requests with a missing, malformed, or revoked key return 401.

Quickstart

Three requests take you from an empty integration to a downloaded image.

1 · See which makes exist

curl "https://carstack.dev/v1/makes" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN"

2 · Search vehicles for one of them

curl "https://carstack.dev/v1/vehicles?make=porsche&year_min=2020&per_page=5" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN"

3 · Download an image from a result

curl "https://carstack.dev/v1/images/12345" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN" \
  --output vehicle.jpg
Image URLs are returned to you

You never build an image URL by hand. Vehicle responses carry absolute images.primary_url and images.items[].url values; request those directly.

Conventions

Pagination

List endpoints accept page (default 1) and per_page (default 24, maximum 50). Out-of-range values are clamped rather than rejected. Every list response carries a meta object with page, per_page, total_count, and total_pages.

Matching

make and model ignore case, spacing, and punctuation, so Mercedes-Benz, MERCEDES BENZ, and mercedesbenz are the same query. They also match on whole words, so make=toyota returns vehicles listed under AMERICA TOYOTA. Both parameters are repeatable to OR several values together.

All other filters match the exact values published by /filters. Unknown query parameters are ignored, never rejected.

Currency and units

Prices are integer Japanese yen (price.currency is always JPY). Odometer readings are kilometers. Timestamps are ISO 8601 in UTC. Fields with no value are null rather than omitted.

List vehicles

GET/v1/vehicles

Returns a paginated collection of vehicle summaries. With no parameters it returns the whole catalog ordered by auction date, soonest first.

ParameterTypeDescription
qstringSubstring search over make, model, and title.
makestring, repeatableVehicle make. See /makes.
modelstring, repeatableVehicle model. See /makes.
year_min, year_maxintegerInclusive model-year range.
price_min, price_maxintegerInclusive current-price range, JPY.
odometer_min, odometer_maxintegerInclusive odometer range, kilometers.
transmissionsarrayautomatic, manual, cvt, unknown.
steeringarraylhd or rhd.
colorsarrayExterior colors from /filters.
auction_gradesarrayInspection grades such as 4.5, S, R.
auction_housesarrayAuction house names such as Tokyo.
sortstringending_soon (default), price_asc, price_desc, year_asc, year_desc, mileage_asc, mileage_desc.
page, per_pageintegerPagination; per_page maximum is 50.

Request

curl "https://carstack.dev/v1/vehicles?make=porsche&auction_grades=6&sort=price_desc&per_page=1" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN"

Response

{
  "data": [
    {
      "id": "4609179117499670",
      "lot_number": "79126",
      "title": "2024 PORSCHE 911 CP 911GT3",
      "make": "PORSCHE",
      "model": "911",
      "year": 2024,
      "grade": "6",
      "auction": {
        "house": "Tokyo",
        "date": "2026-07-01T15:00:00Z",
        "status": "upcoming"
      },
      "price": { "current": 39800000, "currency": "JPY" },
      "odometer_km": 2000,
      "specs": {
        "engine": "4L",
        "engine_cc": 4000,
        "transmission": "Automatic",
        "steering": "lhd",
        "color": "Red",
        "equipment": ""
      },
      "images": {
        "total": 14,
        "primary_url": "https://carstack.dev/v1/images/9821"
      }
    }
  ],
  "meta": { "page": 1, "per_page": 1, "total_count": 12, "total_pages": 12 }
}
Repeat a parameter to widen a filter

?make=porsche&make=ferrari&auction_grades=4.5&auction_grades=5 returns Porsches and Ferraris graded 4.5 or 5. Bracketed names such as make[] are accepted too.

Retrieve a vehicle

GET/v1/vehicles/{vehicle_id}

Returns one vehicle by the id from a list response. The payload repeats every summary field and adds chassis_code, price.start, price.final, and the full image list under images.items. Unknown IDs return 404.

Request

curl "https://carstack.dev/v1/vehicles/4609179117499670" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN"

Response (additional fields only)

{
  "chassis_code": "992",
  "price": {
    "current": 39800000,
    "start": 39800000,
    "final": 0,
    "currency": "JPY"
  },
  "images": {
    "total": 14,
    "primary_url": "https://carstack.dev/v1/images/9821",
    "items": [
      {
        "id": 9821,
        "kind": "thumbnail",
        "position": 0,
        "url": "https://carstack.dev/v1/images/9821",
        "updated_at": "2026-07-02T09:14:22Z"
      }
    ]
  }
}

Retrieve an image

GET/v1/images/{image_id}

Streams a JPEG rendered for the partner that owns the API key. Use the url values returned by /vehicles and /vehicles/{vehicle_id} rather than composing this path yourself.

Request

curl "https://carstack.dev/v1/images/9821" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN" \
  --output vehicle.jpg

What you receive

  • A full-resolution image/jpeg in the original frame, never letterboxed or cropped.
  • Your logo, or your configured logo text, rendered at the lower right; your contact number in a compact pill at the lower left when one is configured.
  • EXIF attribution written on delivery: Artist and Copyright hold your logo text, ImageDescription adds your contact number and Delivered via carstack.dev, and Software is carstack.dev.
  • No source EXIF, XMP, IPTC, or embedded provider identity — every derivative is rebuilt from pixels before your attribution is written.

Images not yet prepared for delivery return 404; they are also absent from images.items, so an empty list means nothing is ready yet rather than that something failed.

See Caching for conditional requests.

List makes

GET/v1/makes

Returns every make in the catalog with its models and vehicle counts. This is the authoritative source for the make and model parameters — the feed uses market-specific spellings such as AMERICA TOYOTA and LEXUS (US), and this endpoint shows them verbatim. Counts cover the whole catalog and are recomputed hourly.

Request

curl "https://carstack.dev/v1/makes" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN"

Response

{
  "data": [
    {
      "name": "MERCEDES BENZ",
      "vehicle_count": 174,
      "models": [
        { "name": "S-CLASS", "vehicle_count": 21 },
        { "name": "G-CLASS", "vehicle_count": 19 }
      ]
    },
    {
      "name": "PORSCHE",
      "vehicle_count": 65,
      "models": [{ "name": "911", "vehicle_count": 28 }]
    }
  ],
  "meta": { "total_makes": 36, "total_models": 190, "vehicle_count": 662 }
}

Makes are ordered by vehicle count, most first; models are ordered the same way within each make.

List filter values

GET/v1/filters

Returns every remaining enumerable filter value with counts, plus the numeric ranges present in the catalog. Use it to build filter UIs without guessing, and to avoid queries that cannot match anything.

Response

{
  "data": {
    "colors": [{ "value": "BLACK", "vehicle_count": 148 }],
    "transmissions": [{ "value": "automatic", "vehicle_count": 599 }],
    "steering": [{ "value": "lhd", "vehicle_count": 662 }],
    "auction_grades": [{ "value": "4", "vehicle_count": 211 }],
    "auction_houses": [{ "value": "Tokyo", "vehicle_count": 286 }],
    "sort": ["ending_soon", "price_asc", "price_desc", "year_asc",
             "year_desc", "mileage_asc", "mileage_desc"],
    "year": { "min": 1968, "max": 2026 },
    "price_jpy": { "min": 0, "max": 66000000 },
    "odometer_km": { "min": 0, "max": 303000 }
  },
  "meta": { "vehicle_count": 662 }
}

Errors

Every failure returns the same JSON envelope with an HTTP status that matches error.status. Branch on error.code; treat error.message as human-readable text that may change.

{
  "error": {
    "code": "unauthorized",
    "message": "A valid API token is required.",
    "status": 401
  }
}
StatusCodeMeaning
400 422invalid_requestThe request could not be processed as sent.
401unauthorizedMissing, malformed, or revoked API key.
403access_deniedThe key is valid but not entitled to this resource.
404not_foundNo such vehicle or image, or it is not available for delivery.
429rate_limit_exceededToo many requests. Back off and retry.
502upstream_unavailableTemporary server-side failure. Retry with backoff.

Rate limits

Limits are per API key, measured over a rolling minute.

EndpointsLimit
/vehicles, /vehicles/{id}, /makes, /filters60 requests / minute
/images/{id}120 requests / minute

Exceeding a limit returns 429. When a Retry-After header is present, wait at least that long before retrying; otherwise back off exponentially. Conditional image requests that return 304 still count toward the limit, so cache locally as well.

Caching

All responses are marked private; do not put them in a shared cache. Vehicle responses stay fresh for 60 seconds, /makes and /filters for 10 minutes, and images for a year.

Image responses carry ETag and Last-Modified. Send them back to skip re-downloading unchanged bytes — a match returns 304 with no body.

curl "https://carstack.dev/v1/images/9821" \
  -H "Authorization: Bearer $CARSTACK_API_TOKEN" \
  -H 'If-None-Match: "previously-returned-etag"'

An image's bytes change when your branding changes, which is why the validator is tied to both the image and your partner configuration.