lmnauto.com car-detail pages — using only the JSON returned by GET /v1/vehicles/{id}. It is intentionally exhaustive: a partner engineer should be able to build a pixel-faithful rendering from scratch using only this page plus the response.
Why a dedicated guide?
The inspection data is the densest, most source-variable part of the response. The unified shape covers six inspectors (Glovis, SK, AJ, Lotte, KCar, Encar dealer) that all expose different raw data, normalized into a single response contract. The shape is mostly consistent across sources, with a few documented asymmetries:- Shape asymmetries — auction and dealer both carry
checklist[]; only dealer adds thedealer_inspectiondamage-count block.accident_history[]remains auction-only for now (dealer surfaces accident state viahas_accident/accident_summary). - Value asymmetries — SK and Lotte return a mirrored diagram
image_url(damage baked in) and AJ a blueprint base image; Glovis, K-Car, and dealer returnnulland need a client-rendered diagram frompanels[]. Damage codes and panel IDs differ per source (see Damage Code Dictionary and Panel ID Catalog) — render-time partner code must tolerate the variations.
1. Anatomy of the response
The detail endpoint returns these two top-level objects relevant to inspection:| JSON path | Drives | Type |
|---|---|---|
body_condition | The car-diagram panel (“Body Inspection”) | Object | null |
inspection_report | The grade-summary card (“Inspection Report” / ” Grade”) | Object | null |
null independently — feature-detect before rendering.
Why both can be null
| Scenario | body_condition | inspection_report |
|---|---|---|
| Auction listing freshly scraped, inspector hasn’t filed report yet | null | null |
| Auction with grade filed but no panel damage | populated (panels: []) | populated |
| Dealer car where Encar has no inspection record (upstream 404) | null | null |
| Dealer car where Encar returned data but no panel damage (clean car) | populated (panels: []) | populated |
| Dealer car with both inspection metadata and panel damage | populated | populated |
accident_cost_summary may be null even when inspection_report itself is populated.
2. Per-source field matrix
Every field below is part of the same response shape, but populated differently depending oninspection_report.source. Knowing which fields you can expect per source lets you build skeletons and empty states that don’t flicker.
| Field | Glovis | SK | AJ | Lotte | KCar | Dealer (Encar) |
|---|---|---|---|---|---|---|
body_condition.image_url | — | ✅ mirror | ✅ blueprint | ✅ mirror | — | — |
body_condition.panels[] | ✅ ~12-20 entries | ✅ 4-8 entries | ✅ 6-14 entries | ✅ 4-10 entries | ✅ 4-12 entries | ✅ 0-10 entries |
inspection_report.overall_grade | ✅ "A/7" | ✅ "A/A" | ✅ "A/A" | ✅ "A/A" | ✅ "A/A" | — |
inspection_report.grade_description | ✅ accident grade / 1-9 condition score | ✅ accident grade / exterior letter | ✅ frame grade / exterior letter (digit) | ✅ accident grade / exterior letter | ✅ accident grade / exterior letter | ✅ "Encar dealer inspection" |
inspection_report.accident_summary | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ (“No structural damage” or “Frame damage reported”) |
inspection_report.has_accident | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
inspection_report.has_frame_damage | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
inspection_report.exterior_summary | ✅ “6 panels: 4× needs bodywork, 1× scratch” | ✅ short | ✅ short | ✅ short | ✅ short | ✅ N exterior damage cases |
inspection_report.accident_reason | ✅ “Welded (W): rear door (L), trunk (L)” | — | ✅ | — | — | — |
inspection_report.category_grades[] | ✅ 5-8 categories | ✅ 3-5 | ✅ 5-7 | ✅ 3-5 | ✅ 3-5 | ✅ [{frame},{exterior}] only |
inspection_report.checklist[] | ✅ 17 items | ✅ limited (~5-8) | ✅ up to 39 items | ✅ limited | ✅ limited | ✅ up to ~35 items (mechanical, EN-translated) |
inspection_report.accident_history[] | ✅ | — | ✅ | — | — | [] |
inspection_report.accident_cost_summary | ✅ when accidents present | — | ✅ when accidents present | — | — | null |
inspection_report.issues[] | ✅ | ✅ | ✅ | ✅ | ✅ | [] |
inspection_report.inspection_sheet_url | — | ✅ original sheet PDF | ✅ original sheet PDF | — | — | null |
inspection_report.inspector_notes | ✅ EN-translated | ✅ EN-translated | ✅ EN-translated | ✅ EN-translated | ✅ EN-translated | ✅ EN-translated (live Google Translate) |
inspection_report.dealer_inspection | absent | absent | absent | absent | absent | ✅ |
checklist[] (engine, transmission, steering, braking, electrical, …, EN-translated) alongside the dealer_inspection damage counts. Render whatever is non-empty; the renderer below handles all six.
inspection_report. Previously a dealer car with no panel damage returned inspection_report: null (and the UI showed “No inspection report available”), even though the inspection existed and was simply clean. As of the change below, a successfully-fetched dealer inspection always returns a report — a clean car reads as zero damage with a populated mechanical checklist[]. inspection_report is still null only when the inspection genuinely doesn’t exist upstream (Encar 404) or the fetch failed transiently.3. The Body Inspection card
The card titled “Body Inspection” onlmnauto.com. For live comparison, see any dealer listing at https://lmnauto.com/en/auction?source=retail&tab=encar_<id> — the worked example in §12 uses encar_41657860 (BMW M5 2019).
3.1 Visual structure
3.2 Response shape
3.3 Field reference
| Field | Type | Meaning |
|---|---|---|
image_url | string | null | HTTPS URL to the source’s mirrored diagram image — populated for SK and Lotte (damage baked in) and AJ (a blueprint base image drawn under the panel markers). null for Glovis, K-Car, and dealer — render those from panels[]. |
panels[].panel_id | string | Stable identifier — see the Panel ID Catalog below. Use as marker-position key. |
panels[].panel_type | "exterior" | "frame" | Determines which of the two silhouettes the marker goes on. |
panels[].damage_code | string | The primary damage code. See the Damage Code Dictionary. |
panels[].damage_codes | string[] | All damage codes for this panel — one panel may have multiple non-rank codes (e.g. welded + sheet-metalled). Order is most-significant first. Dealer-only caveat: when a panel has both a rank attribute (e.g. RANK_ONE) and a non-rank damage code (e.g. CHANGE) upstream, only the non-rank codes survive in this array; rank attrs are reflected in the aggregate dealer_inspection counts instead. See Damage Code Dictionary §4.6. |
panels[].label | string | English display label (e.g. “Hood”, “Front Door (L)”, “Rear Quarter Panel (R)”). |
panels[].description | string | Human-readable description of damage_code. Localized to English. |
panels[].severity | "high" | "medium" | "low" | "none" | Roll-up severity for color coding. See the Severity Computation Rules. "none" only appears in rare cases where a panel is listed for completeness without actual damage. |
3.4 Count derivation
Compute the two count boxes from the panels array:3.5 Status text per count box
| Count | Max severity | Frame box text | Exterior box text |
|---|---|---|---|
0 | — | “No structural damage" | "No exterior damage” |
≥1 | low | ”Minor damage" | "Minor damage” |
≥1 | medium | ”Repair history" | "Repair history” |
≥1 | high | ”Major damage" | "Major damage” |
3.6 Count box color
| Count | Severity | Background | Text |
|---|---|---|---|
0 | — | #ECFDF5 (emerald-50) | #047857 (emerald-700) |
≥1 | low | #FEFCE8 (yellow-50) | #A16207 (yellow-700) |
≥1 | medium | #FFFBEB (amber-50) | #B45309 (amber-700) |
≥1 | high | #FEF2F2 (red-50) | #B91C1C (red-700) |
3.7 Rank breakdown (dealer-source only)
Wheninspection_report.source === "dealer", render a small summary beneath the diagrams using the server-computed totals in inspection_report.dealer_inspection:
inspection_report.checklist[] for dealer cars too — each entry is { group, item, result }, already KO→EN translated. Render it with the same checklist component used for auction sources.
Display under each diagram:
dealer_inspection.rank_counts. To reproduce the reference UI’s “Rank 1 / Rank 2 / Rank A / Rank B / Rank C” lines, read dealer_inspection.rank_counts ({ rank_one, rank_two, rank_a, rank_b, rank_c }, integers, dealer-only). By construction rank_a + rank_b + rank_c === critical_frame_damage and rank_one + rank_two === exterior_damage, so the aggregate count fields above remain valid for older clients.Do not try to compute per-rank counts by scanning body_condition.panels[].damage_codes. When a panel has both a rank attribute and a regular damage code (the common case — RANK_ONE together with CHANGE), the rank attribute is dropped from damage_codes in favor of the more specific damage. Counting from damage_codes would systematically undercount — use rank_counts, which is tallied before that collapse.4. Damage Code Dictionary
Thedamage_code vocabulary is source-specific. Each inspector emits its own codes — Glovis uses lowercase mnemonics, SK/AJ/Lotte use uppercase letter codes, and the Encar dealer path uses descriptive uppercase tokens. The unified panel.severity and panel.description fields paper over this — those are normalized for display. Use damage_code for icon mapping and case-by-case handling; rely on description for textual rendering.
The full set of codes you may receive, per inspection_report.source:
4.1 Glovis (source: "glovis")
Lowercase mnemonics derived from Korean damage type names.
| Code | English | Korean origin | Severity (server) | Icon glyph |
|---|---|---|---|---|
xx | Replaced | 교환 | high | × (white on red) |
w | Sheet metal / Welding | 판금/용접, 용접 | medium | W (white on amber) |
pp | Sheet metal repair | 판금 | medium | P (white on amber) |
f | Bent / Crumpled | 꺾임 | medium | F (white on amber) |
m | Adjusted | 조정 | low | outlined dot |
4.2 SK (source: "sk")
Uppercase single- or double-letter codes.
| Code | English | Korean origin | Severity (server) | Icon glyph |
|---|---|---|---|---|
XX | Replacement history | 교환이력 | high | × (white on red) |
X | Replaced | 교환 | high | × (white on red) |
W | Welded | 판금용접 | medium | W (white on amber) |
Q | Panel work | 쿼터패널 | medium | Q (white on amber) |
P | Paint | 도장 | low | outlined dot |
M | Adjusted | 조정 | low | outlined dot |
G, G1, G2 may appear in raw upstream data but are filtered out before reaching the partner API — you will not see them.
4.3 AJ (source: "aj")
Uppercase letter codes. Shares some letters with SK (e.g. X, W) — never mix the two dictionaries; always switch on source first.
| Code | English | Korean origin | Severity (server) | Icon glyph |
|---|---|---|---|---|
XX | Replacement history | 교환이력 | high | × (white on red) |
X | Replaced | 교환 | high | × (white on red) |
W | Panel / Weld | 판금/용접 | high | W (white on amber) |
A | Scratch | 상처 | low | outlined dot |
P | Paint | 도장 | low | outlined dot |
4.4 Lotte (source: "lotte")
Lotte uses a code set similar to SK. Treat unknown codes by falling back to description text — the inspector’s free-text describes the damage in English.
4.5 KCar (source: "kcar")
Same fallback rule as Lotte — handle unknown codes gracefully via description. KCar emits a sparse, mostly-letter-code set; expect coverage to grow over time.
4.6 Dealer (Encar) (source: "dealer")
Descriptive uppercase tokens derived from Encar’s outers[].attributes[] raw values.
| Code | English | Severity (server) | Notes |
|---|---|---|---|
CHANGE | Replaced (Exchange) | high | Panel was swapped out. Rendered with the × exchange overlay. |
WELD | Welded | medium | Structural repair via welding. See ‡ below. |
METAL | Sheet metal repair | medium | Body work without replacement. |
CORROSION | Corrosion | medium | Rust / oxidation. |
SCRATCH | Scratch | low | Surface scratch. |
DAMAGE | Damage (general) | medium | Catch-all for unspecified damage. |
HILLS | Dent | low | Encar’s term for a dent / dimple. See ‡ below. |
RANK_A | Frame rank A | high | Frame panel (most severe of A/B/C). See note below. |
RANK_B | Frame rank B | high | Frame panel. |
RANK_C | Frame rank C | high | Frame panel. |
RANK_ONE | Exterior rank 1 | low–high | Severity is set by the accompanying statusTypes (W → medium, X → high). Bare rank-only panels with no statusTypes upstream emit low. |
RANK_TWO | Exterior rank 2 | low–high | Same rule as RANK_ONE — severity is set by the canonical damage code derived from statusTypes. |
WELD and HILLS are recognized by the server’s severity and description logic for forward-compatibility, but are not currently produced by any upstream mapping. The dealer codes you can actually receive today are CHANGE, METAL, CORROSION, SCRATCH, DAMAGE, and the RANK_* attributes. WELD / HILLS are listed so your renderer tolerates them if they start appearing — fall back to panel.description for any code you don’t recognize.
damage_codes when a non-rank code is also present. A panel with ["RANK_ONE", "CHANGE"] upstream emits damage_codes: ["CHANGE"] from this API — the rank attribute is collapsed in favor of the more specific damage code. You will only see RANK_ONE/RANK_TWO/RANK_A/RANK_B/RANK_C in damage_codes when it is the only code for that panel (i.e., when Encar reported a rank with no accompanying statusTypes entry — rare in practice).For per-rank breakdown, do not derive from damage_codes. Use the aggregate counts in inspection_report.dealer_inspection.{critical_frame_damage, exterior_damage}. See section 3.7.4.7 Severity is server-computed — trust the emitted field
Theseverity field on each panel is set server-side and is the only signal you should use for color coding. Severity rules differ per source (each source has its own code-to-severity table at ingest time, e.g. Glovis maps w → medium while AJ maps W → high), and frame panels may be promoted at the unified-mapping layer for some sources. The compounding rules are not stable contract — they may evolve as we ingest new inspectors.
What is stable contract:
| Field | Stability |
|---|---|
The set of possible severity values: "high" | "medium" | "low" | "none" | Stable |
| The color you should pick for each value | Stable (see Color tokens) |
| The per-source code-to-severity mapping at ingest time | Not stable — may evolve |
| Whether frame panels are auto-promoted | Not stable — varies per source |
panel.severity for color picking. Do not re-derive from damage_code or damage_codes — your local re-derivation will drift from server behavior as we tune the per-source tables, and you’ll either over-color (false alarms) or under-color (silent damage) edge cases.
If you need to display a textual rationale alongside the marker, render panel.description — it is the localized English explanation of the panel’s damage state, regardless of source.
5. Panel ID Catalog
panel_id values use two different naming conventions depending on the source:
| Source | Convention | Example |
|---|---|---|
| Glovis, SK, AJ, Lotte, KCar (auction) | kebab-case | front-door-l, front-wheel-house-r |
| Encar (dealer) | camelCase, passed through from Encar’s raw outers[].partId / panelId | rearDoorRight, frontDoor, hood |
5.1 Auction panel IDs (kebab-case)
This is the complete set currently emitted by the auction inspectors. New IDs may be added over time (additive); your client should fall back gracefully on unknowns (see the Note at the end of this section).Exterior panels
panel_id | English label | Marker placement (top-down body view) |
|---|---|---|
hood | Hood | Front-center, just behind the front bumper |
roof | Roof | Center, above the cabin |
trunk | Trunk / Tailgate | Rear-center, just ahead of the rear bumper |
front-bumper | Front Bumper | Front edge, full width |
rear-bumper | Rear Bumper | Rear edge, full width |
front-door-l / front-door-r | Front Door (L/R) | Mid sides, ahead of B-pillar |
rear-door-l / rear-door-r | Rear Door (L/R) | Mid-rear sides, behind B-pillar |
front-fender-l / front-fender-r | Front Fender (L/R) | Front sides, between bumper and door |
rear-fender-l / rear-fender-r | Rear Fender (L/R) | Rear sides, between door and bumper |
side-sill-l / side-sill-r | Side Sill (L/R) | Lower body edge, full length under the doors |
front-light-l / front-light-r | Front Light (L/R) | Headlamp positions on front fascia |
rear-light-l / rear-light-r | Rear Light (L/R) | Tail-lamp positions on rear fascia |
Frame panels
panel_id | English label | Marker placement (top-down chassis view) |
|---|---|---|
radiator-support | Radiator Support | Front-center, behind front panel |
cross-member | Cross Member | Front, transverse beam |
front-side-member-l / front-side-member-r | Front Side Member (L/R) | Front longitudinal beams |
side-member-l / side-member-r | Side Member (L/R) | Mid rocker / frame rails |
side-member-frame | Side Member (Frame) | Truck-style frame rail when present |
front-side-member | Front Side Member | Single-rail front variant when present |
rear-side-member-l / rear-side-member-r | Rear Side Member (L/R) | Rear longitudinal beams |
front-wheel-house-l / front-wheel-house-r | Front Wheel House (L/R) | Around front wheel arches |
rear-wheel-house-l / rear-wheel-house-r | Rear Wheel House (L/R) | Around rear wheel arches |
wheel-house-l / wheel-house-r | Wheel House (L/R) | Generic wheel-arch variant |
a-pillar-l / a-pillar-r | A-Pillar (L/R) | Between hood and front door |
b-pillar-l / b-pillar-r | B-Pillar (L/R) | Between front and rear doors |
c-pillar-l / c-pillar-r | C-Pillar (L/R) | Between rear door and quarter |
inside-panel-l / inside-panel-r | Inside Panel (L/R) | Left/right longitudinal inner beams |
rear-inside-panel-l / rear-inside-panel-r | Rear Inside Panel (L/R) | Rear inner beams |
dash-panel | Dash Panel | Mid, between engine bay and cabin |
floor-panel | Floor Panel | Center, full underbody |
trunk-floor | Trunk Floor | Rear, behind rear seats |
rear-panel | Rear Panel | Rear-center under trunk |
package-tray | Package Tray | Behind rear seats, under rear glass |
seat-back-panel | Seat Back Panel | Vertical panel behind rear seats |
5.2 Dealer panel IDs (camelCase, derived from Encar type.code)
Dealer responses come from Encar’s https://api.encar.com/v1/readside/inspection/vehicle/{id} endpoint. Each outers[] entry has a nested type.code (Encar’s panel identifier, e.g. P062) and a type.title (Korean label). The partner API reads these and emits:
panel_id— translated via the internal Encar panel-code map to a canonical camelCase token (quarterPanelRightforP062,frontFenderLeftforP021). When the upstreamtype.codeis not yet in the map, the raw code passes through verbatim ("P099") so partners still have a stable per-panel identifier.raw_panel_code— the unmodified Encartype.codevalue (e.g."P062"). Always present when upstream provided it.raw_label_ko— the unmodified Encartype.titlevalue (Korean, e.g."쿼터 패널(우)"). Always present when upstream provided it.label— the English label from the map when canonical-mapped, otherwise the raw Korean title.
panel_id values. If your PANEL_COORDS map does not contain the panel_id you receive (because it’s a raw P-code that we haven’t yet added to our canonical map, or a new code Encar emitted that we haven’t seen), fall back to listing the panel by label in a textual “Affected panels” list under the diagram. Use the raw_label_ko field if you want to display the Korean label alongside or instead. Do not drop the panel silently.A pattern that handles both canonical and raw passthrough:panel_${index+1} IDs are rare today — they only appear when Encar’s response omits both type.code and all legacy flat fields, which is unusual. Most dealer panels you receive will have either a canonical camelCase ID or a raw P-code.Example panel_id (camelCase) | Equivalent English label |
|---|---|
hood | Hood |
frontDoor / frontDoorLeft / frontDoorRight | Front Door (L/R) |
rearDoor / rearDoorLeft / rearDoorRight | Rear Door (L/R) |
frontFender / frontFenderLeft / frontFenderRight | Front Fender (L/R) |
rearFender / rearFenderLeft / rearFenderRight | Rear Fender (L/R) |
trunkLid | Trunk Lid |
roof | Roof |
frontBumper / rearBumper | Front / Rear Bumper |
quarterPanel / quarterPanelLeft / quarterPanelRight | Quarter Panel (L/R) |
panel.label field carries a human-readable rendering when available; when it is not, it falls back to the raw panel_id string.
5.3 Catalog completeness and fallbacks
This catalog reflects the set of IDs currently in use as of the latest release. New IDs may be added (additive — never a breaking change) as inspector data formats evolve. Your client must handle unknown IDs gracefully:panel_id arrives that is not in your PANEL_COORDS map, do not drop the panel silently. Fall back to listing it by label in a textual “Affected panels” section under the diagram. The damage is real even when you don’t have a marker position for it; suppressing the entry hides information from your customer.A change-resilient pattern:6. The Inspection Report card
The card titled “Inspection Report” or ” Grade” onlmnauto.com. For live comparison, see any auction listing at https://lmnauto.com/en/auction?source=auctions&tab=glovis_<date>_<auction_id>_<lot_id> — the worked example in §11 uses glovis_20260521_1078_1005 (Hyundai Sonata 2020).
6.1 Visual structure
6.2 Response shape
source: "aj") response, so dealer_inspection is omitted entirely from the JSON — it would only appear when source === "dealer".6.3 Field reference
| Field | Type | Meaning |
|---|---|---|
source | string | "glovis" | "sk" | "aj" | "lotte" | "kcar" | "dealer". Drives the badge label (“Glovis Grade” / “SK Grade” / “AJ Sellcar Grade” / “Lotte Grade” / “KCar Grade” / “Encar Dealer Inspection”). |
overall_grade | string | null | Two-part grade rendered in the top-left badge. Examples below. null for dealer. |
grade_description | string | One-line explanation of what the two parts of overall_grade represent for this source. Render as a small italic line under the badge or as a tooltip on hover. |
accident_summary | string | null | One-line accident verdict. Display next to the Accident Grade row. |
has_accident | boolean | Drives the green/red top-right pill. |
has_frame_damage | boolean | More specific — distinguishes accident history from current frame damage (a repaired accident may leave has_accident=true but has_frame_damage=false). Useful if you want a separate visual signal for “structural risk” vs “any accident in the past”. |
exterior_summary | string | null | One-line exterior verdict. Display next to the Exterior Grade row. |
accident_reason | string | null | More detailed accident description. Glovis and AJ only. Renders as a smaller secondary line under accident_summary. |
category_grades[] | array | One row per category (frame, exterior, engine, suspension, electrical, interior, etc.). Each { category, status }. See section 6.4 for status colors. |
checklist[] | array | Per-item checklist. Each { group, item, result }. Populated for auction and dealer (encar_*) sources, EN-translated. See section 6.5. |
accident_history[] | array | Per-incident records. Glovis + AJ. Each entry has structured incident fields (date, description, severity). See section 6.6. |
accident_cost_summary | object | null | { total_incidents, total_repair_cost, breakdown: { parts, labor, paint }, insurance_paid, incidents[] }. All values are USD whole integers. Already FX-converted server-side. incidents[] (Glovis; [] when the source has no per-incident breakdown) lists one entry per insurance-settled accident: { date: string | null, insurance_paid, repair_cost: number | null }. insurance_paid is the sum of incidents[].insurance_paid — i.e. the per-incident payouts always reconcile exactly to the total (rounding is applied per incident, then summed). Render as: accident count → per-incident payout → total. |
issues[] | array | Normalized “issues found” entries from all sources. Each { category, status, detail, faults: string[], type }. See section 6.7. |
inspection_sheet_url | string | null | HTTPS link to the original inspection-sheet PDF. Populated for SK and AJ auction sources; null for all other sources, including dealer. Render as a “View original inspection sheet” link when present. |
inspector_notes | string | null | Free-text observations, in English. Auction reports carry the LMN inspector’s notes (translated offline). Dealer (encar_*) reports carry the Encar inspector’s opinion (특기사항 및 점검자의 의견), translated to English via Google Translate on the fetch path. Render as a quote block. |
dealer_inspection | object | Dealer-only sub-object — absent (not null) on auction responses. Present only when source === "dealer". See section 6.8. |
6.4 category_grades[] rendering
status | English label | Pill background | Pill text |
|---|---|---|---|
good | ”Good” | #ECFDF5 (emerald-50) | #047857 (emerald-700) |
caution | ”Caution” | #FFFBEB (amber-50) | #B45309 (amber-700) |
bad | ”Needs attention” | #FEF2F2 (red-50) | #B91C1C (red-700) |
category:
category raw value | Display label |
|---|---|
frame | ”Accident Grade” |
exterior | ”Exterior Grade” |
engine | ”Engine” |
transmission | ”Transmission” |
brakes | ”Brakes” |
suspension | ”Suspension” |
electrical | ”Electrical” |
interior | ”Interior” |
glass | ”Glass” |
lighting | ”Lighting” |
(unknown) | Fall back to capitalize-first (engine → “Engine”) |
6.5 checklist[] rendering
The checklist is grouped by group. Render as a collapsible list, with group as section header and one row per item. The result field contains the raw inspector verdict and is often in Korean — display as-is unless you maintain a translation map (see Korean Glossary).
Item count by source:
- Glovis: exactly 17 items. Groups: Engine, Transmission, Brakes, Steering, Electrical, Body, Glass, Interior.
- AJ: up to 39 items. Same group taxonomy plus suspension, fuel system, cooling system.
- SK / Lotte / KCar: 5-8 items, sparse coverage.
- Dealer: always
[].
6.6 accident_history[] rendering
Each entry has structured fields (subject to source variation):
type field distinguishes “owner_self” (the current/past owner caused it) from “third_party” (someone else was at fault for the damage). Korean carfax convention treats these very differently for pricing.
6.7 issues[] rendering
Normalized “issues found” across all sources. Each entry:
| Field | Meaning |
|---|---|
category | Display label for the issue’s category. |
status | "bad" | "caution" — color coding. |
detail | One-line description of the issue. |
faults[] | Damage codes associated (links back to the Damage Code Dictionary). |
type | "mechanical" | "body" | "functional" — drives the icon (wrench / car-outline / power-cog). |
status.
6.8 dealer_inspection (dealer-only)
When source === "dealer", this sub-object carries Encar-specific aggregate data:
| Field | Type | Meaning |
|---|---|---|
critical_frame_damage | integer | Count of frame-rank panels (RANK_A/B/C). Matches the Frame Damage count box. |
exterior_damage | integer | Count of exterior-rank panels (RANK_ONE/TWO). Matches the Exterior Damage count box. |
frame_status | string | null | Raw Encar frame status string in Korean. Common values: "이상없음" (no issues), "교환" (replaced), "판금" (sheet metal). |
panel_status | string | null | Raw Encar panel status string. Often includes a count, e.g. "교환 1" (1 replacement), "이상없음". |
simple_repair | boolean | null | Encar’s 단순수리 (simple repair) flag. null when the page doesn’t state it. |
insurance_history | integer | null | Own-damage accident claim count, sourced from a separate insurance-record upstream. null means “no data reported”, 0 means “no claims”. |
insurance_amount | integer | null | Total own-damage insurance payout in whole USD, FX-converted server-side (same convention as accident_cost_summary). Do not re-apply fx_rate. null means “no data reported”, 0 means “no claims”. |
registration_no | string | null | 성능번호 — the inspection-sheet registration number. |
vehicle_info | object | Inspection-form-specific particulars only — Valid Period, First Registered, Warranty, Engine Model, Base Price (KO→EN translated). Identity fields that duplicate the top-level resource (make/model, year, plate, VIN, transmission, fuel) are intentionally omitted — read those from the top-level Vehicle fields. Render as a key-value list. |
overall_status | array of { item, status, detail } | Section-2 rows (emissions, tuning, special history, usage change, recall, odometer, VIN marking, color, major options). item and status are translated; detail is raw. |
photos | array of { url, label } | Inspection front/rear photos. label is translated. |
certification | object { inspector, notifier, date } | null | Inspecting body and notifier. inspector and notifier are raw Korean company names; date is translated. null when the sheet carries no certification block. |
7. Overall grade interpretation
Theoverall_grade field is a two-part string "X/Y". The semantics differ per source. The grade_description field tells you which is which for the current row, but here’s the master decoder:
| Source | Format | Left part | Right part |
|---|---|---|---|
| Glovis | "A/7" to "D/1" | Letter: accident grade (A = no accident, B/C/D = increasing severity) | Digit 1-9: condition score (9 = best, 1 = worst) |
| SK | "A/A" to "C/C" | Letter: accident grade | Letter: exterior letter grade (A = best) |
| AJ | "A/A" to "C/C" (digit-converted from raw numbers) | Letter: frame grade (A/B/C) | Letter: exterior letter grade (converted from a 1-5 digit scale internally) |
| Lotte | "A/A" to "C/C" | Letter: accident grade | Letter: exterior letter grade |
| KCar | "A/A" to "C/C" | Letter: accident grade | Letter: exterior letter grade |
| Dealer | null | — | — |
/ separator. The exact pixel layout in the LMN reference UI is a 56×56 square with both characters rendered in a serif font centered.
Pill colors by overall grade
A quick heuristic for badge background:| Pattern | Color |
|---|---|
Both parts A or score ≥ 7 | Emerald (#10B981) |
| One part B / score 5-6 | Amber (#D97706) |
| Any part C/D or score ≤ 4 | Red (#DC2626) |
null (dealer) | Slate (#475569) |
8. Color tokens reference
Exact colors used in the lmnauto.com reference UI. Use these or your design-system equivalents.| Token | Hex | Tailwind | Purpose |
|---|---|---|---|
--inspection-good-bg | #ECFDF5 | bg-emerald-50 | Good status background |
--inspection-good-fg | #047857 | text-emerald-700 | Good status text |
--inspection-caution-bg | #FFFBEB | bg-amber-50 | Caution status background |
--inspection-caution-fg | #B45309 | text-amber-700 | Caution status text |
--inspection-minor-bg | #FEFCE8 | bg-yellow-50 | Minor severity background |
--inspection-minor-fg | #A16207 | text-yellow-700 | Minor severity text |
--inspection-bad-bg | #FEF2F2 | bg-red-50 | Bad status background |
--inspection-bad-fg | #B91C1C | text-red-700 | Bad status text |
--inspection-marker-high | #DC2626 | bg-red-600 | High-severity panel marker |
--inspection-marker-medium | #D97706 | bg-amber-600 | Medium-severity panel marker |
--inspection-marker-low | #CA8A04 | bg-yellow-600 | Low-severity panel marker |
--inspection-marker-exchange | #DC2626 | bg-red-600 | Exchange (CHANGE) overlay |
--inspection-text-muted | #64748B | text-slate-500 | Tooltip / “Learn more” links |
--inspection-card-bg | #FFFFFF | bg-white | Card background |
--inspection-card-border | #E2E8F0 | border-slate-200 | Card border |
9. Korean Glossary
The following raw Korean strings may appear indealer_inspection.frame_status, dealer_inspection.panel_status, inspection_report.checklist[].result, and in some accident_history[].description entries. Maintain a client-side translation map if you want English-only UI.
9.1 Status terms
| Korean | English | Where it appears |
|---|---|---|
| 이상없음 | ”No issues” | frame_status, panel_status, checklist result |
| 양호 | ”Good” / “Pass” | checklist result |
| 불량 | ”Bad” / “Fail” | checklist result |
| 이음 | ”Joint” / “Caution” | checklist result |
| 교환 | ”Replaced” | panel_status |
| 판금 | ”Sheet metal” | panel_status, description |
| 용접 | ”Welded” | panel_status, description |
| 부식 | ”Corrosion” | panel_status, description |
| 손상 | ”Damaged” | panel_status |
| 균열 | ”Cracked” | panel_status |
| 누유 | ”Oil leak” | checklist result |
| 누수 | ”Water leak” | checklist result |
| 소음 | ”Noise” | checklist result |
| 미세누유 | ”Minor oil leak” | checklist result |
| 미세누수 | ”Minor water leak” | checklist result |
9.2 Category terms (in accident_history[].description)
| Korean | English |
|---|---|
| 본넷 | Hood |
| 트렁크 | Trunk |
| 도어 | Door |
| 펜더 | Fender |
| 휀더 | Fender (alt spelling) |
| 쿼터패널 | Quarter panel |
| 루프 | Roof |
| 프론트범퍼 | Front bumper |
| 리어범퍼 | Rear bumper |
| 라디에이터서포트 | Radiator support |
| 사이드멤버 | Side member |
| 인사이드패널 | Inside panel |
| 휠하우스 | Wheelhouse |
| 대시패널 | Dash panel |
| 플로어패널 | Floor panel |
| 좌 | Left |
| 우 | Right |
| 전 | Front |
| 후 | Rear |
9.3 Translation strategy
The safest approach is client-side translation with raw fallback — translate known terms, leave unknowns intact:10. Full reference renderer (React)
This is a complete, production-ready React component that consumes the JSON and renders both panels. Adapt to your component library — the logic is the contract.11. Worked example A — Glovis auction (real API response)
This is a verbatim slice of a realGET /v1/vehicles/{id} response from sandbox at the time of writing. Sandbox base URL is https://sandbox-api.lmnauto.com; production is https://api.lmnauto.com (see Quickstart for both). The response shape is identical across environments — sandbox just runs against the staging data snapshot.
Request
image_url: null and dealer_inspection absent. This is a Hyundai Sonata 2020 with significant frame damage history (overall grade C/1).
image_urlisnullfor Glovis. Glovis (and K-Car, dealer) have no mirrored image — render the diagram frompanels[]directly. SK and Lotte do return a mirroredimage_url(damage baked in), and AJ returns a blueprint base image drawn under the markers.accident_summaryandaccident_reasonarenulleven thoughhas_frame_damage: true. Don’t gate the “Accident History” pill onaccident_summarybeing non-null; usehas_accident/has_frame_damagedirectly.checklisthas 48 items, not the canonical “17 items” that older documentation mentions. The count varies per inspection — render whatever the array contains.- Some
panel.labelvalues are Korean (e.g."리어휠하우스(좌)") even though others are English. The Korean-to-English mapping is incomplete; displaylabelas-is and translate client-side if you need an English-only UI. See the Korean Glossary. category_grades[].categorycan be Korean ("동력"in this row) for categories not yet in the English mapping.exterior_summaryhere describes mechanical issues (engine/transmission), not exterior panels. The field name is historically misleading on Glovis — it’s effectively a free-text “summary of issues found” rather than strictly panel-related.
- Badge:
C/1on red (C is left, 1 is the worst condition score). - Pill: green No Accident (
has_accident: false) — but a separate caution callout forhas_frame_damage: trueis healthier UX, since the car has significant frame welding. - Body Inspection card:
- Counts: Frame 11 panels (mostly medium
w, one highxx=rear-panel), Exterior 6 panels (highxxonly — five rear/side replacements). - Diagram: render from
panels[]becauseimage_urlis null. Markers: 6 red on exterior silhouette, 1 red + 10 amber on frame silhouette.
- Counts: Frame 11 panels (mostly medium
- Category rows: 9 entries — render two reds (“Engine”, “Shift Issue”) and seven greens. The Korean
동력row renders as-is unless you translate client-side. - Checklist: collapsible list with 48 items (group-by-group).
- Issues Found: 2 entries.
- Inspector notes block: long run-on string of replacement summaries.
- No accident_cost_summary, no accident_history entries (the frame damage exists but no structured accident record is currently associated).
12. Worked example B — Encar dealer (real API response)
This is a verbatim slice of a realGET /v1/vehicles/{id} response from sandbox. It is a BMW M5 2019 listing with two ranked exterior panels — a clean worked example of the canonical dealer shape described in §5.2 and §4.6: nested type.code translated to a drawable camelCase panel_id, and statusTypes[] normalized into canonical damage codes.
Request
- Both panels have canonical camelCase
panel_idvalues (quarterPanelRight,frontFenderLeft) drawable directly on the standard Encar silhouette. raw_panel_codepreserves the upstream Encar P-code (P062,P021) so you can correlate against Encar’s own admin tooling or display the raw value alongside the canonical one.raw_label_kocarries the upstream Korean label verbatim — useful if your customer base includes Korean speakers or for showing both languages side-by-side.damage_codeis the canonical normalized code derived from Encar’sstatusTypes[](W →METAL, X →CHANGE) — not the rank attribute. The rank attribute (RANK_TWO,RANK_ONE) remains preserved in the aggregatedealer_inspection.exterior_damagecount (2).severityis computed from the canonical damage code:METAL→medium(sheet metal repair),CHANGE→high(replacement). Use the emitted value directly; do not re-derive locally.frame_status: null,panel_status: nullfor this car — Encar didn’t return the descriptive status strings. Render the dealer summary with placeholder dashes for those fields.insurance_history: 1,insurance_amount: 1370— own-damage accident history is populated for dealer cars from a separate insurance-record upstream; the amount is whole USD (FX-converted server-side), matching the auctionaccident_cost_summaryconvention — don’t re-applyfx_rate. Anull(not0) still means “no data reported”;0means “no claims”.vehicle_info,overall_status,photos,certificationcarry the full inspection-sheet detail. Rendervehicle_infoas a key-value list,overall_statusas a status table,photosas a thumbnail row, andcertificationas a small attribution line.
- Badge: slate
—(nooverall_grade). Title: “Encar Dealer Inspection”. - Pill: green No Accident (
has_accident: false). - Two grade rows: green “Accident Grade” + “No structural damage”, amber “Exterior Grade” + “2 exterior damage cases”.
- Mechanical
checklist[]present (engine, transmission, steering, braking, electrical, …, EN-translated); inspector notes present; no auction-only accident-cost summary. - Dealer summary block at bottom:
frame_status/panel_statusdash (null this car);exterior_damage: 2, insurance history (1claim, $1,370), plus thevehicle_info/overall_status/photos/certificationsheet detail carry the real signal. - Body Inspection card:
- Count boxes: Frame 0 (green “No structural damage”), Exterior 2 (red “Major damage” — driven by the high-severity
CHANGEon the front-fender-left). - Diagram: amber marker on the right quarter panel (
quarterPanelRight, METAL/medium), red marker with×overlay on the left front fender (frontFenderLeft, CHANGE/high). - Affected panels list: empty — both panels are drawable.
- Count boxes: Frame 0 (green “No structural damage”), Exterior 2 (red “Major damage” — driven by the high-severity
- Rank summary below diagrams: “Exterior — 2 ranked panels”, “Frame — None”.
13. Edge cases (full list)
Both objects null
Both objects null
One null, one populated
One null, one populated
body_conditionnull butinspection_reportpopulated → no diagram, show the grade card alone with all available fields.body_conditionpopulated butinspection_reportnull → diagram alone with the count boxes; omit any reference to grade.
Unknown panel_id
Unknown panel_id
panel_id not in your PANEL_COORDS map (we extend the catalog as inspector data evolves), do not drop the panel. Render it in a textual list under the diagram via the UnknownPanels component in section 10. The damage is real even if you don’t have a marker position for it.Korean status strings in dealer fields
Korean status strings in dealer fields
dealer_inspection.frame_status and panel_status are raw Encar Korean. Either display as-is (your end customers may include Korean speakers) or translate via section 9’s dictionary. The panel_status value sometimes includes a count suffix ("교환 1") — strip and translate the term, preserve the digit.accident_cost_summary in USD
accident_cost_summary in USD
fx_rate on the vehicle response is null, this field is also null.incidents[] (Glovis) lists one row per insurance-settled accident — { date, insurance_paid, repair_cost }. The aggregate insurance_paid equals the sum of incidents[].insurance_paid: rounding to whole USD is applied per incident and then summed, so a per-incident breakdown always reconciles exactly to the total (don’t recompute from the won amounts client-side). When incidents[] is [] (a source with no per-incident detail), fall back to showing the count + aggregate only.Auction sources without image_url
Auction sources without image_url
image_url. SK / AJ / Lotte / KCar all return null — draw your own diagram from panels[]. Dealer is the same.Checklist with empty result
Checklist with empty result
checklist[].result values may be empty strings (the inspector marked the item but left the result blank). Treat as missing — render the item with a — placeholder, do not skip the item.Dealer panels with both rank and damage codes
Dealer panels with both rank and damage codes
RANK_ONE) and a damage marker (e.g., CHANGE). When this happens the API collapses damage_codes to the non-rank code(s) only — so you will see damage_codes: ["CHANGE"], not ["RANK_ONE", "CHANGE"].The rank attribute is not lost — it is reflected both in the aggregate counts under inspection_report.dealer_inspection.{critical_frame_damage, exterior_damage} and, per-rank, in inspection_report.dealer_inspection.rank_counts ({ rank_one, rank_two, rank_a, rank_b, rank_c }). rank_counts is tallied from the rank attributes before the damage_codes collapse described above, so it stays accurate even for panels that carry both a rank and a damage code.This means: on a single dealer panel you see one marker on the diagram colored by the panel’s severity (computed from the strongest code present), and the totals beneath the diagram come from dealer_inspection, not from damage_codes.Accident history with no cost summary
Accident history with no cost summary
accident_history may be populated while accident_cost_summary is null (the source recorded an accident but the cost details weren’t captured). Render the history regardless.Stale checklist items from older inspections
Stale checklist items from older inspections
14. Localization
The inspection text is in English by default (translated server-side from Korean source data). For RTL languages (Arabic in particular):| Source | Output |
|---|---|
inspection_report.exterior_summary | English-only |
inspection_report.accident_summary | English-only |
inspection_report.accident_reason | English-only |
inspection_report.inspector_notes | English — auction translated offline, dealer translated live via Google Translate |
inspection_report.grade_description | English-only |
inspection_report.checklist[].result | Korean — translate client-side |
inspection_report.checklist[].item | English |
dealer_inspection.frame_status / panel_status | Korean — translate client-side |
accident_history[].description | Mixed; often Korean for older records — translate client-side |
15. Performance and caching
- The detail response is cached server-side for 30 minutes per ID (Encar dealer detail) or until the next inspection ingest (auction). Refetching more often than every 5 minutes per car is wasteful.
- The inspection diagram (
image_url) is served from GCS with a 7-day cache header. Safe to use directly in<img src>without your own caching layer. - The full response size with inspection populated runs 8-25KB. Keep that in mind if you’re streaming many details client-side.
16. Verification checklist
Before you ship your rendering, verify each of these against the reference UI:Empty state renders correctly
body_condition and inspection_report both null). Confirm a single neutral message appears, not an empty card.Dealer-source renders correctly
encar_* ID. Confirm:- No overall_grade badge (slate
—) - “Encar Dealer Inspection” source label
- Dealer summary block at bottom (vehicle info, overall status, photos, certification, insurance history)
- Rank breakdown table under diagrams
- Mechanical
checklist[]present (EN-translated); inspector notes present; no auction-only accident-cost summary
Glovis rich auction renders correctly
glovis_* ID with frame damage. Confirm:overall_gradebadge in correct color band- Red “Accident History” pill
- All category rows render with correct status colors
- Checklist with 17 items, collapsible
- Accident History with at least one entry
- Accident Cost section with USD amounts
- Inspector notes as quote block
image_urlrendered as<img>, not SVG
Severity coloring matches
- High-severity panels show red markers
- Medium-severity show amber
- Low-severity show yellow outline
CHANGEpanels have an×overlay- Count boxes color-match their max severity
Unknown panel fallback works
panel_id not in your PANEL_COORDS (e.g., temporarily delete one entry). Confirm the panel appears in the “X affected panels not shown on diagram” expandable list, not dropped silently.Korean fallback works
frame_status / panel_status either translates correctly or displays as-is (no undefined, no empty render).USD amounts not re-converted
accident_cost_summary, confirm the values render exactly as returned — no client-side division by FX, no rounding errors.17. FAQ
Why is body_condition.image_url only set for Glovis?
Why is body_condition.image_url only set for Glovis?
outers[] from their API, no diagram). If you can’t build SVG rendering, fall back to listing damaged panels by label and skipping the diagram entirely; the count boxes still convey the high-signal info.Why is overall_grade null for dealer cars?
Why is overall_grade null for dealer cars?
How accurate is the dealer inspection?
How accurate is the dealer inspection?
checklist[] (engine, transmission, steering, braking, electrical, …), inspection photos, certification, insurance history, and inspector notes. The remaining gap versus an LMN auction inspector’s report is the auction-only accident_history[] per-incident breakdown and accident_cost_summary. For high-stakes decisions (export, customs), encourage your customer to request an LMN secondary inspection — that’s available on the auction tab but not for dealer listings.Can I rely on category_grades order?
Can I rely on category_grades order?
frame, exterior, engine, transmission, brakes, suspension, electrical, interior, glass, lighting. Categories not applicable to the source are omitted. Don’t sort client-side; just render in array order.What's the difference between has_accident and has_frame_damage?
What's the difference between has_accident and has_frame_damage?
has_accident = there’s at least one accident in the car’s history (could be a long-ago repair, or a current visible issue). has_frame_damage = there’s structural (frame) damage currently visible. A repaired car may have has_accident: true but has_frame_damage: false. Use both signals for nuanced messaging — “previously repaired” vs “currently damaged” are very different stories to a buyer.Are accident_history entries reliably ordered?
Are accident_history entries reliably ordered?
What if the same panel appears twice in panels[]?
What if the same panel appears twice in panels[]?
panel_id. If you see it, file a bug; meanwhile, render the first occurrence and ignore subsequent.What if I want to show the original Korean alongside the English?
What if I want to show the original Korean alongside the English?
accident_reason, exterior_summary, etc. directly. For fields that are raw Korean (dealer_inspection.frame_status, checklist[].result), show both: {translateKR(value)} ({value}) — gives Korean speakers the original and English speakers the translation simultaneously.How is severity computed?
How is severity computed?
panel.severity directly; do not infer from panel_type or damage_code. Severity is set server-side per inspector source — each source has its own code-to-severity table at ingest time, and frame-panel promotion (when it happens) varies by source. Local re-derivation will drift from server behavior as we tune the per-source tables. See section 4.7. The stable contract is the set of possible values ("high" \| "medium" \| "low" \| "none") and the color you pick for each, not the rule that produced it.Why are some panel labels in Korean while others are English?
Why are some panel labels in Korean while others are English?
panel.label. For dealer sources, panel.label is what Encar’s API returns — usually English or the raw camelCase ID. In both cases, your client should display label as-is and not assume it is always English. If you spot consistently-untranslated values, email integrations@lmnauto.com — additions are quick.Can I use this guide for the deprecated v1.16 response shape?
Can I use this guide for the deprecated v1.16 response shape?
18. Versioning and stability
This is part ofGET /v1/vehicles/{id} and follows our versioning policy:
- Additive changes (new fields on
body_condition.panels[], new fields oninspection_report, new fields ondealer_inspection) ship without a version bump. Your renderer must ignore unknown fields safely. - New panel IDs ship without notice (additive). Your
PANEL_COORDSshould have a graceful fallback. - New damage codes ship without notice (additive). Your damage legend should tolerate unknown codes by falling back to
panels[].descriptionfor display. - Removing a field is a breaking change → new major version + 90-day deprecation window + changelog notice.
- Renaming a field is a breaking change → same policy.
- Changing a
severityrule is treated as additive (the rule is server-side; you receive the computed value). We may move panels between severity buckets — the partner-visible contract is the field name and type, not the computation.
inspection_report.dealer_inspection sub-object is new in v1.18 (shipped 2026-05-20). Earlier versions of the doc may not show it.
19. Where to look on lmnauto.com
For pixel-faithful comparison, open the same ID in both places — the consumer site atlmnauto.com and the partner API at sandbox-api.lmnauto.com — and diff the JSON against the rendered UI.
GET /v1/vehicles?source=<src>&limit=1 and use that same ID in both URLs.
If your rendering ever looks materially different from the lmnauto.com reference, diff against the JSON returned from GET /v1/vehicles/{id} for the same ID rather than trying to reverse-engineer the UI. The JSON is the contract; the UI is one possible rendering of it.
20. Support
If you encounter rendering edge cases this guide doesn’t cover, or you find an inconsistency between the JSON and the reference UI, email integrations@lmnauto.com with:- The vehicle ID (auction or dealer)
- The raw JSON response from
GET /v1/vehicles/{id}(paste in full) - A screenshot or description of how your UI rendered it
- A link or screenshot of the corresponding
lmnauto.compage