Skip to main content

POST /v1/orders — Place order

This is a bid commitment, not a payment. No deposit. By POSTing, the partner takes commercial responsibility to pay LMN if (and only if) the order reaches secured. Money flow is described in Conventions.
curl -X POST \
  -H "x-api-key: $KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"vehicle_id": "01HXYZ...", "max_bid_amount_usd": 15500}' \
  https://api.lmnauto.com/v1/orders
HeaderRequiredDescription
Idempotency-KeyYesUUID v4. Permanent uniqueness per (api_key, key). Replays return the original response. Reusing with a different vehicle_id returns 422 idempotency_key_reused.
Body fieldTypeRequiredDescription
vehicle_idstringYesCurrent listing ID from GET /v1/vehicles or GET /v1/vehicles/{id}. Auction listings (glovis_*, sk_*, aj_*, lotte_*, kcar_*) and dealer listings (encar_*, source: "dealer") are both accepted. For auction IDs this is not a permanent physical-car ID; use the current listing’s id, not an old ID from pricing.history.
max_bid_amount_usdinteger | nullConditionalBid ceiling in whole USD. Required for auction vehicles in an upcoming round (auction_result: "upcoming"). Must be > 0 and ≥ pricing.listing_price. Null/omitted for buy-now: auction vehicles with auction_result: "no_bid", and all dealer (encar_*) listings (dealer is fixed-price, no bidding). Non-null dealer values return 400 validation_error.

Response — 201 Created (or 200 OK on idempotent replay)

{
  "id": "01HXYZ...",
  "vehicle_id": "glovis_20260420_1064_2345",
  "vin": "KMHL14JA0NA123456",
  "license_plate": "12가 3456",
  "status": "placed",
  "max_bid_amount_usd": 15500,
  "is_highest_bid": true,
  "current_max_bid_usd": 15500,
  "amounts": { "purchase_price_usd": null, "auction_fee_usd": null },
  "fx_rate": 1347.52,
  "auction_date": "2026-04-20T13:00:00+09:00",
  "order_cutoff_at": "2026-04-20T12:00:00+09:00",
  "options": ["sunroof", "leather_seats", "navigation", "rear_view_camera"],
  "created_at": "2026-04-11T10:00:00+09:00",
  "updated_at": "2026-04-11T10:00:00+09:00"
}

POST /v1/orders/backfill — Place order from LMN snapshot

Use this when you want to place an order for a dealer vehicle that may already be SOLD, WAIT, or removed upstream, but LMN may have a previously captured snapshot. Auth, idempotency, request body, response shape, and errors are intentionally the same as POST /v1/orders:
curl -X POST \
  -H "x-api-key: $KEY" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "Content-Type: application/json" \
  -d '{"vehicle_id": "encar_41865534", "max_bid_amount_usd": null}' \
  https://api.lmnauto.com/v1/orders/backfill
Behavior:
  1. If the vehicle is still live, LMN creates the order normally and captures a fresh at-order-time snapshot.
  2. If the vehicle is no longer live (SOLD, WAIT, deleted, or 404), LMN creates the order from the latest stored vehicle snapshot for your account, if one exists.
  3. If neither live data nor a stored snapshot exists, response remains 404 vehicle_not_found.
Partners do not send snapshot JSON to this endpoint. LMN owns snapshot capture and snapshot reuse.

FX rate is locked at creation

fx_rate (KRW-per-USD) is captured at the moment you POST the order and never changes for the life of that order — not on PATCH, not on status pushes, not when markets move. That rate drives the purchase_price_usd conversion when the order transitions to secured:
amounts.purchase_price_usd = auction_final_price_krw / fx_rate   (rounded)
Implication: once you’ve placed the order, you can compute the maximum settlement exposure yourself from max_bid_amount_usd — no FX surprise on auction day.
If the FX provider was unavailable at creation (rare), fx_rate is null. In that case LMN applies the settlement-day rate and communicates it offline with the secured transition. This does not happen silently — you’ll see fx_rate: null in the response from the start and can rotate the order if that’s unacceptable.

Competitive bidding

