Calculator API

Console & integration docs

Overview

Programmatic access to car details, delivery cost and the auction fee — for live auction lots and for our retail catalogue — plus your ground (inland US) delivery tariffs.

Base URL

https://base-auction.com/api/v1

Authentication

Send your key in the X-Api-Key header on every request. Paste it in the field above to try requests right here on this page — you'll see exactly what your integration receives.

X-Api-Key: lk_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx

Browser (JS) calls are additionally restricted to your whitelisted domains (Origin/Referer). Server-to-server calls are bound by the key only. Contact your manager to enable access and get a key.

Rate limits

  • 60 requests/minute by default (configurable per account) → 429 on exceed.
  • Optional monthly quota per account → 429 on exceed.

GET/ping

Validate your key and read your live quota usage. Great first call to confirm the integration.

Response

{ "ok": true, "dealer": "…", "quota": { "rate_per_minute": 60, "monthly_quota": null, "used_this_month": 12 } }

Try it

POST/calculate

Full car info + delivery cost + auction fee (сбор) for a live auction lot. Customs is not included.

Parameters

FieldRequiredDescription
urlyes*Full Copart/IAAI lot URL, or a raw lot number. (*or use retail_id — see retail tab.)
auctionconditionalcopart | iaai. Needed when url is a raw number or can't be inferred.
destinationyesgeorgia, lithuania, poland (also poti/klaipeda/rotterdam/ukraine).
bidnoThe bid you plan to place (USD). The auction fee is calculated on this amount. Omit to use the lot's current price.

Response

{
  "auction": "copart", "lot": "12345678",
  "vehicle": { "vin": "…", "make": "HONDA", "model": "CIVIC", "year": "2018", "price": 8200, "images": ["…"], … },
  "delivery": { "port": "PORT, GA", "land_price": 350, "container_price": 1200, "cost": 1550 },
  "fee": { "bid": 8500, "auction_fee": 495.00 }
}

cURL

curl -X POST https://base-auction.com/api/v1/calculate \
  -H "X-Api-Key: YOUR_KEY" -H "Content-Type: application/json" \
  -d '{"url":"https://www.copart.com/lot/12345678","destination":"georgia"}'

Try it

POST/calculate (retail car)

Same calculation for a car from our retail catalogue — computed from stored data (no live auction fetch, faster). Get the id from GET /retail/cars.

Parameters

FieldRequiredDescription
retail_idyesCatalogue car id.
destinationyesDelivery destination (same options as above).
bidnoThe bid you plan to place (USD). The auction fee (сбор) is calculated on this amount. Omit to use the lot's stored price.

Response

Same shape as /calculate, plus retail_id and the stored gallery in vehicle.images. fee.bid echoes the amount the fee was computed on.

Try it

POST/images

All photos for a live auction lot.

Parameters

FieldRequiredDescription
urlyesLot URL or raw lot number.
auctionconditionalcopart | iaai.

Response

{ "auction": "copart", "lot": "12345678", "count": 24, "images": ["https://…jpg", …] }

Try it

GET/retail/cars

Filtered, paginated catalogue. Only lots with a complete, unmasked VIN are returned. All filters are optional and combine with AND; values inside one multi-value parameter combine with OR.

Active vs. sold lots

status=active returns only lots that are currently listed at auction. status=inactive returns only closed ones (sold or no longer listed), and status=all returns both. The default is all, so pass status=active explicitly if you need only cars that can still be bought. With all, active lots always come first. Each car in the response carries isActive and status (active / sold).

Query parameters (all optional)

Multi-value parameters are repeated with []: makers[]=HONDA&makers[]=TOYOTA. Values are matched exactly (case-sensitive), so take them from GET /retail/filters or from a previous response.

