{"openapi":"3.0.3","info":{"title":"LMN Open API","version":"1.34.0","description":"Partner-facing API for LMN inventory, orders, and fulfillment. Served at sandbox-api.lmnauto.com and api.lmnauto.com. All auth via the `x-api-key` header; sandbox keys start with `lmn_stg_`, production with `lmn_prd_`."},"servers":[{"url":"https://api.lmnauto.com","description":"Production"},{"url":"https://sandbox-api.lmnauto.com","description":"Sandbox"}],"components":{"securitySchemes":{"ApiKey":{"type":"apiKey","in":"header","name":"x-api-key"}},"parameters":{"IdempotencyKey":{"name":"Idempotency-Key","in":"header","required":true,"schema":{"type":"string","format":"uuid"},"description":"Client-generated UUID. Replaying the same key returns the original result without creating a new order."},"CursorParam":{"name":"cursor","in":"query","schema":{"type":"string"},"description":"Opaque cursor from a previous response's `next_cursor`."},"LimitParam":{"name":"limit","in":"query","schema":{"type":"integer","minimum":1,"maximum":200,"default":50},"description":"Page size. Default 50, max 200."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["code","message","request_id"],"properties":{"code":{"type":"string","description":"Stable machine-readable error code. Branch client logic on this, not `message`.","enum":["missing_api_key","invalid_api_key","ip_not_allowed","missing_idempotency_key","idempotency_key_reused","missing_max_bid","validation_error","vehicle_not_found","order_not_found","duplicate_order","past_order_cutoff","invalid_status_transition","invalid_cursor","rate_limited","dealer_upstream_unavailable","mixed_source_pagination_unsupported","internal_error"]},"message":{"type":"string","description":"Human-readable summary. May evolve between versions; do not branch on it."},"request_id":{"type":"string","pattern":"^req_[0-9a-f]{24}$"},"details":{"type":"object","additionalProperties":true,"description":"Optional structured context. Keys depend on the error `code`.","properties":{"issues":{"type":"array","description":"Set on `validation_error`. One entry per failing field.","items":{"type":"object","properties":{"path":{"type":"string"},"code":{"type":"string"},"message":{"type":"string"}}}},"existing_order_id":{"type":"string","description":"Set on `duplicate_order`."},"original_vehicle_id":{"type":"string","description":"Set on `idempotency_key_reused`."},"cutoff_at":{"type":"string","format":"date-time","description":"Set on `past_order_cutoff`."},"now":{"type":"string","format":"date-time"},"field":{"type":"string","description":"Set on `validation_error` when a single field triggered the error."}}}}}}},"Health":{"type":"object","required":["status","db","bq"],"properties":{"status":{"type":"string","enum":["ok","degraded"]},"db":{"type":"string","enum":["ok","fail"]},"bq":{"type":"string","enum":["ok","fail"]}}},"SourceEnum":{"type":"string","enum":["glovis","sk","aj","lotte","kcar","dealer"]},"AccidentGrade":{"type":"string","enum":["A","B","C","D","F"],"description":"Accident-history grade. Null for dealer rows."},"ExteriorGrade":{"type":"string","enum":["A","B","C","D","F"],"description":"Exterior condition letter (no E). For Glovis/KCar (and SK/AJ/Lotte rows that carry a numeric grade), derived from the 1–9 condition score (A=8–9, B=6–7, C=4–5, D=2–3, F=1). SK/AJ/Lotte rows that already carry a letter pass through unchanged."},"Pricing":{"type":"object","required":["listing_price","sold_price","discount_config","breakdown"],"properties":{"listing_price":{"type":"integer","minimum":0,"description":"Estimated final price in whole USD. Converted from KRW using the daily ECB rate cached server-side."},"sold_price":{"type":"integer","nullable":true,"minimum":0,"description":"Final sold price in whole USD. Null when auction_result is not `sold` or `negotiation_sold`."},"discount_config":{"type":"object","required":["bid_threshold","rate_below","rate_at_or_above","fixed_discount_amount","vehicle_discount_pct"],"additionalProperties":false,"description":"Always populated on both summary and detail (2026-05-26). For auction rows: bid-based fields drive the discount and `fixed_discount_amount` is 0. For dealer rows: bid-based fields are all 0 and `fixed_discount_amount` carries the entire economic effect (offsets the flat dealer fee). Partner computes auction discount as: `your_rate = your_bid_usd < bid_threshold ? rate_below : rate_at_or_above; your_bid_rate_discount_usd = ceil(your_bid_usd * your_rate / 100)`. Total discount = `your_bid_rate_discount_usd + fixed_discount_amount`. At settlement the same rule is applied against `purchase_price_usd` (the actual hammer price, which may be lower than `max_bid_amount_usd`). `vehicle_discount_pct` is a partner-specific whole-percent discount on the basis (0 for most partners); when > 0 the bid-based fields and `fixed_discount_amount` are all 0 and the percentage replaces them.","properties":{"bid_threshold":{"type":"integer","minimum":0,"description":"Bid amount in USD at which the rate switches. Bids strictly below use rate_below; bids at or above use rate_at_or_above. 0 for dealer rows (bid-based logic does not apply)."},"rate_below":{"type":"number","description":"Discount percentage applied when bid < bid_threshold. Example: 1.5 means 1.5%. 0 for dealer rows."},"rate_at_or_above":{"type":"number","description":"Discount percentage applied when bid >= bid_threshold. Example: 2 means 2%. 0 for dealer rows."},"fixed_discount_amount":{"type":"integer","minimum":0,"description":"Flat USD discount applied at quote time, independent of bid. Subtracted from estimated_landed. 0 for auction rows today; non-zero for dealer rows (currently 300, offsets the flat dealer_fee)."},"vehicle_discount_pct":{"type":"integer","minimum":0,"maximum":100,"description":"Whole-percent, partner-specific discount applied to the vehicle basis BEFORE fees/freight/LMN. 0 for partners without a configured discount (the common case). When > 0, the bid-based fields (bid_threshold/rate_below/rate_at_or_above) and dealer fixed_discount_amount are all 0 — the percentage replaces them. See the Vehicles guide 'Recomputing landed cost'."}}},"breakdown":{"type":"object","description":"Illustrative landed-cost breakdown — always populated on both summary and detail (2026-05-26). `estimated_landed` is a single-bid hypothetical computed against LMN's internal basis price; for an exact total at the partner's own bid, recompute using `auction_fee_config` (detail only) and `discount_config`. See the Vehicles endpoint guide section 'Recomputing landed cost' for the formula, rounding rules, and FX-rounding / hammer-vs-max-bid caveats.","properties":{"auction_fee":{"type":"integer","nullable":true,"description":"Illustrative auction house buyer fee in whole USD, calculated from auction_fee_config evaluated against LMN's internal basis price (sold_price if available, otherwise market-derived final-price estimate, otherwise auction starting price). 0 for dealer rows."},"dealer_fee":{"type":"integer","description":"Flat dealer fee in whole USD. 0 for auction rows; 300 for dealer rows. Independent of response fx (not KRW-derived)."},"lmn_commission":{"type":"integer","nullable":true,"description":"LMN service fee in whole USD. Pilot constant."},"ocean_freight":{"type":"integer","nullable":true,"description":"Ocean freight to destination port in whole USD (includes Korean-side export logistics)."},"estimated_landed":{"type":"integer","nullable":true,"description":"Illustrative single-bid total in whole USD. Auction: basis + auction_fee + lmn_commission + ocean_freight − (bid_rate_discount + fixed_discount_amount), where basis = sold_price if available, otherwise market-derived final-price estimate, otherwise auction starting price; bid_rate_discount = ceil(basis × rate / 100). Dealer: listing_price + dealer_fee + lmn_commission + ocean_freight − fixed_discount_amount. For exact auction totals at the partner's own bid, recompute via auction_fee_config + discount_config."}}}}},"PricingDetail":{"allOf":[{"$ref":"#/components/schemas/Pricing"},{"type":"object","properties":{"auction_fee_config":{"type":"object","nullable":true,"required":["percentage","minimum","maximum"],"additionalProperties":false,"description":"Auction house buyer-fee rule for this vehicle's source/category, converted to USD for partner display. Formula used internally: calculate the source-specific KRW percentage fee, apply source/category KRW min/max caps, then convert the final fee to whole USD. Null for dealer vehicles.","properties":{"percentage":{"type":"number","description":"Percent value, not decimal. Example: 2.2 means 2.2%, and AJ returns 2.585."},"minimum":{"type":"integer","minimum":0,"nullable":true,"description":"Source/category minimum cap converted to whole USD with the same FX snapshot used by the response."},"maximum":{"type":"integer","minimum":0,"nullable":true,"description":"Source/category maximum cap converted to whole USD with the same FX snapshot used by the response."}}},"history":{"type":"array","description":"Same-vehicle pricing history for the current physical car, matched internally by Korean license plate across auction appearances. Empty when the vehicle has no plate or no prior listing history. Each row's `vehicle_id` is the listing ID for that auction round and may differ from the current response `id`.","items":{"type":"object","required":["vehicle_id","auction_date","price","result"],"properties":{"vehicle_id":{"type":"string","description":"Auction listing/appearance ID for this history row. This may differ across rows because the same physical car receives a new listing ID when it is re-listed."},"auction_date":{"type":"string","format":"date"},"price":{"type":"integer","description":"Listing/start price for this auction appearance, converted to whole USD."},"result":{"type":"string","description":"Auction result for this appearance."}}}},"market_assessment":{"$ref":"#/components/schemas/MarketAssessment","description":"One-line server-side verdict of the current listed/estimated price vs. comparable sales. Null for dealer vehicles."}}}]},"SimilarSale":{"type":"object","required":["vehicle_id","vin","license_plate","year","mileage_km","starting_price","sold_price","auction_date","auction_result"],"properties":{"vehicle_id":{"type":"string","description":"ID of the comparable sale. The auction-house prefix of this ID (glovis_, sk_, aj_, lotte_, kcar_) implicitly identifies the source. Usable directly with GET /v1/vehicles/{id}."},"vin":{"type":"string","nullable":true,"description":"VIN for the comparable vehicle when the auction source provides it."},"license_plate":{"type":"string","nullable":true,"description":"Korean license plate for the comparable vehicle when available."},"trim":{"type":"string","nullable":true},"year":{"type":"integer"},"mileage_km":{"type":"integer","minimum":0},"accident_grade":{"type":"string","nullable":true},"exterior_grade":{"type":"string","nullable":true},"starting_price":{"type":"integer","minimum":0,"description":"Auction starting price in whole USD."},"sold_price":{"type":"integer","nullable":true,"minimum":0,"description":"Final sold price in whole USD. Null when auction_result is not `sold` or `negotiation_sold`."},"auction_date":{"type":"string","description":"Auction date in KST (ISO 8601 with +09:00 offset)."},"auction_result":{"type":"string","description":"One of: upcoming, sold, negotiation_sold, no_bid, negotiation_requested."}}},"SimilarUpcoming":{"type":"object","required":["vehicle_id","vin","license_plate","year","mileage_km","starting_price","auction_date","auction_result"],"properties":{"vehicle_id":{"type":"string","description":"ID of the comparable upcoming listing. Usable directly with GET /v1/vehicles/{id}."},"vin":{"type":"string","nullable":true,"description":"VIN for the comparable vehicle when the auction source provides it."},"license_plate":{"type":"string","nullable":true,"description":"Korean license plate for the comparable vehicle when available."},"trim":{"type":"string","nullable":true},"year":{"type":"integer"},"mileage_km":{"type":"integer","minimum":0},"accident_grade":{"type":"string","nullable":true},"exterior_grade":{"type":"string","nullable":true},"starting_price":{"type":"integer","minimum":0,"description":"Auction starting price in whole USD."},"auction_date":{"type":"string","description":"Auction date in KST (ISO 8601 with +09:00 offset)."},"auction_result":{"type":"string","enum":["upcoming"],"description":"Always `upcoming`."}}},"Comparables":{"type":"object","required":["past_sales","upcoming_sales"],"description":"Comparable vehicles for the current listing. These are separate from `pricing` because they are market inventory signals, not price components for this vehicle.","properties":{"past_sales":{"type":"array","description":"Up to 20 sold comparable cars matching the similar-cars definition: same make + model, model year ±1, mileage ±20,000 km, within the past 4 weeks. Excludes the target vehicle and same-plate re-listings. Empty array for dealer vehicles.","items":{"$ref":"#/components/schemas/SimilarSale"}},"upcoming_sales":{"type":"array","description":"Up to 20 future upcoming comparable auction options using the same matching rules as past_sales.","items":{"$ref":"#/components/schemas/SimilarUpcoming"}}}},"MarketAssessment":{"type":"object","nullable":true,"required":["label","comp_count","market_median","diff_percent","explanation"],"description":"Server-side one-line verdict of the current listed/estimated price vs. comparable sold cars from the past 4 weeks (same make+model · year ±1 · mileage ±20,000 km). Five labels: great / good / fair / wait / limited.","properties":{"label":{"type":"string","enum":["great","good","fair","wait","limited"],"description":"great (>15% below median), good (5–15% below), fair (±5%), wait (>5% above median), limited (<3 comps — assessment unreliable)."},"comp_count":{"type":"integer","minimum":0,"description":"Number of sold comparables used."},"market_median":{"type":"integer","minimum":0,"description":"Median starting price of comparables in whole USD. 0 when label=limited."},"diff_percent":{"type":"number","description":"Percent the current listed/estimated price sits below (positive) or above (negative) the market median."},"explanation":{"type":"string","description":"Human-readable one-line summary suitable for UI surfacing."},"price_drop":{"type":"object","nullable":true,"description":"Present when the same vehicle has appeared in previous auctions and its starting price has moved.","properties":{"rounds":{"type":"integer","minimum":2},"drop_percent":{"type":"number","description":"Percent drop from first round to current (positive = dropped)."}}}}},"VehicleSummary":{"type":"object","required":["id","source","make","model","year","mileage_km","pricing"],"properties":{"id":{"type":"string","description":"Auction listing/appearance ID for this specific source listing, for example `glovis_20260428_1069_2126`. This is the ID to use in `GET /v1/vehicles/{id}` and `POST /v1/orders`. It is not a permanent physical-car ID; the same car may receive a different `id` when re-listed in another auction round. Use `license_plate` on detail responses when you need the physical-car identifier."},"source":{"$ref":"#/components/schemas/SourceEnum"},"make":{"type":"string"},"model":{"type":"string"},"trim":{"type":"string","nullable":true},"year":{"type":"integer"},"mileage_km":{"type":"integer","minimum":0},"fuel":{"type":"string","nullable":true,"description":"Lowercase token (gasoline, diesel, hybrid, electric, lpg). May be null if upstream data is missing."},"transmission":{"type":"string","nullable":true,"enum":["auto","manual","cvt","dct",null],"description":"Lowercase token. May be null if upstream data is missing."},"color":{"type":"string","nullable":true},"engine_cc":{"type":"integer","nullable":true},"drivetrain":{"type":"string","nullable":true,"description":"Upstream drivetrain token (typical values: FWD, RWD, AWD, 4WD, 2WD). Not strictly enumerated — codegen clients should treat unknown tokens as opaque strings rather than rejecting them."},"options":{"type":"array","items":{"type":"string"}},"accident_grade":{"$ref":"#/components/schemas/AccidentGrade","nullable":true},"exterior_grade":{"$ref":"#/components/schemas/ExteriorGrade","nullable":true},"auction_date":{"type":"string","format":"date-time","nullable":true,"description":"KST offset ISO 8601. Null for dealer rows."},"order_cutoff_at":{"type":"string","format":"date-time","nullable":true,"description":"Orders must be placed before this timestamp. Equals `auction_date` − N minutes, where N is your integration's pre-negotiated lead time (default 1440 = 24h). Shekel: N=60 (1h, no inspection required). Null for dealer/buy-now sources."},"thumbnail_url":{"type":"string","format":"uri","nullable":true},"pricing":{"$ref":"#/components/schemas/Pricing"},"auction_result":{"type":"string","nullable":true,"enum":["upcoming","no_bid","sold","negotiation_sold","negotiation_requested",null]},"auction_count":{"type":"integer","nullable":true}}},"VehicleDetail":{"allOf":[{"$ref":"#/components/schemas/VehicleSummary"},{"type":"object","properties":{"vin":{"type":"string","nullable":true},"license_plate":{"type":"string","nullable":true},"photos":{"type":"array","items":{"type":"string","format":"uri"}},"photo_tags":{"type":"array","items":{"$ref":"#/components/schemas/PhotoTag"}},"body_condition":{"$ref":"#/components/schemas/BodyCondition"},"inspection_report":{"type":"object","nullable":true,"additionalProperties":true},"comparables":{"$ref":"#/components/schemas/Comparables"},"pricing":{"$ref":"#/components/schemas/PricingDetail"}}}]},"PhotoTag":{"type":"object","required":["url","tag"],"additionalProperties":false,"properties":{"url":{"type":"string","format":"uri"},"tag":{"type":"string","enum":["front","side_l","side_r","rear","interior","dashboard","front_seats","rear_seats","trunk","engine","odometer","vin","other"]}}},"BodyCondition":{"type":"object","nullable":true,"description":"Partner-safe body condition data. `image_url` is returned only for LMN-mirrored HTTPS media; upstream auction-site image URLs are not exposed.","required":["image_url","panels"],"properties":{"image_url":{"type":"string","format":"uri","nullable":true},"panels":{"type":"array","items":{"$ref":"#/components/schemas/BodyConditionPanel"}}}},"BodyConditionPanel":{"type":"object","required":["panel_id","panel_type","damage_code","damage_codes","label","description","severity"],"properties":{"panel_id":{"type":"string"},"panel_type":{"type":"string","nullable":true},"damage_code":{"type":"string"},"damage_codes":{"type":"array","items":{"type":"string"}},"label":{"type":"string","description":"English panel label."},"description":{"type":"string","nullable":true},"severity":{"type":"string","nullable":true}}},"Facets":{"type":"object","required":["makes","models","fuels","transmissions","sources","as_of"],"properties":{"makes":{"type":"array","items":{"type":"string"}},"models":{"type":"object","additionalProperties":{"type":"array","items":{"type":"string"}},"description":"Keyed by make. e.g., {\"Toyota\":[\"Camry\",\"RAV4\"], \"Hyundai\":[...]}"},"fuels":{"type":"array","items":{"type":"string"}},"transmissions":{"type":"array","items":{"type":"string"}},"sources":{"type":"array","items":{"$ref":"#/components/schemas/SourceEnum"}},"as_of":{"type":"string","format":"date-time","nullable":true,"description":"Snapshot timestamp for the underlying inventory cache. 5-minute cache."}}},"VehicleList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/VehicleSummary"}},"next_cursor":{"type":"string","nullable":true}}},"OrderStatus":{"type":"string","enum":["placed","inspection_in_progress","inspection_ready","acquiring","secured","export_processing","in_transit","customs","delivered","failed","cancelled"]},"Shipment":{"type":"object","nullable":true,"properties":{"vessel_name":{"type":"string"},"voyage":{"type":"string"},"bl_number":{"type":"string","description":"Bill of Lading number"},"container_id":{"type":"string"},"etd_korea":{"type":"string","format":"date","description":"Departure from Korea"},"eta_destination":{"type":"string","format":"date","description":"Arrival at destination port"},"destination_port":{"type":"string"}}},"Order":{"type":"object","required":["id","vehicle_id","status","amounts","options","created_at","updated_at"],"properties":{"id":{"type":"string","description":"ULID."},"vehicle_id":{"type":"string","description":"Auction listing/appearance ID the order was placed against. This is not a permanent physical-car ID."},"vin":{"type":"string","nullable":true,"description":"VIN snapshotted at order creation (Shekel #6). Null when the upstream listing_price has no VIN. Self-contained — webhook consumers can match dealer records without GET /v1/vehicles/{id}."},"license_plate":{"type":"string","nullable":true,"description":"Korean license plate snapshotted at order creation. Null when upstream listing_price has no plate."},"status":{"$ref":"#/components/schemas/OrderStatus"},"amounts":{"type":"object","required":["purchase_price_usd","auction_fee_usd"],"properties":{"purchase_price_usd":{"type":"integer","nullable":true,"description":"Whole USD. Null until status=secured."},"auction_fee_usd":{"type":"integer","nullable":true}}},"pricing":{"allOf":[{"$ref":"#/components/schemas/PricingDetail"}],"nullable":true,"description":"Frozen at-order-time pricing breakdown, identical shape to GET /v1/vehicles/{id} `pricing`. Null when the order has no creation snapshot or no landed-cost estimate (legacy/pre-feature rows, or a config/FX failure at creation). For auction orders `history` is [] and `market_assessment` is null (vehicle-level fields not snapshotted on auction orders)."},"max_bid_amount_usd":{"type":"integer","nullable":true},"is_highest_bid":{"type":"boolean","nullable":true,"description":"True if this order carries the highest active max_bid for the vehicle at response time. Null for non-auction sources."},"current_max_bid_usd":{"type":"integer","nullable":true,"description":"Highest active max_bid across all partners for this vehicle."},"fx_rate":{"type":"number","nullable":true,"description":"KRW per USD rate **locked at order creation** (POST /v1/orders). Unchanged by PATCH/status updates. Used to compute `amounts.purchase_price_usd` when the order transitions to `secured`. Null when the upstream FX provider was unavailable at creation time."},"auction_date":{"type":"string","format":"date-time","nullable":true},"order_cutoff_at":{"type":"string","format":"date-time","nullable":true},"acquired_at":{"type":"string","format":"date-time","nullable":true},"shipped_at":{"type":"string","format":"date-time","nullable":true},"shipment":{"$ref":"#/components/schemas/Shipment"},"failure_reason":{"type":"string","nullable":true,"enum":["outbid","outbid_internally","vehicle_unavailable","auction_cancelled","auction_passed","seller_withdrew",null]},"cancellation_reason":{"type":"string","nullable":true},"options":{"type":"array","items":{"type":"string"},"description":"Vehicle feature names (e.g. `Sunroof`, `Leather Seats`, `LED Headlamps`) snapshotted from the vehicle at order creation. Mirrors `VehicleDetail.options` byte-for-byte so consumers don't need a follow-up `GET /v1/vehicles/{id}`. English Title-case for both auction and dealer (`encar_*`) sources — dealer values are translated via the same dictionary the consumer site uses. Empty array when the upstream listing exposed no options (or for orders created before v1.21). Not to be confused with the `options_include` *query* parameter on `GET /v1/vehicles`, which takes snake_case tokens."},"created_at":{"type":"string","format":"date-time"},"updated_at":{"type":"string","format":"date-time"}}},"OrderList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Order"}},"next_cursor":{"type":"string","nullable":true}}},"OrderEvent":{"type":"object","description":"A row from the LMN-side webhook event log. Surfaced via GET /v1/orders/{id}/events for self-service delivery debugging.","required":["id","type","delivery_status","attempts","created_at","payload"],"properties":{"id":{"type":"string","description":"Webhook event ID (matches the `id` in the delivered payload)."},"type":{"type":"string","enum":["order.status_changed","order.auction_rescheduled","order.price_updated","order.re_auctioned"],"description":"Event type. Four LMN-driven types — partner-driven changes (POSTs/DELETEs) do not fire events."},"delivery_status":{"type":"string","enum":["pending","delivering","delivered","delivery_failed","delivery_skipped"],"description":"Current delivery state. `delivery_skipped` means the partner has no webhook URL configured."},"attempts":{"type":"integer","description":"Total delivery attempts so far (including failed retries)."},"last_response_code":{"type":"integer","nullable":true,"description":"HTTP status of the most recent delivery attempt; null if never attempted."},"next_retry_at":{"type":"string","format":"date-time","nullable":true,"description":"When the next delivery retry is scheduled. KST ISO 8601 with `+09:00` offset."},"created_at":{"type":"string","format":"date-time","description":"When the event was enqueued. KST ISO 8601 with `+09:00` offset."},"delivered_at":{"type":"string","format":"date-time","nullable":true,"description":"When delivery succeeded; null if not yet delivered. KST ISO 8601 with `+09:00` offset."},"payload":{"type":"object","additionalProperties":true,"description":"The exact JSON payload sent (or to be sent) to the partner webhook URL."}}},"OrderEventList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/OrderEvent"}},"next_cursor":{"type":"string","nullable":true,"description":"Opaque cursor for the next page; null when no more rows."}}},"CreateOrderRequest":{"type":"object","required":["vehicle_id"],"properties":{"vehicle_id":{"type":"string","minLength":1,"description":"Listing ID from `GET /v1/vehicles` or `GET /v1/vehicles/{id}`. Accepts auction IDs (`glovis_*`, `sk_*`, `aj_*`, `lotte_*`, `kcar_*`) and dealer IDs (`encar_*`, `danawa_*`, `source: \"dealer\"`). For auction IDs, use the current listing's ID — do not use old IDs from `pricing.history`. Dealer IDs resolve via a live proxy to the respective dealer upstream; if the upstream is unreachable, this endpoint returns `503 dealer_upstream_unavailable`; if Encar returns 404 or a parseable detail page whose advertisement status is `SOLD`, this endpoint returns `404 vehicle_not_found`."},"max_bid_amount_usd":{"type":"integer","minimum":1,"nullable":true,"description":"Required for auction sources (glovis/sk/aj/lotte/kcar) in an upcoming round. Null/omitted for buy-now: auction vehicles with `auction_result: no_bid` and all dealer (`encar_*`, `danawa_*`) listings. Non-null dealer values return `400 validation_error`."}}},"StatusUpdateRequest":{"type":"object","required":["status"],"description":"Partner-pushed status update. Partners own only the destination-side transitions: `customs` (from `in_transit`) and `delivered` (from `customs`). The legacy `fulfillment_detail` field is removed — sending it returns `400 validation_error`. Use `/v1/orders/{id}/sandbox-status` for sandbox lifecycle simulation.","properties":{"status":{"type":"string","enum":["customs","delivered"],"description":"Partner-writable target. `customs` requires the order to be `in_transit`; `delivered` requires `customs`. Any other value returns `403 invalid_status_transition` (`details.reason: partner_not_authorized`); a valid value from the wrong predecessor returns `409` (`details.reason: out_of_sequence`)."},"occurred_at":{"type":"string","format":"date-time"},"notes":{"type":"string"}}}},"responses":{"UnauthorizedError":{"description":"API key missing or invalid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ForbiddenError":{"description":"IP not in allowlist","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"NotFoundError":{"description":"Resource not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ValidationError":{"description":"Request validation failed. See details.issues for per-field errors.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"ConflictError":{"description":"Request conflicts with current resource state","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"RateLimitError":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"DealerUpstreamUnavailable":{"description":"All dealer upstreams (Encar and Danawa) returned an error or an unexpected response shape. Pure dealer requests (`source=dealer`) fail closed only when **all** dealer upstreams are down; if exactly one is down, a 200 is returned with the surviving source's rows and an `X-LMN-Partial-Dealer-Unavailable` header naming the failed source(s). Mixed auction+dealer requests never return 503 — auction rows are always returned even when all dealer upstreams fail (see `/v1/vehicles` 200 response).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}}}},"security":[{"ApiKey":[]}],"paths":{"/v1/health":{"get":{"operationId":"getHealth","security":[],"summary":"Health check","description":"Checks DB and BigQuery connectivity. Public — no API key required.","responses":{"200":{"description":"All systems healthy","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}},"503":{"description":"Degraded — DB or BigQuery unreachable","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Health"}}}}}}},"/v1/openapi.json":{"get":{"operationId":"getOpenApiSpec","security":[],"summary":"This OpenAPI spec","description":"Returns the live OpenAPI 3.1 document describing this API. Public.","responses":{"200":{"description":"OpenAPI document","content":{"application/json":{"schema":{"type":"object"}}}}}}},"/v1/vehicles/facets":{"get":{"operationId":"getVehicleFacets","summary":"Filter value aggregations","description":"Distinct filter values in the live catalog (last ~14 days). Intended for populating browse-UI dropdowns. Cached 5 minutes server-side; `as_of` reflects the snapshot time.","parameters":[{"name":"source","in":"query","schema":{"type":"string"},"description":"CSV of source enum values to scope the facets (e.g., `glovis,sk`)."}],"responses":{"200":{"description":"Facet aggregation","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Facets"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/v1/vehicles":{"get":{"operationId":"listVehicles","summary":"List inventory (filterable, paginated)","description":"Paginated vehicle list across auction houses and dealer inventory.\n\n**Sources:** auction houses (`glovis`, `sk`, `aj`, `lotte`, `kcar`) and dealer (`dealer`, currently sourced from encar). Default sort `auction_date_asc`.\n\n**Dealer constraints:**\n- `source=dealer` (alone or mixed) requires `make`. Multi-value `make` is accepted as CSV, e.g. `Hyundai,Kia`; the API fans out to one upstream dealer request per manufacturer. Multi-value `model` is also accepted for dealer rows; known make/model pairs are fanned out, e.g. `make=Hyundai,Kia&model=Avante,K5` becomes Hyundai Avante plus Kia K5 searches.\n- Combining `source=dealer` with auction-only filters (`auction_status`, `accident_grade`, `exterior_grade`, `auction_date_from`/`to`, `auction_count_min`/`max`) returns `400` — these filters are meaningless against dealer rows.\n- Mixed auction+dealer requests are first-page only: passing `cursor` with a mixed `source` returns `400 mixed_source_pagination_unsupported`. Paginate each source separately.\n- Dealer page size is capped at 48 server-side. If `limit` exceeds 48 with dealer in scope, the response includes `X-LMN-Dealer-Page-Max: 48`.\n- When `sort=auction_date_asc` is used for a mixed query, the page budget is split between auction (sorted by date) and dealer (sorted by `year_desc` since dealer rows have no auction date).","parameters":[{"name":"make","in":"query","schema":{"type":"string"},"description":"CSV of makes, e.g., `Toyota,Honda`."},{"name":"model","in":"query","schema":{"type":"string"},"description":"Model filter. For dealer rows this may be CSV when `make` is CSV; known make/model pairs are fanned out."},{"name":"year_min","in":"query","schema":{"type":"integer"}},{"name":"year_max","in":"query","schema":{"type":"integer"}},{"name":"mileage_max_km","in":"query","schema":{"type":"integer"}},{"name":"price_min_usd","in":"query","schema":{"type":"integer"}},{"name":"price_max_usd","in":"query","schema":{"type":"integer"}},{"name":"keyword","in":"query","schema":{"type":"string"},"description":"Free-text search across make/model/trim tokens."},{"name":"body_style","in":"query","schema":{"type":"string","enum":["van"]},"description":"Heuristic trim/model text filter for 2-seat/cargo van variants such as Kia Morning Van."},{"name":"source","in":"query","schema":{"type":"string"},"description":"CSV of source enum values: `glovis`, `sk`, `aj`, `lotte`, `kcar`, `dealer`. See operation description for dealer-specific rules (requires `make`, single `make` only, no combination with auction-only filters, no pagination across mixed source)."},{"name":"fuel","in":"query","schema":{"type":"string"},"description":"CSV of fuel tokens (case-insensitive). NOT `fuel_type` — that's the BigQuery column, not the API param."},{"name":"transmission","in":"query","schema":{"type":"string"},"description":"CSV of transmission tokens. Accepts `auto`/`manual`/`cvt`/`dct` (mapped to data values) or raw `A/T`/`M/T`. Singular `transmission` — the plural `transmissions` is the response array name on `GET /v1/vehicles/facets`, NOT the filter param."},{"name":"color","in":"query","schema":{"type":"string"},"description":"Exterior color. A single value is honored (dealer + auction); multi-value CSV is dropped (Encar's DSL rejects multi-color). Translated to the source's color vocabulary."},{"name":"accident_grade","in":"query","schema":{"type":"string"},"description":"CSV of A/B/C/D/F. Dealer rows (null grade) silently excluded — see `X-LMN-Filtered-Out` header."},{"name":"exterior_grade","in":"query","schema":{"type":"string"},"description":"CSV of A/B/C/D/F."},{"name":"options_include","in":"query","schema":{"type":"string"},"description":"CSV of snake_case option tokens (e.g., `sunroof,leather_seats`). AND semantics — a vehicle must have all listed options. For `source=dealer`, applied server-side via Encar's native option facets across the full 62-option catalog; two tokens (`panoramic_sunroof`, `dashcam`) are not available for dealer and return `400 validation_error` (`details.field: options_include`) — they still work on auction sources. Full dealer token list in the Vehicles guide."},{"name":"auction_status","in":"query","schema":{"type":"string"},"description":"CSV exact auction result filter: `upcoming`, `sold`, `negotiation_sold`, `no_bid`, `negotiation_requested`."},{"name":"auction_date_from","in":"query","schema":{"type":"string","format":"date"},"description":"Defaults to today (Asia/Seoul) when omitted — only auctions on/after this date are returned. Pass an explicit past date to include historical inventory."},{"name":"auction_date_to","in":"query","schema":{"type":"string","format":"date"}},{"name":"auction_count_min","in":"query","schema":{"type":"integer"}},{"name":"auction_count_max","in":"query","schema":{"type":"integer"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["auction_date_asc","price_asc","price_desc","year_desc","mileage_asc"],"default":"auction_date_asc"}},{"$ref":"#/components/parameters/CursorParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Paginated list of vehicle summaries. May be partial for mixed auction+dealer requests when the dealer upstream is unavailable — see `X-LMN-Partial-Dealer-Unavailable`.","headers":{"X-LMN-Filtered-Out":{"schema":{"type":"string","example":"dealer=3"},"description":"Set when auction-specific filters silently excluded rows (e.g., dealer rows excluded because the request also applied `auction_status`)."},"X-LMN-Partial-Dealer-Unavailable":{"schema":{"type":"string","example":"encar"},"description":"CSV of failed dealer source names (`encar` | `danawa`, e.g. `encar` or `encar,danawa`). Set when one or more dealer upstreams failed but at least one survived (partial rows returned). Pure dealer requests return `503` only when **all** dealer upstreams are simultaneously down."},"X-LMN-Dealer-Page-Max":{"schema":{"type":"string","example":"48"},"description":"Set when `limit > 48` AND `source` includes `dealer`. The dealer half of the response is capped at 48 server-side; paginate via `cursor` to retrieve more dealer rows."}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleList"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"429":{"$ref":"#/components/responses/RateLimitError"},"503":{"$ref":"#/components/responses/DealerUpstreamUnavailable"}}}},"/v1/vehicles/{id}":{"get":{"operationId":"getVehicle","summary":"Vehicle detail","description":"Full vehicle detail including VIN, photos, body condition, inspection report, and price breakdown.\n\n**Dealer detail:** When the `id` starts with `encar_` the response is fetched live from the dealer (encar) upstream. Pricing breakdown for dealer rows: `auction_fee` is `0`, `dealer_fee` is `300` USD (flat), and `discount_config.fixed_discount_amount` is `300` USD (offsets the dealer fee). `auction_fee_config` is `null`, comparables are empty, and `discount_config` is populated but bid-based fields are zeroed. Dealer `body_condition` / `inspection_report` are populated whenever Encar's inspection page is reachable — including clean cars (zero damage, empty `panels`, populated mechanical `checklist[]`). `inspection_report.dealer_inspection` carries the damage counts plus `vehicle_info`, `overall_status[]`, `photos[]`, `certification`, `registration_no`, and insurance history (`insurance_history` / `insurance_amount`, from a separate record upstream). Both fields are `null` only when Encar has no inspection record (upstream 404) or the fetch fails transiently. If the dealer detail upstream is unreachable or returns an unexpected response shape, this endpoint returns `503 dealer_upstream_unavailable`; an upstream 404 or a parseable Encar detail page whose advertisement status is `SOLD` is surfaced as `404 vehicle_not_found`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"},"description":"Vehicle ID — either an auction prefix (`glovis_…`, `sk_…`, `aj_…`, `lotte_…`, `kcar_…`) or `encar_<numeric>` for dealer rows."}],"responses":{"200":{"description":"Vehicle detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VehicleDetail"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"429":{"$ref":"#/components/responses/RateLimitError"},"503":{"$ref":"#/components/responses/DealerUpstreamUnavailable"}}}},"/v1/orders":{"post":{"operationId":"createOrder","summary":"Create an order","description":"Creates an order (status `placed`) against a vehicle. For auctions, must be placed before `order_cutoff_at`. Replay the same Idempotency-Key to retrieve the original result.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderRequest"}}}},"responses":{"200":{"description":"Idempotent replay — existing order returned unchanged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"201":{"description":"Order created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"description":"Conflict — `duplicate_order`, `past_order_cutoff`, or `invalid_status_transition`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Semantic error — e.g., `idempotency_key_reused` (key used previously with a different vehicle_id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimitError"},"503":{"$ref":"#/components/responses/DealerUpstreamUnavailable"}}},"get":{"operationId":"listOrders","summary":"List orders for the authenticated partner","parameters":[{"name":"ids","in":"query","schema":{"type":"string"},"description":"CSV, up to 100 order IDs."},{"name":"status","in":"query","schema":{"type":"string"},"description":"CSV of `OrderStatus` values."},{"name":"from","in":"query","schema":{"type":"string","format":"date-time"},"description":"Lower bound on `created_at`. Requires `to`."},{"name":"to","in":"query","schema":{"type":"string","format":"date-time"}},{"name":"sort","in":"query","schema":{"type":"string","enum":["created_desc","created_asc","auction_date_asc","updated_desc"],"default":"created_desc"}},{"$ref":"#/components/parameters/CursorParam"},{"$ref":"#/components/parameters/LimitParam"}],"responses":{"200":{"description":"Paginated order list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderList"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/v1/orders/backfill":{"post":{"operationId":"createBackfillOrder","summary":"Create an order from LMN snapshot fallback","description":"Partner-authenticated backfill endpoint with the same request body and response shape as `POST /v1/orders`. LMN first attempts normal live order creation and captures a fresh snapshot. If the vehicle is no longer live (`SOLD`, `WAIT`, deleted, or 404), LMN creates the order from the latest stored vehicle snapshot for the authenticated partner when one exists. If neither live data nor stored snapshot exists, returns `404 vehicle_not_found`.","parameters":[{"$ref":"#/components/parameters/IdempotencyKey"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateOrderRequest"}}}},"responses":{"200":{"description":"Idempotent replay — existing order returned unchanged","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"201":{"description":"Order created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"description":"Conflict — `duplicate_order`, `past_order_cutoff`, or `invalid_status_transition`.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"422":{"description":"Semantic error — e.g., `idempotency_key_reused` (key used previously with a different vehicle_id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"429":{"$ref":"#/components/responses/RateLimitError"},"503":{"$ref":"#/components/responses/DealerUpstreamUnavailable"}}}},"/v1/orders/{id}":{"get":{"operationId":"getOrder","summary":"Order detail","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order detail","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"429":{"$ref":"#/components/responses/RateLimitError"}}},"delete":{"operationId":"cancelOrder","summary":"Cancel an order","description":"Allowed only from `placed` status. Sets `status=cancelled`, `cancellation_reason=dealer_cancelled`. Any other starting status returns `409 invalid_status_transition`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Order cancelled","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"$ref":"#/components/responses/ConflictError"},"429":{"$ref":"#/components/responses/RateLimitError"}}},"patch":{"operationId":"updateOrder","summary":"Update order max bid","description":"Update `max_bid_amount_usd` on an existing order. Allowed only while `status=placed` and before `order_cutoff_at`. Returns `409 invalid_status_transition` if status has moved past placed, and `409 past_order_cutoff` if the cutoff has elapsed. Recomputes `is_highest_bid` and `current_max_bid_usd` across all active orders on the vehicle.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["max_bid_amount_usd"],"properties":{"max_bid_amount_usd":{"type":"integer","minimum":1,"description":"New maximum bid in whole USD. Must be a positive integer."}}}}}},"responses":{"200":{"description":"Order updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"$ref":"#/components/responses/ConflictError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/v1/orders/{id}/status":{"post":{"operationId":"pushOrderStatus","summary":"Push fulfillment/status update","description":"Partner-pushed status change. Permits only the destination-side transitions `customs` (from `in_transit`) and `delivered` (from `customs`). The legacy `fulfillment_detail` field is removed. Use `/v1/orders/{id}/sandbox-status` for sandbox lifecycle simulation.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatusUpdateRequest"}}}},"responses":{"200":{"description":"Status updated","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Order"}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"$ref":"#/components/responses/ConflictError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/v1/orders/{id}/sandbox-status":{"post":{"operationId":"simulateSandboxOrderStatus","summary":"Sandbox-only status simulation","description":"Sandbox helper for webhook testing. Available only on sandbox hosts with sandbox API keys. Setting `status` enqueues `order.status_changed`.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["placed","inspection_in_progress","inspection_ready","acquiring","secured","export_processing","in_transit","customs","delivered","failed","cancelled"]},"purchase_price_usd":{"type":"integer","minimum":0},"auction_fee_usd":{"type":"integer","minimum":0,"nullable":true},"failure_reason":{"type":"string","nullable":true},"cancellation_reason":{"type":"string","nullable":true,"maxLength":64},"occurred_at":{"type":"string","format":"date-time"}}}}}},"responses":{"200":{"description":"Order status simulated and webhook event enqueued when applicable","content":{"application/json":{"schema":{"type":"object","additionalProperties":true}}}},"400":{"$ref":"#/components/responses/ValidationError"},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"409":{"$ref":"#/components/responses/ConflictError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}},"/v1/orders/{id}/events":{"get":{"operationId":"listOrderEvents","summary":"Order event history","description":"Chronological list of LMN-side webhook events for the order, with delivery state. Useful for self-service debugging — `did I miss a webhook?` — without contacting LMN support.","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque pagination cursor returned in `next_cursor`."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100,"default":50}}],"responses":{"200":{"description":"Event list","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OrderEventList"}}}},"401":{"$ref":"#/components/responses/UnauthorizedError"},"403":{"$ref":"#/components/responses/ForbiddenError"},"404":{"$ref":"#/components/responses/NotFoundError"},"429":{"$ref":"#/components/responses/RateLimitError"}}}}}}