Multiple partners may all order the same auction vehicle. All POSTs return 201. The response carries:
  • is_highest_bid (boolean) — whether your bid is currently the highest among all active orders.
  • current_max_bid_usd (integer) — the highest active bid across all partners.
At auction time, LMN bids with the highest active max_bid_amount_usd. Winner gets secured; losers get failed (failure_reason: "outbid_internally").

Errors

CodeHTTPCondition
missing_idempotency_key400Header absent.
missing_max_bid400Auction vehicle, but max_bid_amount_usd null/omitted/below listing_price.
vehicle_not_found404Unknown vehicle_id. For dealer (encar_*) IDs this means the upstream listing has been removed or the parseable Encar detail page marks the advertisement as SOLD or WAIT. Treat any dealer case as no longer available to buy.
dealer_upstream_unavailable503Dealer (encar_*) listing — upstream lookup failed (timeout, 5xx, or unexpected response shape). Listing may still exist; retry.
past_order_cutoff409Past auction_date − N minutes, where N is your integration’s lead time (default 1440 = 24h; set per integration). Read order_cutoff_at from the response — don’t compute. Does not apply to dealer listings (no auction date).
duplicate_order409Active order already exists for (your key, this vehicle). details.existing_order_id referenced.
idempotency_key_reused422Same key, different vehicle_id.
vehicle_unavailable410Listing disappeared before processing.

GET /v1/orders — List

Paginated, filterable list of your orders. AND semantics across filters.
ParamDescription
idsCSV of order IDs (max 100). Foreign IDs silently dropped. Empty result → 200 with data: [] (not 404).
statusSingle status filter.
from, toISO 8601 with offset. Half-open [from, to) on created_at. Both required if either present.
sortcreated_desc (default), created_asc, auction_date_asc, updated_desc.
cursor, limitComposite cursor (sort-specific); default 50, max 200.

Sort use cases

ValueWhen
created_desc (default)“Show what I just placed”
created_ascBackfill / oldest-first reconciliation
auction_date_asc”Which of my orders resolves next?” Dealer-source orders (null auction_date) appear at the END (NULL LAST).
updated_desc”What changed recently?” — useful when a webhook was missed

Errors

CodeHTTPCondition
validation_error400Bad enum, ids > 100, from without to, limit > 200.
invalid_cursor400Cursor obtained with a different sort. Restart pagination.

GET /v1/orders/{id} — Detail

Returns the full Order resource — current state, amounts, cutoffs, shipment.
curl -H "x-api-key: $KEY" https://api.lmnauto.com/v1/orders/01HXYZ...
ErrorWhen
404 order_not_foundUnknown ID, or order belongs to a different API key.
For auction vehicles, response includes recomputed is_highest_bid and current_max_bid_usd reflecting the latest competitive state. Full Order schema in Schemas.

GET /v1/orders/{id}/vehicle — Purchased vehicle snapshot

Returns the immutable VehicleDetail snapshot captured when the order was created. This is the durable read path for purchased dealer (encar_*) cars after Encar removes the live listing page.
curl -H "x-api-key: $KEY" https://api.lmnauto.com/v1/orders/01HXYZ.../vehicle
The response shape is the same as GET /v1/vehicles/{id} detail. For dealer orders created after this rollout, photos and image URLs inside inspection data are LMN-mirrored https://storage.googleapis.com/lmnauto-auction-data/... URLs, not Encar CDN URLs.
ErrorWhen
404 order_not_foundUnknown ID, or order belongs to a different API key.
404 order_vehicle_snapshot_not_foundHistorical order created before purchased-vehicle snapshots were stored.

DELETE /v1/orders/{id} — Cancel

Allowed only when the order is in placed status. Once LMN starts bidding (acquiring+), cancellation moves offline.
curl -X DELETE \
  -H "x-api-key: $KEY" \
  https://api.lmnauto.com/v1/orders/01HXYZ...
Response: 200 OK with the updated Order (status: cancelled, cancellation_reason: dealer_cancelled). No money flow has occurred pre-secured, so cancellation has no settlement implication. Partner-to-dealer arrangements are outside this API.
Race condition: If you DELETE while LMN concurrently transitions the order (e.g., placed → acquiring), you may receive 409 invalid_status_transition. Re-fetch GET /v1/orders/{id} to see current state.
ErrorWhen
order_not_found404
invalid_status_transition409 — order not in placed, or already cancelled. details.current_status shows actual state.