ParamTypeDescription
Scope & paging
statusstringactive | inactive | all (default).
pageintPage number, from 1.
perPageintPage size, 1–100 (default 24).
auction[]string[]copart, iaai.
Vehicle
makers[], models[]string[]Make / model, e.g. TOYOTA / CAMRY.
typeBody[]string[]Body style.
transmission[], fuelType[], drive[]string[]Transmission, fuel type (e.g. ELECTRIC, DIESEL), drive type.
minYear / maxYearintModel year range, inclusive.
minOdometer / maxOdometerintOdometer range, inclusive.
Condition & title
primaryDamages[]string[]Primary damage, any of the given values (e.g. FRONT END, REAR END).
primaryDamagestringSingle primary damage (older form of primaryDamages[], still supported).
secondaryDamages[]string[]Secondary damage, any of the given values.
runsDrives[]string[]Run condition as the auction reports it. Copart: RUNS AND DRIVES, ENGINE START PROGRAM, ENHANCED VEHICLES. IAAI: Run & Drive.
hasKeysbool1 = keys present, 0 = no keys.
title[]string[]Title group.
isInsurancebool1 = sold by an insurance company, 0 = dealer / other seller.
Price, auction date, location
minPrice / maxPricenumberBuy Now price range, USD.
hasPricebool1 = only lots with a Buy Now price, 0 = only lots without one.
auctionDateFrom / auctionDateTodateAuction date range in UTC, a date or a date with time (see Date and time values below). A bare date in auctionDateTo includes that whole day. Lots without an auction date are excluded when either bound is set.
hasAuctionDatebool1 = only lots with a scheduled auction date, 0 = only undated ones.
lane[]string[]Sale lane, exact match: lane[]=A&lane[]=B.
hasLanebool1 = only lots already assigned to a lane, 0 = only unassigned ones.
zip[]string[]ZIP of the place where the car stands, exact match (US: 5 digits).
hasZipbool1 = only lots with a known ZIP, 0 = only lots without one.
createdFrom / createdTodateWhen the lot first appeared in our catalogue. Date or date with time, to the second: createdFrom=2026-10-08T14:00:00Z.
updatedFrom / updatedTodateWhen we last refreshed the lot. Date or date with time, to the second: updatedFrom=2026-10-08T14:45:00Z. A lot is refreshed every time our collector sees it at the auction, not only when its data changes.
locations[]string[]Auction yard, as in the location field.
Search & sort
lotIdstringFlexible free-text search: VIN/lot-number prefix, make/model (together or separately, typo-tolerant), and an exact model year (e.g. "Toyota Camry 2020").
sortstringdate (default: nearest auction first), date_desc, price_asc, price_desc, year_desc, year_asc, newest (recently added), created_asc, updated_desc, updated_asc, lane_asc, lane_desc (lane, then item number), zip_asc, zip_desc, popular. Lots without a lane / ZIP always come last. Every sort is applied inside the standard grouping: active lots first, then today's auctions, other dated lots, undated lots.

Booleans accept 1/0 or true/false. An invalid value for status, perPage, auction[], the boolean flags or the dates returns 422 with details in errors. An unknown sort falls back to date.

Date and time values

auctionDateFrom/To, createdFrom/To and updatedFrom/To accept a date or a date with time, precise to the second. Both bounds are inclusive.

ValueMeaning
2026-10-08In a …From bound: 00:00:00 UTC of that day. In a …To bound: the whole day, through 23:59:59 UTC.
2026-10-08T14:30:00Z
2026-10-08T14:30
2026-10-08 14:30:00
That exact moment in UTC (a value without a time zone is read as UTC).
2026-10-08T17:30:00+03:00The same moment given with an offset. In a query string the + must be sent as %2B.
@1791469800Unix timestamp (seconds), prefixed with @.

To poll for changes, remember the time of your previous request and pass it as updatedFrom — e.g. every 15 minutes with sort=updated_asc — then page until last_page. createdAt / updatedAt in the response are in the same UTC ISO 8601 format and can be sent back as they are.

Examples

# Active Copart electric cars with keys, auction this week, cheapest first
GET /api/v1/retail/cars?status=active&auction[]=copart&fuelType[]=ELECTRIC&hasKeys=1&auctionDateFrom=2026-09-29&auctionDateTo=2026-10-05&sort=price_asc

