Skip to main content
Order events carry a full Order snapshot in data.order so your handler can act without a follow-up GET. Eagle Eye events carry the watch context plus the vehicles or vehicle IDs that changed.
Order payload parity (v1.18+): the data.order field in every order webhook is structurally identical to the response of GET /v1/orders/{id} — same field names, types, nullability, and enrichment (including is_highest_bid and current_max_bid_usd). You can reuse the same Order type and deserializer across order reads and order webhooks.Eagle Eye vehicle parity: vehicle objects inside eagle_eye.match additions and price_changes use the same VehicleSummary schema returned by GET /v1/vehicles. Eagle Eye adds watch and signal metadata around that vehicle object; it does not define a separate vehicle model.Examples below are abbreviated for brevity. Order webhook payloads include every field documented under Get an order, not only the ones shown here. Eagle Eye vehicle examples are also abbreviated; build against the shared VehicleSummary schema.

order.status_changed

Fires on every server-side status transition. Includes the previous status for reconstruction.
{
  "id": "evt_01HXYZ...",
  "type": "order.status_changed",
  "occurred_at": "2026-04-20T13:30:00+09:00",
  "data": {
    "previous_status": "acquiring",
    "order": {
      "id": "01HXYZ...",
      "vehicle_id": "glovis_20260420_1064_2345",
      "status": "secured",
      "max_bid_amount_usd": 15500,
      "amounts": {
        "purchase_price_usd": 14800,
        "auction_fee_usd": 234
      },
      "failure_reason": null,
      "shipment": null,
      "created_at": "2026-04-11T10:00:00+09:00",
      "updated_at": "2026-04-20T13:30:00+09:00"
    }
  }
}

Status transitions that fire this event

TransitionDriver
placedinspection_in_progressLMN starts the optional pre-acquisition inspection
placedacquiringLMN starts bidding/purchasing (inspection skipped)
inspection_in_progressinspection_readyInspection completed; ready for LMN acquisition decision
inspection_readyacquiringInspection passed; LMN starts bidding/purchasing
inspection_readycancelledInspection failed (cancellation_reason: inspection_failed)
acquiringsecuredLMN won/purchased
acquiringfailedLMN lost auction or purchase failed
securedexport_processingTitle transferred to LMN; Korean export begins
export_processingin_transitBill of Lading issued; vessel departed Korean port
placedcancelled (LMN auto)Reschedule-too-soon / source-cancel / seller-withdraw
Partner-initiated transitions (placed creation, placed → cancelled via DELETE, in_transit → customs, customs → delivered) are confirmed by the API response and do not fire webhooks.

Failed-auction example

{
  "id": "evt_01HABC...",
  "type": "order.status_changed",
  "occurred_at": "2026-04-20T13:45:00+09:00",
  "data": {
    "previous_status": "acquiring",
    "order": {
      "id": "01HDEF...",
      "status": "failed",
      "failure_reason": "outbid",
      "amounts": {
        "purchase_price_usd": null,
        "auction_fee_usd": null
      }
    }
  }
}
failure_reason enum (terminal failed, reachable from acquiring only):
  • outbid — lost to external bidder at auction.
  • outbid_internally — another partner’s higher bid won. All competing placed orders on the same auction lot enter acquiring together before resolution, so each competitor sees a clean placed → acquiring → failed sequence.
  • vehicle_unavailable — LMN’s dealer purchase attempt failed (car sold to another buyer).
  • auction_cancelled — auction event cancelled after LMN began bidding.
  • auction_passed — vehicle passed at auction, OR zombie cleanup at auction_date + 24h (see below).
  • seller_withdrew — seller withdrew the car after LMN started attempting to acquire.

Zombie-cleanup variant