PATCH /v1/orders/{id} — Update max bid

Update the max_bid_amount_usd on an existing order. Useful when you want to raise (or lower) your bid after placing the initial order — e.g., to improve win probability as auction day approaches. Allowed only while:
  • status = placed
  • Current time is before order_cutoff_at
Any other state → 409 with the specific code. The payload must carry only max_bid_amount_usd; no other fields are mutable via PATCH.
curl -X PATCH \
  -H "x-api-key: $KEY" \
  -H "Content-Type: application/json" \
  -d '{ "max_bid_amount_usd": 16000 }' \
  https://api.lmnauto.com/v1/orders/01HXYZ...

Response

200 OK with the updated Order. is_highest_bid and current_max_bid_usd are recomputed across all active orders on the same vehicle (so if a competing partner has a higher max, your updated order may still come back with is_highest_bid: false).
{
  "id": "01HXYZ...",
  "vehicle_id": "glovis_20260424_1068_6018",
  "status": "placed",
  "max_bid_amount_usd": 16000,
  "is_highest_bid": true,
  "current_max_bid_usd": 16000,
  "updated_at": "2026-04-24T09:15:03+09:00"
}

Errors

ErrorWhen
validation_error400 — body missing or max_bid_amount_usd not a positive integer.
order_not_found404 — unknown ID, or order belongs to another partner.
invalid_status_transition409 — order has moved past placed. details.current_status shows actual state.
past_order_cutoff409 — order_cutoff_at already elapsed. details.cutoff_at + details.now provided.
Concurrency: PATCH takes the same vehicle-level advisory lock as POST /v1/orders, so is_highest_bid stays consistent under concurrent bid updates. No need to back off and retry.
Idempotency: PATCH does not require Idempotency-Key. Replaying the same PATCH is safe (sets the same value). If you need strict at-most-once semantics, include your own client-side deduplication.

Sandbox status simulation

Use the dedicated Status updates guide for POST /v1/orders/{id}/sandbox-status, including request fields, lifecycle behavior, QA cases, and response examples.

GET /v1/orders/{id}/events — Event history

Returns the LMN-side webhook event log for the order — every event LMN attempted to deliver, with current delivery state. Useful for self-service debugging without contacting LMN support.
ParamInRequiredNotes
idpathyesOrder ID.
cursorquerynoOpaque cursor returned in next_cursor.
limitqueryno1–100. Default 50.

Response — 200 OK

{
  "data": [
    {
      "id": "evt_01HK5M...",
      "type": "order.status_changed",
      "delivery_status": "delivered",
      "attempts": 1,
      "last_response_code": 200,
      "next_retry_at": null,
      "created_at": "2026-04-24T03:14:11+09:00",
      "delivered_at": "2026-04-24T03:14:13+09:00",
      "payload": { "id": "evt_01HK5M...", "type": "order.status_changed", "occurred_at": "...", "data": { } }
    },
    {
      "id": "evt_01HJPU...",
      "type": "order.price_updated",
      "delivery_status": "delivery_failed",
      "attempts": 4,
      "last_response_code": 503,
      "next_retry_at": "2026-04-24T05:30:00+09:00",
      "created_at": "2026-04-22T03:02:10+09:00",
      "delivered_at": null,
      "payload": { }
    }
  ],
  "next_cursor": null
}
type is one of the five event types in webhooks → event types. payload is the exact JSON body LMN sent (or will send) to your webhook URL — same shape your endpoint receives.

delivery_status values

ValueMeaning
pendingEnqueued, not yet picked up by a delivery worker.
deliveringClaimed by a worker, in-flight.
delivered2xx response received. Terminal state.
delivery_failedAll retries exhausted (or non-retryable error). Terminal state.
delivery_skippedNo webhook URL configured for the partner — recorded for completeness but not retried.

Errors

ErrorWhen
order_not_found404 — unknown ID, or order belongs to another partner.