# Active running Toyota / Lexus 2019–2023 up to 80,000 mi, 100 per page
GET /api/v1/retail/cars?status=active&makers[]=TOYOTA&makers[]=LEXUS&minYear=2019&maxYear=2023&maxOdometer=80000&runsDrives[]=RUNS%20AND%20DRIVES&runsDrives[]=Run%20%26%20Drive&perPage=100

# Lots added to the catalogue since 1 October that already have a lane, in lane order
GET /api/v1/retail/cars?status=active&createdFrom=2026-10-01&hasLane=1&sort=lane_asc

# Everything refreshed in the last 15 minutes (14:30–14:45 UTC), oldest change first
GET /api/v1/retail/cars?updatedFrom=2026-10-08T14:30:00Z&updatedTo=2026-10-08T14:45:00Z&sort=updated_asc&perPage=100

# New lots of the last hour
GET /api/v1/retail/cars?status=active&createdFrom=2026-10-08T13:45:00Z&sort=newest

Response

{ "cars": { "data": [ { "id": 12345, "status": "active", "isActive": true, "auction": "copart", "vin": "…", "maker": "HONDA", … } ], "current_page": 1, "last_page": 42, "total": 1000 } }

Each car also carries lane and laneItem (sale lane and item number, null until the auction assigns the lot), zip (yard ZIP, null when not known yet), and createdAt / updatedAt (ISO 8601, UTC) — when the lot first appeared in our catalogue and when we last refreshed it.

To load every active lot, request status=active&perPage=100 and increase page until it reaches last_page.

Try it

GET/retail/filters

Every filter of GET /retail/cars as a typed list: what kind of control it is, which query parameter(s) it is sent in, and the values available right now. Build your filter UI by type — no per-filter parsing rules are needed. The values cover the active inventory and are refreshed about every 30 minutes, so cache the response on your side.

Response

{
  "version": 1,
  "filters": [
    { "key": "status",   "group": "scope",   "type": "single", "valueType": "string",
      "param": "status", "options": ["active", "inactive", "all"], "default": "all" },
    { "key": "makers",   "group": "vehicle", "type": "multi",  "valueType": "string",
      "param": "makers[]", "options": ["ACURA", "AUDI", "BMW", …] },
    { "key": "models",   "group": "vehicle", "type": "multi",  "valueType": "string",
      "param": "models[]", "dependsOn": "makers",
      "optionsBy": { "ACURA": ["ILX", "MDX", …], "AUDI": ["A3", "A4", …] } },
    { "key": "year",     "group": "vehicle", "type": "range",  "valueType": "int",
      "params": { "min": "minYear", "max": "maxYear" }, "min": 1990, "max": 2027, "unit": null },
    { "key": "price",    "group": "price",   "type": "range",  "valueType": "number",
      "params": { "min": "minPrice", "max": "maxPrice" }, "min": 0, "max": 250000, "unit": "USD" },
    { "key": "hasKeys",  "group": "condition", "type": "bool", "valueType": "bool", "param": "hasKeys" },
    { "key": "updated",  "group": "catalogue", "type": "dateRange", "valueType": "datetime",
      "params": { "from": "updatedFrom", "to": "updatedTo" } },
    { "key": "zip",      "group": "location", "type": "multi", "valueType": "string",
      "param": "zip[]", "options": null },
    { "key": "lotId",    "group": "search",  "type": "text",   "valueType": "string", "param": "lotId" },
    …
  ],
  "sort":   { "param": "sort", "default": "date", "options": ["date", "date_desc", "price_asc", …] },
  "paging": { "page":    { "param": "page", "default": 1 },
              "perPage": { "param": "perPage", "default": 24, "max": 100 } }
}

Fields of a filter

FieldDescription
keyStable identifier of the filter.
groupSuggested section of a filter panel: scope, vehicle, condition, price, auction, location, catalogue, search.
typeOne of the six types below — it alone defines which other fields are present.
valueTypeType of a value you send: string, int, number, bool, datetime.
param / paramsThe exact query parameter name(s) of GET /retail/cars. A filter has either one param or a params object, never both.

Filter types

