리포트 데이터와 콘텐츠

report.v1 객관 데이터와 report-content.v1 표시 콘텐츠의 필드, 버전, 이미지 출처, 렌더링 방법을 설명합니다.

ATRACE 리포트를 파트너 화면에서 직접 렌더링할 때는 두 응답을 함께 사용합니다. 아래 예제 JSON과 필드 표도 이 두 버전 계약을 기준으로 설명합니다.

역할엔드포인트스키마변경 방식
측정값·분석 결과·입력 자산·상태GET /reports/{report_id}report.v1재촬영·재분석으로 새 analysis_revision이 생길 수 있음
문구·판정·섹션·시각화용 수치GET /reports/{report_id}/contentreport-content.v1현재 분석에 대응하는 콘텐츠 리비전을 가리킴
과거 콘텐츠의 고정 조회GET /reports/{report_id}/content/{content_revision}report-content.v1발급된 리비전의 응답은 불변

/reports/{id}는 객관 데이터의 기준이고, /content는 그 데이터를 특정 콘텐츠 프로필과 생성 규칙으로 표현한 결과입니다. webhook은 조회 시점을 알려 주는 가벼운 알림이며, 저장과 화면 구성에 사용할 최종 값은 인증된 GET 응답에서 읽으세요.

권장 조회 흐름

GET /reports/{id}를 폴링합니다. analysis_statuspublication_status를 서로 다른 상태로 처리하세요.

analysis_status == "complete"이면 links.content를 호출합니다. 콘텐츠 준비 중이면 202Retry-After: 5가 반환될 수 있습니다.

/contentstatus == "ready"이면 본문과 ETag를 저장합니다. 이후에는 If-None-Match로 조건부 조회할 수 있습니다.

감사 기록이나 이미 발송한 화면을 재현해야 한다면 links.canonical을 저장하고 그 URL을 조회합니다. /content는 현재 리비전의 alias이고, canonical URL은 한 리비전을 고정합니다. canonical API는 부모 리포트에 접근할 수 있는 동안 조회할 수 있으므로 장기 감사가 필요하면 URL뿐 아니라 받은 JSON 본문도 고객사 저장소에 함께 보관하세요.

GET /reports/{id} — 객관 데이터

최상위 필드

필드타입필수설명
schema_versionstring항상 report.v1. 같은 버전 안에서 필드 의미를 바꾸지 않습니다.
report_idstring(UUID)ATRACE 리포트 ID.
analysis_statusenumawaiting_images, processing, partial, complete, failed.
publication_statusenum리포트 공개 상태. unpublished, published, revoked.
summary_statusenum종합 결과 상태. pending, complete, partial, failed.
vehicleobject차량 식별 정보.
client_contextobject생성 요청 때 받은 파트너 식별자와 metadata.
creationobject생성 채널과 분석 모드.
templateobject리포트 생성 시 고정된 템플릿 버전과 충족 조건.
analysis_revisionstring(UUID) | null현재 객관 결과 묶음의 리비전. 아직 결과 묶음이 없으면 null.
slotsarray타이어 위치·이미지 종류별 입력 자산과 분석 결과.
linksobject현재 리포트, 콘텐츠, 활성 공유 화면 링크.
timestampsobject생성·분석 완료·공개·마지막 갱신 시각.

상태를 해석하는 방법

필드의미
analysis_statusawaiting_images분석할 이미지 등록을 기다리는 중
processing등록된 슬롯을 분석 중
partial성공과 실패가 함께 있고 템플릿 조건을 아직 충족하지 못함
complete템플릿의 성공 개수 조건 충족
failed성공한 슬롯 없이 분석이 종료됨
publication_statusunpublished공유 화면이 공개되지 않음
published공유 화면이 공개됨
revoked이전에 공개된 리포트가 현재 비공개 상태임
summary_statuspending종합 판정 대기 중
complete종합 판정 완료
partial일부 결과만 이용 가능
failed종합 판정을 만들 수 없음