If LMN never picked up a placed order and the auction has been over for 24 hours, the system auto-resolves it with failure_reason: auction_passed. The webhook collapses the synthetic intermediate state — previous_status is placed (not acquiring), and an additive synthetic_acquiring: true discriminator is set:
{
  "id": "evt_01HZOM...",
  "type": "order.status_changed",
  "occurred_at": "2026-04-21T13:00:00+09:00",
  "data": {
    "previous_status": "placed",
    "synthetic_acquiring": true,
    "order": {
      "id": "01HXYZ...",
      "status": "failed",
      "failure_reason": "auction_passed",
      "acquired_at": null
    }
  }
}
Treat this as a regular failed event, or branch on synthetic_acquiring to suppress noise from known LMN ops outages.

Cancellation example

{
  "id": "evt_01HCAN...",
  "type": "order.status_changed",
  "occurred_at": "2026-04-19T08:00:00+09:00",
  "data": {
    "previous_status": "placed",
    "order": {
      "status": "cancelled",
      "cancellation_reason": "auction_cancelled"
    }
  }
}
cancellation_reason enum (terminal cancelled, reachable from placed only):
  • dealer_cancelled — partner sent DELETE.
  • auction_rescheduled_too_soon — LMN auto, auction rescheduled past order cutoff.
  • auction_cancelled — LMN auto, auction event cancelled before LMN started bidding.
  • seller_withdrew — LMN auto, seller pulled dealer listing before LMN started purchase.
failure_reason and cancellation_reason are mutually exclusive — an order has one or the other, never both. For reasons that can appear in either enum (auction_cancelled, seller_withdrew), the order’s current status at the moment of the upstream event decides the terminal.

order.auction_rescheduled

Fires when the auction source postpones or advances an auction, shifting auction_date and recomputing order_cutoff_at. No status change.
{
  "id": "evt_01HRES...",
  "type": "order.auction_rescheduled",
  "occurred_at": "2026-04-14T08:15:00+09:00",
  "data": {
    "previous_auction_date": "2026-04-20T13:00:00+09:00",
    "order": {
      "auction_date": "2026-04-22T13:00:00+09:00",
      "order_cutoff_at": "2026-04-21T00:00:00+09:00"
    }
  }
}
Compare data.previous_auction_date against data.order.auction_date to detect direction and magnitude. Update dealer-facing deadlines accordingly. If a reschedule moves auction_date so close that order_cutoff_at is already in the past on a placed order, LMN auto-cancels with cancellation_reason: "auction_rescheduled_too_soon" and fires a separate order.status_changed event. Orders already in acquiring or later are unaffected (LMN is committed; the auction proceeds on the new date).

order.price_updated

Fires when the vehicle backing an active placed order has its listing_price updated by the upstream scraper. No status change. The payload keys (previous_listing_usd / current_listing_usd) keep the _usd suffix for webhook-event convention; they refer to the same underlying value as pricing.listing_price on the vehicle. Useful for partners whose bid strategy depends on the current market estimate — a price drop may mean the dealer should raise max_bid_amount_usd to stay competitive, while a spike may mean the current max_bid is now insufficient.
{
  "id": "evt_01HJPU...",
  "type": "order.price_updated",
  "occurred_at": "2026-04-22T03:02:10+09:00",
  "data": {
    "previous_listing_usd": 14200,
    "current_listing_usd": 13650,
    "delta_usd": -550,
    "delta_pct": -3.9,
    "order": {
      "id": "01HXYZ...",
      "vehicle_id": "glovis_20260420_1064_2345",
      "status": "placed",
      "max_bid_amount_usd": 15000
    }
  }
}
Semantics:
  • delta_usd is negative when the price dropped (partner-friendly).
  • delta_pct is rounded to 1 decimal place and is null if previous_listing_usd was 0.
  • Fires at most once per actual change — identical refreshes to the same value are deduped server-side.
  • Fires only while the order is in placed — terminal-state and post-acquiring orders ignore market refreshes.

order.re_auctioned