typeExtra fieldsHow to send it
singleoptions: string[], defaultOne value: status=active.
multioptions: string[] — or null when any value is accepted (lane, zip).
A dependent filter has dependsOn + optionsBy instead of options: an object «value of the parent filter → string[]» (models per make).
Repeat the parameter, values are combined with OR: makers[]=HONDA&makers[]=TOYOTA. Values are sent exactly as listed (case-sensitive).
rangeparams.min, params.max; min, max — the bounds present in the catalogue now (null if unknown); unit (USD, mi or null)Either bound or both, inclusive: minYear=2019&maxYear=2023.
bool—1 / 0 (or true / false); leave the parameter out for «any».
dateRangeparams.from, params.toA date or a date with time, UTC — see «Date and time values» in GET /retail/cars.
text—Free-text search string.

New filters and new fields may be added without a version change — ignore a type or a field you do not know. version changes only if an existing field changes its meaning. The option lists leave out rare values: a make is listed when at least 20 active lots carry it, any other value from 5 lots — the auctions' feeds contain thousands of one-off spellings. A value that is not listed can still be sent as a filter. Option values are the auctions' own wording (e.g. RUNS AND DRIVES at Copart, Run & Drive at IAAI) — translate them to labels on your side.

Try it

GET/retail/settings — legacy

Legacy method. It keeps working and its format will not change, but it is no longer extended. For filters use GET /retail/filters: it returns every filter (this method covers only part of them) with its type and the exact parameter name.

Returns the available filter values as a plain object. The keys are not the parameter names of GET /retail/cars — use this table:

KeyShapeParameter of /retail/cars
makersstring[]makers[]
modelobject: make → string[]models[]
categorystring[]typeBody[]
transmission, fuelType, drive, title, locations, runsDrivesstring[]same name with []
primaryDamagestring[]primaryDamages[]
secondaryDamagestring[]secondaryDamages[]
year{ min, max } intminYear / maxYear
price{ min, max } numberminPrice / maxPrice
odometr{ min, max } intminOdometer / maxOdometer

Try it

GET/retail/cars/{id}

Full detail for one catalogue car — photo gallery and sale history. For shipping, use /calculate.

Try it

GET/retail/cars/{id}/images

All photos for a catalogue car (the full gallery is fetched on first request, then cached).

Response

{ "id": 12345, "vin": "…", "count": 24, "images": ["https://…jpg", …] }

Try it

GET/retail/cars/{id}/similar

Up to 12 lots similar to {id} — same make + model within ±3 years, or (if none) same make + body style. VIN-only, same as the catalogue.

Response

{ "data": [ { "id": 12346, "vin": "…", "make": "HONDA", "model": "CIVIC", … } ] }

Try it

GET/retail/popular

Top active lots ranked by popularity (views + engagement, decayed daily). VIN-only, same as the catalogue.

Query parameters

ParamDescription
limitNumber of lots to return, 1–50 (default 12).

Response

{ "data": [ { "id": 12345, "vin": "…", "make": "HONDA", … } ] }

Try it

GET/ground/auctions