분석 완료와 공유 화면 공개는 다른 축입니다. 자체 렌더링만 필요하다면 analysis_status/content 상태를 기준으로 삼고, ATRACE 공유 화면도 사용할 때만 publication_statuslinks.share를 함께 확인하세요.

DELETE /reports/{id}/share로 공유 링크만 회수해도 리포트 자체의 publication_status는 바뀌지 않습니다. 이 경우 links.sharenull이 되며, 링크의 만료·회수 상태는 GET /reports/{id}/share를 기준으로 확인합니다.

차량·요청 컨텍스트·생성 정보

필드타입필수설명
vehicle.plate_numberstring | null생성 요청의 차량 번호.
client_context.external_inspection_idstring | null파트너 검사 1건의 ID.
client_context.external_vehicle_idstring | null파트너 차량 ID.
client_context.metadataobject생성 요청의 사용자 정의 JSON. 전달하지 않으면 {}.
creation.source_channelenumpartner_api, atrace_console, mobile_web.
creation.modeenumautomatic 또는 manual. 수동 리포트는 편마모 콘텐츠를 생성하지 않습니다.

템플릿

필드타입필수설명
template.keystring생성 요청에 적용된 템플릿 키.
template.versionstring생성 당시 고정된 템플릿 버전.
template.requirements[]array이미지 종류별 성공 개수 조건.
requirements[].module_typestring현재는 tire.
requirements[].image_typeenumtread 또는 sidewall.
requirements[].allowed_positionsstring[]이 조건에서 허용하는 타이어 위치.
requirements[].minimum_success_countinteger허용 위치 중 성공해야 하는 최소 슬롯 수.

tire_4t_2s의 사이드월 조건은 특정 두 위치가 아니라 네 위치 중 아무 두 위치입니다. 따라서 기존의 위치별 required boolean을 추론하지 말고 requirements의 개수 규칙을 사용하세요.

슬롯과 자산

필드타입필수설명
slots[].slot_idstringtire.{image_type}.{position} 형식의 안정적 키.
slots[].module_typestring현재는 tire.
slots[].slot.positionenumfront_left, front_right, rear_left, rear_right.
slots[].slot.image_typeenumtread, sidewall.
slots[].statusenum슬롯의 pending, success, failed. analysis.status와 동일.
slots[].assetobject | null등록된 입력 자산. 아직 없으면 null.
asset.asset_idstring(UUID)ATRACE가 이 입력을 식별하기 위해 발급한 불투명 ID.
asset.source.kindenumpartner_url 또는 atrace_upload.
asset.source.urlstring | nullpartner_url이면 생성 요청에 제출한 문자열 그대로, atrace_upload이면 null.
asset.source.client_asset_idstring | null파트너가 선택적으로 제출한 자사 자산 ID. ATRACE 업로드면 null.

asset_idclient_asset_id는 역할이 다릅니다. asset_id는 ATRACE API 안에서 입력을 참조하는 ID이고, client_asset_id는 파트너 시스템과 대조하기 위한 선택 필드입니다.

고객 URL을 제출한 경우

고객 URL 모드에서는 URL 문자열을 파트너가 보낸 형태 그대로 반환합니다. 쿼리 문자열의 순서나 인코딩까지 일치해야 하는 연동은 이 값을 그대로 사용하세요.

{
  "slot_id": "tire.tread.front_left",
  "module_type": "tire",
  "slot": { "position": "front_left", "image_type": "tread" },
  "status": "success",
  "asset": {
    "asset_id": "6df5b94e-7408-4a03-9c44-80d8f46cc780",
    "source": {
      "kind": "partner_url",
      "url": "https://cdn.partner.example/tires/FL.jpg?signature=a%2Bb&order=raw",
      "client_asset_id": "SM-20260722-FL-TREAD"
    }
  },
  "analysis": {
    "status": "success",
    "provenance": "engine",
    "engine": {
      "api": "atrace-ai-engine",
      "api_version": "v2",
      "operation": "tire.tread",
      "result_schema_version": "tire-tread.v2",
      "requested_functions": [
        "aggregated_depth",
        "individual_depths",
        "vehicle_side",
        "tire_rotation",
        "groove_masks",
        "tread_roi"
      ]
    },
    "result": {
      "aggregated_depth": {
        "aggregated_remaining_depth": 5.8,
        "estimated_lifetime": 20
      },
      "individual_depths": {
        "individual_remaining_depth": [5.8, 6.0, 5.9, 6.1]
      },
      "tire_rotation": 90,
      "vehicle_side": "left",
      "groove_masks": [],
      "tread_roi": { "bbox_xyxy_norm": [0.1, 0.08, 0.9, 0.94] }
    },
    "quality": { "recognized": true, "confidence": null },
    "error": null,
    "completed_at": "2026-07-22T03:00:20.000Z"
  }
}

