validation_error | 400 | Request shape failed validation. | Bad enum, missing field, model without make, ids > 100, from without to. Dealer requests: an auction-only filter such as auction_status sent with source=dealer. | Inspect error.details.issues[].path (or error.details.field). Fix the request; do not retry as-is. A future alias/suggestion release will add to rejected dealer model/sub_model errors (and rejected model on GET /v1/vehicles/trims) error.details.suggestions — { model, sub_model?, catalog_status, make? } entries to send instead; make appears only when a multi-value make request is rejected — and error.details.facets. Dealer cases: see Missing dealer listings. |
missing_idempotency_key | 400 | Required Idempotency-Key header is absent. | POST /v1/orders, or a plate request to POST /v1/history-lookups, without the header. History VIN requests do not require it. | Keep one stable key per logical request and reuse it for retries. |
invalid_cursor | 400 | Cursor invalid, expired, or sort-mismatched (orders and invoices). | Resending a cursor after changing sort= on GET /v1/orders or GET /v1/invoices. Not returned by GET /v1/vehicles: it can instead return 400 validation_error on cursor for an incompatible price sort or taxonomy version change. Legacy page-number cursors may silently apply their position to changed filters — see Missing dealer listings → T5. GET /v1/eagle-eye/watches/\{watch_id\}/matches reports a bad cursor as 400 validation_error with details.field: "cursor". | Restart pagination from page 1 with the desired sort. |
missing_max_bid | 400 | Auction vehicle requires max_bid_amount_usd. | POST with null/omitted/below-listing bid. | Add max_bid_amount_usd (integer > 0, ≥ listing). Not required for buy-now. |
missing_api_key | 401 | x-api-key header absent. | Any request without header. | Add the header. |
invalid_api_key | 401 | Key not recognized, revoked, or wrong env. | Sandbox key against production URL, or revoked key. | Verify env (sandbox vs production); rotate if compromised. |
ip_not_allowed | 403 | Source IP not in allowlist. | Egress IP missing from the key’s allowlist. Production keys only — sandbox trial keys have no allowlist and never return this. | Add the IP yourself: partner console → Keys → the key → Allowlist. Check egress NAT stability; if your backend has rotating IPs, certify on sandbox first. |
invalid_status_transition | 403 / 409 | Requested transition not permitted. | 403 = partner attempted an LMN-owned status (secondary_inspection_in_progress, secondary_inspection_ready, acquiring, secured, export_processing, in_transit); details.reason: "partner_not_authorized". 409 = sequence violation (e.g., delivered from non-customs, DELETE from non-placed); details.reason: "out_of_sequence". details.current_status set in both cases. | Re-fetch GET /v1/orders/{id} to see current state. Only use partner-permitted transitions: in_transit → customs, customs → delivered. |
vehicle_not_found | 404 | Unknown or unavailable vehicle ID. | Stale ID, wrong-env ID, a dealer (encar_*) detail page whose upstream advertisement is no longer active / marked SOLD or WAIT, or a dealer listing currently under contract (계약중) on Encar. | Refresh the listing; confirm correct base URL. For a SOLD / WAIT dealer car, treat this as no longer available to buy and remove or disable the listing in your UI. For an under-contract dealer car, this is reversible — don’t remove the listing permanently; it can resolve normally again once the contract falls through. Cars you have already ordered are exempt — their detail still resolves from your stored order snapshot, so a purchased vehicle won’t return this error. |
order_not_found | 404 | Unknown order ID for this key. | Wrong env, cross-key ID, or deleted. | Confirm correct base URL; the ID belongs to your account. |
order_vehicle_snapshot_not_found | 404 | Order exists, but no purchased-vehicle snapshot is stored. | GET /v1/orders/{id}/vehicle for a historical order created before snapshot storage. | Use live GET /v1/vehicles/{vehicle_id} only if the listing still exists; otherwise contact LMN for manual recovery. |
past_order_cutoff | 409 | POST after the auction’s cutoff. | auction_date − N min (your integration’s lead time; default 1440 = 24h) already passed. | Inform dealer that the order window is closed. |
past_secondary_inspection_cutoff | 409 | POST with secondary_inspection_required: true after the inspection request window. | End of day (auction day − 2, your integration’s local time) already passed — read secondary_inspection_cutoff_at on the Vehicle resource. | Offer the dealer the same order without inspection (secondary_inspection_required: false) while order_cutoff_at is still open. |
duplicate_order | 409 | Active order already exists for this vehicle. | Repeat POST while a prior order is not terminal. details.existing_order_id references it. | Redirect user to existing order page. Do not auto-retry. |
idempotency_key_reused | 422 | An order key was reused with a different vehicle/inspection flag, or a History plate key with a different normalized body (including reference or fresh). | Reusing one key across different logical requests, or changing a retry body. History VIN keys are ignored. | Orders expose details.original_vehicle_id / details.original_secondary_inspection_required; History exposes details.original_lookup_id. Reuse the original key/body to recover that request, or intentionally create a new key for genuinely new work. |
vehicle_unavailable | 410 | Vehicle no longer available. | Dealer or buy-now listing disappeared before LMN could complete the purchase. | Move order to failed in UI once the order snapshot reflects failure_reason: "vehicle_unavailable"; notify dealer. |
rate_limited | 429 | Several conditions share this code — one permanent, the rest transient. See Telling the 429s apart. | Permanent: a sandbox trial key has spent its lifetime call budget. Transient: more than 5 test-webhook fires per minute on one Eagle Eye watch; more than 60 invoice PDF downloads per minute per key; a history-lookup cap (10 in flight, 200 per KST day). | Branch on error.details and Retry-After. details.used present → budget exhausted, stop retrying. Else Retry-After header present (invoice PDFs, history lookups) → wait that many seconds. Else → test-webhook throttle, retry after ~60s. |
history_lookup_not_enabled | 403 | Vehicle history lookups are not enabled for your account in this environment. | POST /v1/history-lookups before production onboarding is complete. | Use sandbox, or contact LMN to be enabled for production. |
history_lookup_not_found | 404 | Unknown lookup ID for this key. | Wrong env, another partner’s ID, or a mistyped hlk_ ID. | Confirm the base URL and that the lookup was created with your key. |
inspections_not_enabled | 403 | The inspection API is not enabled for your account in this environment. | Any /v1/inspections request without the inspections_api feature. | Contact LMN to be enabled. |
inspection_not_found | 404 | Unknown inspection ID for this key. | Wrong env, another partner’s inspection, or a mistyped id — in any status. | Confirm the base URL and that the inspection was created with your company’s key. |
DUPLICATE_INSPECTION | 409 | Your company already requested an inspection for this car. | Repeat POST /v1/inspections for the same carUniqueId, in any status including ready. details.id is the existing inspection. Upper-case by design (shared with the CarbitX inspection code). | Read GET /v1/inspections/{id} with that id. Do not auto-retry. |
capacity_exceeded | 429 | Global capacity for new real-data history work is temporarily full. | Enabled production or sandbox real-data trial admission; fixture-only examples do not use this provider capacity. | Honor Retry-After; retry the same VIN, or the same plate idempotency key/body. |
insufficient_history_credits | 402 | No available credit for a new chargeable history lookup in this environment. | Production prepaid balance or sandbox test-credit balance is exhausted; an active free-repeat entitlement remains usable at zero balance. | Request more credits through the partner console. Do not loop retries expecting the balance to replenish automatically. |
service_unavailable | 503 | The feature is not available in this environment, or is temporarily switched off. | POST /v1/history-lookups against production while the feature is closed. GET /v1/vehicles with trim, or GET /v1/vehicles/trims, while trim filtering is switched off (details.reason: "trim_filter_disabled"). GET /v1/vehicles/facets on a server that has not yet loaded any auction inventory (details.reason: "facets_cache_not_ready") or whose loaded inventory carries no auction taxonomy version (details.reason: "taxonomy_version_mismatch"); both carry details.retry_after_seconds: 60. | Use sandbox, or contact LMN. For trim_filter_disabled, drop trim (the rest of the search still works) or retry later. For the two facets reasons, keep your current facets copy and retry after details.retry_after_seconds. |
internal_error | 500 | Server-side failure. | Rare; LMN on-call is paged automatically. Body carries only a generic message — no stack traces. | Retry with exponential backoff (3 tries). If persistent, share request_id with support. |
mixed_source_pagination_unsupported | 400 | cursor passed with mixed auction+dealer source using an unsupported sort or multiple makes/models. | Trying to paginate beyond page 1 on a query like source=glovis,dealer&cursor=…. | Restart pagination per source — issue separate requests with source=glovis and source=dealer. Mixed pagination is supported with sort=price_asc / price_desc and at most one make/model; other mixed sorts remain first page only. See also Missing dealer listings → T4. |
dealer_upstream_unavailable | 503 | Every requested dealer source is unreachable or returned an invalid response, and no eligible Encar list cache exists. | Transient dealer-source outage, network blip, bot-protection interstitial, or extractor drift. Encar list search may return an exact cache page no more than 30 minutes old as source_status.encar.status: "stale". Since 2026-10-20, when Encar answers a dealer list read with a server error (HTTP 5xx), LMN retries that read once, about 0.4 seconds later, if enough of the request’s time budget remains (see the Changelog); a request can still return this 503 after that retry. Mixed requests can degrade gracefully, with two headers: X-LMN-Partial-Dealer-Unavailable: 1 and X-LMN-Dealer-Unavailable-Sources: <csv> for partial or unavailable sources. | Retry after a short backoff (5–30s). Preserve prior inventory state. If persistent (> 5 min for a single ID, > 2 min for list), include request_id and the failing dealer query in a support note — auction requests are unaffected during dealer outages. For price-sorted mixed pagination, a failure before any dealer row is examined can return this 503; retry the same cursor. Storefront handling: Missing dealer listings → T6. |