Skip to main content
This guide accompanies the History endpoint reference. It describes the prepared version-2 contract after LMN enables it for your environment. The complete response examples include full JSON bodies and downloads. This guide does not announce that multi-provider collection is live.

Integration checklist

  1. Confirm History API access, environment, and whether you are using fixtures, the saved example, or a real-data trial.
  2. Send a VIN, or a plate with a stable idempotency key. Persist the returned lookup ID and original reference.
  3. Use polling, signed webhooks, or both. Separate HTTP request failure from a retrieved lookup’s failed processing status.
  4. Preserve both primary report and supplemental aggregate, including on a failed lookup.
  5. Display source coverage, conflicts, and unknown values. Do not turn unavailable information into a clean-history claim.
  6. Handle stored version-1 webhooks alongside the new version-2 envelope. Remove dependencies on history PDFs.

Run a client against sandbox

Download the Node.js client module, save it as client.mjs, and use Node.js 22 or later:
Set LMN_BASE_URL=https://sandbox-api.lmnauto.com and your sandbox key. The sample’s response can still have supplemental sources marked not_collected; it tests API access and saved primary JSON, not current government/dealer collection. The client polls every five seconds and allows six minutes of client-side waiting. That wait is a client policy, separate from the server’s fixed five-minute content cutoff. A client timeout or cancellation does not cancel an accepted lookup. Save the ID from onProgress, then resume with GET. If POST’s response was lost, reuse the same plate idempotency key/body. For a VIN, a repeat reuses the same job only while it is in flight: if it already finished, expanded collection creates a new lookup. Use GET-list, optionally bounded by created_from/created_to, and match the accepted reference and identifier to locate the original VIN job before submitting again. References are correlation values, not uniqueness constraints. Do not use a new plate key merely because a network response was lost. For a new plate request, replace vin with plate and supply idempotencyKey. Keep the key stable for retries of that request. Real-data collection can consume a credit; the client deliberately never sends fresh: true automatically.

Postman

Import the dedicated History collection. It defaults to sandbox and a blank API key. Set api_key; the first request uses the free saved Sportage example. A successful POST stores history_lookup_id for the polling request. The plate template has a blank history_plate until you intentionally fill it and confirm your environment’s billing mode. The collection does not run itself or configure your webhook. Production needs a separately enabled key and an intentional base-URL change. The generic inventory/order collections remain separate.

Store the response without flattening away evidence

Use fact/value IDs to relate evidence within a frozen result. IDs are opaque; do not infer dates or business meaning from them, or assume they remain the same across distinct lookups. A revision_id is a source reference, not a public raw-data download.

Scalars, sets, and conflicts

For a scalar fact, a single values[] member can carry several source references. If conflict is true, retain and label every alternative. Do not average conflicting odometer readings or sum duplicate claim totals. For cardinality: "set", multiple work items or part codes are legitimate members. Several providers can support the same value. Amounts retain the units indicated by the key: *_won and *_krw are Korean won; *_raw remains source-denominated text and must not be silently converted or added to a known-unit total.

Events and uncertain matches

An event can be verified, source_record, or unresolved. source_record identifies an event within its source, not a verified match across providers. A shared candidate_group_id links uncertain correspondences; show them as possibly related. Date-only or same-month similarity does not prove identity. Keep every event context’s date_precision. A month is not the first day of that month, null mileage is not zero, and an unknown date can be an empty string with precision unknown.

Partial result example

Open completed-partial.json: the primary report is ready, some Car365 information is available, and Encar has no listing. Render the primary report and the aggregate; label source availability separately. The lookup remains completed, and the existing successful-lookup credit policy applies. Open failed-supplemental.json: the primary report was unavailable, but Car365 facts were ready by cutoff. Retain those facts, show the primary failure, and record credits_charged: 0. HTTP GET returns 200 for this stored failed lookup; it is not an HTTP 5xx error. aggregate.complete concerns the observations admitted into consolidation. Check all three sources entries before describing coverage. Even a reconciled set of recorded facts is not a complete lifetime record or a vehicle-condition guarantee.

Receive terminal events

  1. Configure your existing environment-specific webhook endpoint with LMN.
  2. Verify the signature over the raw request body before parsing, using Signing and retries.
  3. Deduplicate by event ID. Enqueue application processing durably, then acknowledge with 2xx; keep delivery handling fast.
  4. Route history_lookup.completed and history_lookup.failed to the same history-result storage path.
verifiedEvent and saveHistoryResult are your verified event object and persistence function. This snippet does not replace signature verification or durable deduplication. One terminal business event can have several network deliveries. Reusing a job, retrying a delivery, or explicitly replaying an event does not create a second credit debit. Five minutes limits result content, not webhook network arrival time. Full downloadable completed, failed, and legacy event bodies can be fed to readHistoryEvent offline, without any API or webhook call.

Cutover and replay checklist

This is an in-place /v1/history-lookups contract cutover, not an unannounced /v2 route. Accept unknown added fields, keep version-1 event handling, and test null report/aggregate values. Do not overwrite the archived body of an old event with a current GET response just because both use the same lookup ID.

Acceptance cases for your integration

  • VIN in flight: a repeat returns the same ID and no extra event.
  • Plate retry: same key/body returns the original job; changed body returns 422.
  • Completed with partial supplemental coverage: useful data remains visible and one successful charge policy applies.
  • Failed primary with ready supplemental facts: aggregate remains visible and no credit is deducted.
  • All source data unavailable: null aggregate stays unknown, not a clean result.
  • Equal facts from several providers: preserve all provenance without summing repeated values.
  • Conflicting scalar or uncertain event: retain alternatives and uncertainty.
  • Seven-day source reuse versus 30-day credit entitlement: do not treat either as the other’s expiry.
  • Duplicate or legacy webhook delivery: keep one business result and do not assume its body matches current GET.
  • Client timeout: resume a known ID; a plate’s stable key recovers its original request, while a VIN job that has already finished must be located through recent lookups before intentionally starting another.
The response downloads are explicitly synthetic offline fixtures, generated through the implementation. Controlled live-source acceptance is a separate LMN release gate.