ATRACE 발급 URL로 업로드한 경우

ATRACE 업로드 모드에서는 파트너가 장기 사용 가능한 원본 URL을 제출한 것이 아니므로 source.urlclient_asset_idnull입니다. 화면에 원본 이미지가 꼭 필요하면 자체 스토리지 URL을 제출하는 고객 URL 모드를 권장합니다.

{
  "slot_id": "tire.sidewall.front_left",
  "module_type": "tire",
  "slot": { "position": "front_left", "image_type": "sidewall" },
  "status": "success",
  "asset": {
    "asset_id": "9172738e-15e0-44e5-8d5d-70dc2956ea90",
    "source": {
      "kind": "atrace_upload",
      "url": null,
      "client_asset_id": null
    }
  },
  "analysis": {
    "status": "success",
    "provenance": "engine",
    "engine": {
      "api": "atrace-ai-engine",
      "api_version": "v2",
      "operation": "tire.sidewall",
      "result_schema_version": "tire-sidewall.v2",
      "requested_functions": ["size"]
    },
    "result": {
      "size": {
        "section_width": 205,
        "aspect_ratio": 55,
        "rim_diameter": 16
      }
    },
    "quality": { "recognized": true, "confidence": null },
    "error": null,
    "completed_at": "2026-07-22T03:00:20.000Z"
  }
}

분석 공통 필드

필드타입필수설명
analysis.statusenumpending, success, failed.
analysis.provenanceenum | nullengine, manual, legacy_projection. 대기 중이면 null.
analysis.engineobject | null사용한 API·오퍼레이션·결과 스키마. 대기 또는 수동 입력이면 null.
analysis.resultobject | null성공일 때만 결과.
analysis.qualityobject | null성공일 때 판독 여부와 신뢰도. 제공되지 않은 신뢰도는 null.
analysis.errorobject | null실패일 때 안정적인 coderetryable.
analysis.completed_atdate-time | null슬롯 분석 종료 시각. 대기 중이면 null.

분석 엔진·품질·오류 하위 필드

필드타입필수설명
analysis.engine.apistring분석 API 제품 식별자.
analysis.engine.api_versionstring호출한 API 버전.
analysis.engine.operationenumtire.tread 또는 tire.sidewall.
analysis.engine.result_schema_versionstringanalysis.result의 원천 결과 스키마 버전.
analysis.engine.requested_functionsstring[]분석 요청에 포함된 기능 이름.
analysis.quality.recognizedboolean해당 슬롯의 핵심 결과를 판독했는지 여부.
analysis.quality.confidencenumber | null제공되는 경우의 신뢰도. 엔진이 제공하지 않으면 null.
analysis.error.codestring파트너 분기 처리에 사용할 안정적인 공개 오류 코드.
analysis.error.retryableboolean같은 입력 또는 교체 입력으로 재시도 가능한 오류인지 여부.

대기 슬롯은 provenance, engine, result, quality, error, completed_at이 모두 null입니다. 실패 슬롯은 resultqualitynull이고 error가 채워집니다.

트레드 결과