Fires when a vehicle tied to one of your terminal orders (status failed / cancelled / delivered) reappears in a new auction round. Matched by Korean license plate across auction houses, so the same physical car is caught even if it moves from Glovis to SK or Lotte between listings.
{
  "id": "evt_01HK5M...",
  "type": "order.re_auctioned",
  "occurred_at": "2026-04-24T00:15:00+09:00",
  "data": {
    "previous_vehicle_id": "glovis_20260410_1062_5000",
    "new_vehicle_id": "glovis_20260428_1070_3021",
    "new_auction_date": "2026-04-28T09:00:00+09:00",
    "license_plate": "12가 3456",
    "order": {
      "id": "01HWYZ...",
      "status": "failed",
      "failure_reason": "outbid"
    }
  }
}
Use case: the dealer originally bid, lost (or cancelled), and wants a second chance. On receiving this event, surface the new vehicle_id back to the dealer UI and let them re-POST /v1/orders if still interested. Semantics:
  • The attached data.order is the original terminal order — NOT a new order. No new order is implicitly created.
  • Fires at most once per (license_plate, new_auction_date) — no duplicates during re-scrapes.
  • data.previous_vehicle_id is the ID from the terminal order; data.new_vehicle_id is the current listing’s ID.
  • data.new_auction_date is in KST ISO 8601 with +09:00 offset.

eagle_eye.match

Fires when a saved Eagle Eye watch has at least one addition, price change, or removal. The payload is batched per watch and includes enough context for a partner UI to explain why the vehicle appeared.
{
  "id": "evt_01HZX0Q...",
  "type": "eagle_eye.match",
  "occurred_at": "2026-06-09T12:00:00+09:00",
  "data": {
    "watch_id": "wat_01HZW...",
    "watch_name": "GLE 450 watch",
    "batch_id": "batch_01HZX0M9R5Q7TZWN4D5VG3F2KA",
    "evaluated_at": "2026-06-09T03:00:00.000Z",
    "additions": [
      {
        "vehicle": {
          "id": "glovis_20260609_1234_5678",
          "source": "glovis",
          "make": "Mercedes-Benz",
          "model": "GLE-Class",
          "year": 2022,
          "pricing": {
            "listing_price": 31000000,
            "currency": "KRW"
          }
        },
        "match_reason": ["filters", "signals.undervalued"],
        "signal_detail": {
          "undervalued": {
            "reference_price_krw": 38500000,
            "listing_price_krw": 31000000,
            "delta_pct": 19.5
          }
        }
      }
    ],
    "price_changes": [
      {
        "vehicle": {
          "id": "sk_20260609_88_1001",
          "source": "sk",
          "pricing": {
            "listing_price": 30000000,
            "currency": "KRW"
          }
        },
        "previous": {
          "price_krw": 32500000,
          "observed_at": "2026-06-08T03:00:00.000Z"
        },
        "match_reason": ["filters", "signals.price_drop"],
        "signal_detail": {
          "price_drop": {
            "previous_price_krw": 32500000,
            "current_price_krw": 30000000,
            "drop_pct": 7.7,
            "min_drop_pct_configured": 5
          }
        }
      }
    ],
    "removals": [
      {
        "vehicle_id": "glovis_20260601_1234_1000",
        "reason": "auction_complete"
      }
    ]
  }
}

Signal detail

Signal-driven matches include signal_detail so product teams can show the dealer why the alert matters:
SignalDetail fields
repeat_listingbucket, listing_count, cumulative_drop_pct, window_days
undervaluedreference_price_krw, listing_price_krw, delta_pct
price_dropprevious_price_krw, current_price_krw, drop_pct, min_drop_pct_configured
price_drop is drop-only. A price increase does not carry signals.price_drop; if the vehicle still qualifies, the current match updates silently and no price_changes webhook entry is emitted. If the increase makes it fail the watch’s filters, LMN sends a removal.

Removal reasons

ReasonMeaning
delistedDealer inventory listing disappeared.
auction_completeAuction listing finished.
price_above_thresholdVehicle rose above the watch’s configured price cap.
Hiding a match via POST /v1/eagle-eye/watches/{watch_id}/matches/hide is a view-state change on your side only — it never produces a removals entry on this webhook. Use GET /v1/eagle-eye/watches/{watch_id}/events to recover the exact webhook payload history for a watch.