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
| Header | Required | Description |
|---|
Idempotency-Key | Yes | UUID v4. Permanent uniqueness per (api_key, key). Replays return the original response. Reusing with a different vehicle_id returns 422 idempotency_key_reused. |
| Body field | Type | Required | Description |
|---|
vehicle_id | string | Yes | Current 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_usd | integer | null | Conditional | Bid 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:
- If the vehicle is still live, LMN creates the order normally and captures a fresh at-order-time snapshot.
- 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.
- 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
| Code | HTTP | Condition |
|---|
missing_idempotency_key | 400 | Header absent. |
missing_max_bid | 400 | Auction vehicle, but max_bid_amount_usd null/omitted/below listing_price. |
vehicle_not_found | 404 | Unknown 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_unavailable | 503 | Dealer (encar_*) listing — upstream lookup failed (timeout, 5xx, or unexpected response shape). Listing may still exist; retry. |
past_order_cutoff | 409 | Past 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_order | 409 | Active order already exists for (your key, this vehicle). details.existing_order_id referenced. |
idempotency_key_reused | 422 | Same key, different vehicle_id. |
vehicle_unavailable | 410 | Listing disappeared before processing. |
GET /v1/orders — List
Paginated, filterable list of your orders. AND semantics across filters.
| Param | Description |
|---|
ids | CSV of order IDs (max 100). Foreign IDs silently dropped. Empty result → 200 with data: [] (not 404). |
status | Single status filter. |
from, to | ISO 8601 with offset. Half-open [from, to) on created_at. Both required if either present. |
sort | created_desc (default), created_asc, auction_date_asc, updated_desc. |
cursor, limit | Composite cursor (sort-specific); default 50, max 200. |
Sort use cases
| Value | When |
|---|
created_desc (default) | “Show what I just placed” |
created_asc | Backfill / 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
| Code | HTTP | Condition |
|---|
validation_error | 400 | Bad enum, ids > 100, from without to, limit > 200. |
invalid_cursor | 400 | Cursor 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...
| Error | When |
|---|
404 order_not_found | Unknown 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.
| Error | When |
|---|
404 order_not_found | Unknown ID, or order belongs to a different API key. |
404 order_vehicle_snapshot_not_found | Historical 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.
| Error | When |
|---|
order_not_found | 404 |
invalid_status_transition | 409 — 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
| Error | When |
|---|
validation_error | 400 — body missing or max_bid_amount_usd not a positive integer. |
order_not_found | 404 — unknown ID, or order belongs to another partner. |
invalid_status_transition | 409 — order has moved past placed. details.current_status shows actual state. |
past_order_cutoff | 409 — 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.
| Param | In | Required | Notes |
|---|
id | path | yes | Order ID. |
cursor | query | no | Opaque cursor returned in next_cursor. |
limit | query | no | 1–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
| Value | Meaning |
|---|
pending | Enqueued, not yet picked up by a delivery worker. |
delivering | Claimed by a worker, in-flight. |
delivered | 2xx response received. Terminal state. |
delivery_failed | All retries exhausted (or non-retryable error). Terminal state. |
delivery_skipped | No webhook URL configured for the partner — recorded for completeness but not retried. |
Errors
| Error | When |
|---|
order_not_found | 404 — unknown ID, or order belongs to another partner. |