필드타입필수단위·설명
aggregated_depthobject | null종합 잔여 홈깊이 결과.
aggregated_depth.aggregated_remaining_depthnumber | nullmm.
aggregated_depth.estimated_lifetimenumber | null분석 엔진이 제공한 예상 수명 값.
individual_depths.individual_remaining_depthnumber[]mm. 입력 이미지 좌표 순서의 홈별 깊이.
tire_rotationnumber | null입력 이미지를 시계 방향으로 돌려 표시할 각도.
vehicle_sideenum | nullleft, right, unknown.
groove_masks[]array홈별 정규화 폴리곤.
groove_masks[].depth_mmnumber | null같은 인덱스의 홈 깊이(mm).
groove_masks[].scorenumber | null마스크 신뢰도.
groove_masks[].polygon_xy_norm[number, number][]입력 이미지의 0~1 정규화 좌표. 원점은 좌상단.
tread_roi.bbox_xyxy_norm[number, number, number, number] | null[x1,y1,x2,y2] 입력 이미지 정규화 경계.

사이드월 결과

필드타입필수단위·설명
result.sizeobject | null세 정수 모두 인식된 경우의 규격. 부분 인식은 null.
size.section_widthinteger | null단면폭(mm).
size.aspect_ratiointeger | null편평비(%).
size.rim_diameterinteger | null림 지름(inch).

사이드월 응답에는 원문 표기와 speed marker가 포함되지 않습니다. 현재는 speed marker를 안정적으로 분리하는 계약을 제공하지 않으므로 세 정수만 사용하세요. 콘텐츠의 표시 규격도 205/55 · 16인치처럼 세 정수만 조합하며 임의의 speed marker 문자를 만들지 않습니다.

링크와 시각

필드타입필수설명
links.selfuri이 리포트의 GET URL.
links.contenturi현재 콘텐츠 alias.
links.shareuri | null현재 활성 공유 capability만 반환. 만료·회수·발급 관리는 /share에서 확인.
timestamps.created_atdate-time리포트 생성 시각.
timestamps.analysis_completed_atdate-time | null현재 분석 리비전 완료 시각.
timestamps.published_atdate-time | null현재 공개 상태가 published일 때 공개 시각.
timestamps.updated_atdate-time리포트 마지막 갱신 시각.

GET /reports/{id}/content — 표시 콘텐츠

현재 alias와 canonical 리비전

  • GET /reports/{id}/content: 현재 analysis_revision에 대응하는 콘텐츠를 조회합니다.
  • GET /reports/{id}/content/{content_revision}: 특정 콘텐츠 리비전을 고정 조회합니다.
  • 준비된 현재 alias의 200 응답에는 Content-Location으로 canonical URL이 함께 옵니다.
  • canonical URL에서 이미 발급된 content_revision의 JSON은 변경되지 않습니다.
  • 재분석으로 analysis_revision이 바뀌면 현재 alias가 새 content_revision을 가리킬 수 있습니다.

최상위 필드

필드타입필수설명
schema_versionstring항상 report-content.v1.
report_idstring(UUID)원본 리포트 ID.
statusenumpending, ready, failed.
content_revisionstring(UUID) | null준비된 불변 콘텐츠 ID. 대기·실패면 null.
content_profileobject고객·로케일별 콘텐츠 계약.
generatorobject규칙·문구·렌더 투영 버전.
sourceobject어떤 report 스키마와 analysis_revision에서 생성됐는지 표시.
generated_atdate-time | null콘텐츠 기준 시각. 원천 분석 완료 시각이며, 없으면 리포트 생성 시각.
report_contextobject표시용 번호판·검사시각·템플릿 키.
overallobject | null종합 문구. 준비 전에는 null.
tiresarrayT1~T4 타이어별 판정·문구.
sectionsarray순서가 지정된 리포트 섹션.
render_dataobject오버레이와 규격 표시를 위한 구조화 데이터.
errorobject | null콘텐츠 생성 실패 정보.
linksobject현재 alias, canonical, 원본 report 링크.

프로필과 생성기 버전