The auctions you have ground tariffs for, with the number of yards in each. Use code as the auction parameter of the other /ground/* endpoints.

“Ground” = inland US delivery from the auction yard to the loading port. All /ground/* endpoints answer with your account's tariffs — the same numbers POST /calculate uses for a lot. Prices are in USD.

Response

{ "data": [
  { "code": "copart", "name": "Copart", "locations": 745, "sublot_locations": 144 },
  { "code": "iaai",   "name": "IAAI",   "locations": 243, "sublot_locations": 172 }
] }

sublot_locations — off-site (sublot) yards, priced separately from the auction's own yards.

Try it

GET/ground/locations

Reference list of the auction yards you have a tariff for — without prices. Returned in full (no paging), sorted by auction and name.

Query parameters (all optional)

ParamDescription
auctioncopart | iaai.
sublot1 — only off-site (sublot) yards, 0 — only the auction's own yards. Omit for both.
portLoading port code: NJ, GA, TX, CA, FL, WA, CAN.
zipUS ZIP of the yard (ZIP+4 is cut to 5 digits). Exact match.
qPart of the yard name or city.

Response

{ "count": 1, "data": [
  { "id": 1, "auction": "iaai", "sublot": false, "name": "Newburgh", "city": "Rock Tavern",
    "zip": "12575", "port": "PORT, NJ", "port_code": "NJ" }
] }

zip can be null — some yards are known by name only. id is stable and is what /ground/price?location_id= takes.

Try it

GET/ground/rates

All ground tariffs of your account in one call: every yard with its price. Returned in full (no paging) — load it once and cache it; updated_at of a row tells when its price last changed.

Query parameters (all optional)

ParamDescription
auction, sublot, port, zip, qSame filters as /ground/locations.
destinationlithuania (= ukraine, klaipeda) | poland | georgia. Applies the Florida rule below. Omit to get the tariffs as stored.

Response

{ "currency": "USD", "destination": null, "count": 1304, "data": [
  { "id": 1, "auction": "iaai", "sublot": false, "name": "Newburgh", "city": "Rock Tavern",
    "zip": "12575", "port": "PORT, NJ", "port_code": "NJ",
    "price": 300, "price_type": "ground", "surcharge": 0,
    "updated_at": "2026-07-23T20:17:07+00:00" }
] }

Fields of a tariff

FieldDescription
priceThe tariff in USD.
price_typeground — the inland leg only (yard → port); ocean freight is separate. total — your account is priced by one all-in figure per yard (inland + ocean together); nothing is added on top of it.
surchargePart of price added by the Florida rule below, else 0. The stored tariff = price − surcharge.
port, port_codeThe US port the car is loaded at.

Florida yards (destination)

Cars from PORT, FL yards going to Lithuania / Ukraine / Poland are loaded at PORT, GA for + $150. With destination set to one of those, such rows come back with port: "PORT, GA", surcharge: 150 and the higher price:

{ "id": 3957, "auction": "copart", "name": "… HOMESTEAD, FL, 33035",
  "port": "PORT, GA", "port_code": "GA",
  "price": 450, "price_type": "ground", "surcharge": 150 }

To Georgia, without destination, and for price_type: total tariffs nothing changes (PORT, FL, surcharge: 0). No other yard has a surcharge.

Try it

GET/ground/price

Ground price of one yard — by its id, by ZIP or by name. Use it when you know where the car stands and need the number without downloading the whole tariff list.

Query parameters

ParamDescription
location_idYard id from /ground/locations / /ground/rates. When given, nothing else is required.
auctioncopart | iaai. Required without location_id.
zipUS ZIP of the yard (ZIP+4 accepted). Tried first.
locationYard / city name as the auction shows it (Houston-North, TX - HOUSTON, Lorain, OH). Used when the ZIP is missing or unknown. At least one of zip / location is required without location_id.
sublot1 when the lot is an off-site (sublot) one — its yards are looked up first.
destinationSame as in /ground/rates (Florida rule).

Response

{ "currency": "USD", "destination": null, "matched_by": "zip",
  "rate": { "id": 1, "auction": "iaai", "sublot": false, "name": "Newburgh", "city": "Rock Tavern",
            "zip": "12575", "port": "PORT, NJ", "port_code": "NJ",
            "price": 300, "price_type": "ground", "surcharge": 0,
            "updated_at": "2026-07-23T20:17:07+00:00" } }

matched_by: location_id | zip | name. No tariff for the place → 404 { "message": "No ground tariff for this location." } — ask your manager for a price. To price a concrete lot (with ocean freight and the auction fee) use POST /calculate.

cURL

curl "https://base-auction.com/api/v1/ground/price?auction=iaai&zip=12575" \
  -H "X-Api-Key: lk_live_xxx"

Try it

Errors & limits

Errors return JSON: { "message": "…" } (validation errors also include an errors map).

StatusMeaning
401Missing or invalid API key.
403Browser request from a non-whitelisted domain.
404Retail car not found / not available; no ground tariff for the location.
422Validation error (bad/unknown destination, missing auction, lot not found).
429Per-minute rate limit or monthly quota exceeded.
502Failed to fetch the lot/images from the auction — retry.