필드타입필수설명
content_profile.keystring현재 speedmate-ko.
content_profile.versionstring현재 1.0. 리포트 생성 시 고정.
content_profile.localestring현재 ko-KR.
generator.ruleset_versionstring판정 규칙 버전.
generator.copy_versionstring문구 버전.
generator.projection_versionstring렌더 데이터 투영 버전.
source.report_schema_versionstring현재 report.v1.
source.analysis_revisionstring(UUID) | null콘텐츠가 참조한 객관 결과 리비전.

표시 맥락·종합 결과·링크

필드타입필수설명
report_context.plate_numberstring | null표시용 차량번호.
report_context.inspected_atdate-time | null표시할 검사 시각. 생성 정보가 없으면 null.
report_context.template_keystring리포트에 고정된 이미지 슬롯 템플릿 키.
overall.severityenumgood, caution, critical, unknown.
overall.severity_labelstring종합 상태의 표시 라벨.
overall.headlinestring종합 제목 문구.
overall.paragraphsstring[]종합 설명 문단.
links.selfuri현재 alias URL.
links.canonicaluri | null준비된 불변 콘텐츠 URL. 대기·실패 상태에서는 null.
links.reporturi원본 report.v1 조회 URL.

overall 객체 자체는 콘텐츠가 준비된 경우에만 존재하며 대기·실패 상태에서는 null입니다.

새로운 문구 로직이 출시돼도 기존 canonical 콘텐츠는 바뀌지 않습니다. 새 리포트에서 다른 프로필 버전을 선택할 수 있게 될 때는 POST /reportscontent_profile로 명시합니다. 현재 지원값은 { "key": "speedmate-ko", "version": "1.0", "locale": "ko-KR" }입니다. 화면 문구를 머신 조건으로 비교하지 말고 severity, section_id, metrics 같은 구조화 필드를 사용하세요. 외부 출력 문구·판정·렌더 투영이 달라지면 해당 버전을 올리고, 기존 프로필 구현과 canonical 결과는 그대로 유지합니다. 같은 copy_version의 출력은 수정하지 않습니다.

타이어별 콘텐츠

필드타입필수설명
tires[].slot_idstring대응하는 트레드 슬롯 ID.
tires[].tire_indexenumT1=앞좌, T2=앞우, T3=뒤좌, T4=뒤우.
tires[].positionenum타이어 위치 코드.
tires[].position_labelstring표시용 위치 라벨.
tires[].minimum_remaining_depth_mmnumber | null해당 타이어의 최소 잔여 홈깊이(mm).
tires[].severityenumgood, caution, critical, unknown.
tires[].severity_labelstring표시용 상태 라벨.
tires[].decision_labelstring권장 판단 라벨.
tires[].wear_patternobject | null편마모 코드·라벨·설명. 수동 리포트는 null.
tires[].narrativestring | null타이어별 설명 문구.

편마모 하위 필드

필드타입필수설명
tires[].wear_pattern.codeenumeven_wear, center_wear_overinflation_candidate, both_shoulder_wear_underinflation_candidate, one_shoulder_wear_alignment_candidate, mixed_or_uncertain.
tires[].wear_pattern.worn_shoulderenum | null한쪽 가장자리 마모인 경우 left 또는 right; 그 외에는 null.
tires[].wear_pattern.labelstring표시용 유형 라벨.
tires[].wear_pattern.descriptionstring표시용 유형 설명.

편마모 유형별 일러스트 묶음이 필요한 경우 API와 별도로 전달할 수 있습니다. 파트너는 전달받은 파일을 wear_pattern.code에 매핑해 자체 정적 리소스로 배포합니다.

섹션

모든 섹션은 section_id, order, title, severity, badge_label, paragraphs, metrics를 가집니다. 화면 순서는 배열 순서가 아니라 order를 기준으로 정렬하세요.

공통 필드타입필수설명
sections[].section_idenum섹션 유형을 식별하는 안정적인 키.
sections[].orderinteger오름차순 렌더링 순서.
sections[].titlestring표시용 섹션 제목.
sections[].severityenumgood, caution, critical, unknown.
sections[].badge_labelstring | null표시용 배지 문구. 배지가 없으면 null.
sections[].paragraphsstring[]표시용 설명 문단.
sections[].metricsobjectsection_id별 동적 렌더링과 조건 판단에 사용할 구조화 수치·상태.
section_id목적주요 metrics
tread_wear전체 홈깊이와 법정·점검 기준minimum_remaining_depth_mm, legal_limit_mm, inspection_threshold_mm
braking_distance젖은 노면 제동거리 추정reference_speed_kmh, new_tire_distance_m, current_tire_distance_m, distance_gap_m, distance_gap_car_lengths, speed_at_new_tire_stop_kmh, band
wear_pattern편마모 요약affected_tire_count, codes
position_variance같은 축 좌우 마모 편차front_axle_delta_mm, rear_axle_delta_mm, max_axle_delta_mm
sidewall_spec인식된 규격과 앞뒤 일치 여부recognized_count, front_spec, rear_spec, front_rear_match — 규격 문자열은 예: 205/55 · 16인치이며 speed marker를 포함하지 않음

수동 생성 리포트에는 wear_pattern 섹션이 없고 각 타이어의 wear_patternnull입니다. 클라이언트는 섹션 개수를 고정하지 말고 section_id를 기준으로 렌더링하세요.

제동거리 시각화

제동거리 섹션의 그림은 고정 이미지가 아닙니다. 아래 metrics를 이용해 막대·차량·거리선을 HTML/CSS, Canvas 또는 SVG로 그때그때 렌더링합니다.

{
  "reference_speed_kmh": 100,
  "new_tire_distance_m": 41,
  "current_tire_distance_m": 58,
  "distance_gap_m": 17,
  "distance_gap_car_lengths": 3.8,
  "speed_at_new_tire_stop_kmh": 54,
  "band": "inspect"
}

예를 들어 두 거리 막대의 길이는 같은 스케일로 new_tire_distance_mcurrent_tire_distance_m를 사용하고, 차이는 distance_gap_m으로 표시합니다. 별도의 완성된 제동거리 이미지 리소스는 제공하지 않습니다.

트레드 오버레이 좌표

필드타입필수설명
render_data.tread_overlays[]array자산이 등록된 트레드 슬롯의 오버레이 데이터.
render_data.tread_overlays[].slot_idstring대응하는 트레드 슬롯 ID.
render_data.tread_overlays[].assetobjectreport와 같은 자산 식별자·원본 출처.
render_data.tread_overlays[].tire_rotationnumber | null엔진이 반환한 시계 방향 회전값.
render_data.tread_overlays[].vehicle_sideenum | nullleft, right, unknown; 알 수 없으면 null.
render_data.tread_overlays[].remaining_depths_mmnumber[]groove_masks와 같은 인덱스 순서.
render_data.tread_overlays[].groove_masksarrayreport 결과와 같은 입력 이미지 정규화 마스크.
render_data.tread_overlays[].tread_roiobject | null트레드 영역.
coordinate_system.spacestringinput_image_normalized.
coordinate_system.originstringtop_left.
coordinate_system.x_range, y_range[0,1]좌표 범위.
coordinate_system.rotation_degrees_clockwisenumber표시 전에 적용할 시계 방향 회전.
coordinate_system.mirror_xboolean회전 후 좌우 반전 적용 여부.
coordinate_system.image_orientation_normalizedboolean현재 항상 false; 원본 좌표임을 뜻함.
coordinate_system.mask_depth_orderstringsame_index; 마스크와 깊이의 인덱스가 대응함.

권장 순서는 입력 이미지와 정규화 좌표로 오버레이 구성 → 시계 방향 회전 → 필요하면 좌우 반전입니다. source.url == null인 ATRACE 업로드 자산은 파트너 화면에서 원본 URL로 사용할 수 없으므로 오버레이 원본이 필요한 연동은 고객 URL 모드를 선택하세요.

사이드월 표시 투영

필드타입필수설명
render_data.sidewall_specs[]array자산이 등록된 사이드월 슬롯의 표시 투영.
render_data.sidewall_specs[].slot_idstring대응하는 사이드월 슬롯 ID.
render_data.sidewall_specs[].assetobjectreport와 같은 자산 식별자·원본 출처.
render_data.sidewall_specs[].sizeobject | null인식된 세 정수 규격. 판독하지 못하면 null.
render_data.sidewall_specs[].size.section_widthinteger | null단면폭(mm).
render_data.sidewall_specs[].size.aspect_ratiointeger | null편평비(%).
render_data.sidewall_specs[].size.rim_diameterinteger | null림 지름(inch).
render_data.sidewall_specs[].recognizedboolean표시 가능한 규격을 판독했는지 여부.

콘텐츠 응답 예시

{
  "schema_version": "report-content.v1",
  "report_id": "123e4567-e89b-42d3-a456-426614174000",
  "status": "ready",
  "content_revision": "2fe4ed93-166f-428a-b1ac-d87fcb4538a4",
  "content_profile": {
    "key": "speedmate-ko",
    "version": "1.0",
    "locale": "ko-KR"
  },
  "generator": {
    "ruleset_version": "tire-report-rules.1.0",
    "copy_version": "speedmate-copy.1.0",
    "projection_version": "tire-render.1.0"
  },
  "source": {
    "report_schema_version": "report.v1",
    "analysis_revision": "32ed64db-d943-4a25-99ab-8de411a04bd1"
  },
  "generated_at": "2026-07-22T03:00:22.000Z",
  "report_context": {
    "plate_number": "12가3456",
    "inspected_at": "2026-07-22T03:00:00.000Z",
    "template_key": "tire_4t_2s"
  },
  "overall": {
    "severity": "caution",
    "severity_label": "점검 권장",
    "headline": "일부 타이어의 마모 상태를 점검해 주세요.",
    "paragraphs": ["타이어별 잔여 홈깊이와 마모 편차를 함께 확인해 주세요."]
  },
  "tires": [
    {
      "slot_id": "tire.tread.front_left",
      "tire_index": "T1",
      "position": "front_left",
      "position_label": "front_left",
      "minimum_remaining_depth_mm": 5.8,
      "severity": "good",
      "severity_label": "양호",
      "decision_label": "정상",
      "wear_pattern": {
        "code": "even_wear",
        "worn_shoulder": null,
        "label": "정상 마모",
        "description": "마모가 고르게 진행되고 있습니다."
      },
      "narrative": "마모가 고르게 진행되고 있습니다."
    }
  ],
  "sections": [
    {
      "section_id": "tread_wear",
      "order": 1,
      "title": "타이어 마모 검사",
      "severity": "caution",
      "badge_label": "점검 권장",
      "paragraphs": ["가장 낮은 잔여 홈깊이를 기준으로 상태를 확인했습니다."],
      "metrics": {
        "minimum_remaining_depth_mm": 3.5,
        "legal_limit_mm": 1.6,
        "inspection_threshold_mm": 3
      }
    },
    {
      "section_id": "braking_distance",
      "order": 2,
      "title": "젖은 노면 제동거리",
      "severity": "caution",
      "badge_label": "경고",
      "paragraphs": [
        "현재 타이어의 젖은 노면 추정 제동거리가 새 타이어보다 깁니다."
      ],
      "metrics": {
        "reference_speed_kmh": 100,
        "new_tire_distance_m": 41,
        "current_tire_distance_m": 58,
        "distance_gap_m": 17,
        "distance_gap_car_lengths": 3.8,
        "speed_at_new_tire_stop_kmh": 54,
        "band": "inspect"
      }
    }
  ],
  "render_data": {
    "tread_overlays": [
      {
        "slot_id": "tire.tread.front_left",
        "asset": {
          "asset_id": "6df5b94e-7408-4a03-9c44-80d8f46cc780",
          "source": {
            "kind": "partner_url",
            "url": "https://cdn.partner.example/tires/FL.jpg?signature=a%2Bb&order=raw",
            "client_asset_id": "SM-20260722-FL-TREAD"
          }
        },
        "tire_rotation": 90,
        "vehicle_side": "left",
        "remaining_depths_mm": [5.8, 6.0, 5.9, 6.1],
        "groove_masks": [],
        "tread_roi": { "bbox_xyxy_norm": [0.1, 0.08, 0.9, 0.94] },
        "coordinate_system": {
          "space": "input_image_normalized",
          "origin": "top_left",
          "x_range": [0, 1],
          "y_range": [0, 1],
          "rotation_degrees_clockwise": 90,
          "mirror_x": true,
          "image_orientation_normalized": false,
          "mask_depth_order": "same_index"
        }
      }
    ],
    "sidewall_specs": []
  },
  "error": null,
  "links": {
    "self": "https://app.atrace.ai/api/v1/reports/123e4567-e89b-42d3-a456-426614174000/content",
    "canonical": "https://app.atrace.ai/api/v1/reports/123e4567-e89b-42d3-a456-426614174000/content/2fe4ed93-166f-428a-b1ac-d87fcb4538a4",
    "report": "https://app.atrace.ai/api/v1/reports/123e4567-e89b-42d3-a456-426614174000"
  }
}

위 예시는 필드 설명을 위해 tiressections 배열을 일부만 표시했습니다. 실제 automatic 리포트는 T1~T4 네 개 타이어와 tread_wear, braking_distance, wear_pattern, position_variance, sidewall_spec 섹션을 반환합니다.

준비 중·실패 응답

현재 콘텐츠가 아직 준비되지 않았으면 HTTP 202, Retry-After: 5와 함께 같은 스키마의 status: "pending" 응답이 옵니다. 트레드 분석이 종결 실패한 경우 status: "failed"error.code: "content_source_incomplete"가 옵니다. 두 경우 모두 content_revision, generated_at, overall, links.canonicalnull이고 배열은 빈 배열입니다.

캐시와 동시성

준비된 콘텐츠의 응답에는 canonical JSON을 기준으로 한 약한 ETag가 옵니다.

ETag: W/"4c743d..."

다음 요청에서 그대로 보내세요.

curl "https://app.atrace.ai/api/v1/reports/$REPORT_ID/content" \
  -H "Authorization: Bearer $ATRACE_API_KEY" \
  -H 'If-None-Match: W/"4c743d..."'

변경이 없으면 본문 없는 304 Not Modified가 반환됩니다. 응답은 파트너별 비공개 데이터이므로 공용 CDN 캐시가 아니라 애플리케이션의 인증된 저장소에서 관리하세요.

편마모 그림과 이미지 리소스

  • 편마모 유형별 예시 일러스트는 ATRACE가 준비한 별도 리소스 묶음으로 제공할 수 있습니다.
  • 이 묶음은 API 응답과 별도로 전달합니다. 전달받은 압축 파일을 파트너 애플리케이션의 정적 리소스로 배포하고 wear_pattern.code에 매핑하세요.
  • 제동거리 그림은 고정 이미지가 아니라 braking_distance.metrics를 사용해 동적으로 시각화하므로 별도 완성 이미지 리소스를 제공하지 않습니다.

구현 체크리스트

  • schema_version을 먼저 확인하고 모르는 버전이면 안전하게 중단합니다.
  • 상태·섹션·편마모 코드는 enum으로 분기하고 문구 자체를 머신 조건으로 사용하지 않습니다.
  • JSON 객체에 새 필드가 추가돼도 무시할 수 있게 파서를 작성합니다.
  • 배열 개수는 고정하지 않고 slot_id, section_id, order를 사용합니다.
  • null과 필드 부재를 구분합니다. 이 계약의 필수 필드는 값이 없을 때도 null로 존재합니다.
  • 고객 URL은 asset.source.url을 그대로 사용하고 재구성하거나 정규화하지 않습니다.
  • ATRACE 업로드 자산의 URL을 추측하거나 asset_id로 URL을 조합하지 않습니다.
  • 현재 화면은 /content, 과거 재현은 links.canonical을 사용합니다.

다음 단계

On this page