리포트 데이터와 콘텐츠
report.v1 객관 데이터와 report-content.v1 표시 콘텐츠의 필드, 버전, 이미지 출처, 렌더링 방법을 설명합니다.
ATRACE 리포트를 파트너 화면에서 직접 렌더링할 때는 두 응답을 함께 사용합니다. 아래 예제 JSON과 필드 표도 이 두 버전 계약을 기준으로 설명합니다.
| 역할 | 엔드포인트 | 스키마 | 변경 방식 |
|---|---|---|---|
| 측정값·분석 결과·입력 자산·상태 | GET /reports/{report_id} | report.v1 | 재촬영·재분석으로 새 analysis_revision이 생길 수 있음 |
| 문구·판정·섹션·시각화용 수치 | GET /reports/{report_id}/content | report-content.v1 | 현재 분석에 대응하는 콘텐츠 리비전을 가리킴 |
| 과거 콘텐츠의 고정 조회 | GET /reports/{report_id}/content/{content_revision} | report-content.v1 | 발급된 리비전의 응답은 불변 |
/reports/{id}는 객관 데이터의 기준이고, /content는 그 데이터를 특정 콘텐츠 프로필과
생성 규칙으로 표현한 결과입니다. webhook은 조회 시점을 알려 주는 가벼운 알림이며, 저장과
화면 구성에 사용할 최종 값은 인증된 GET 응답에서 읽으세요.
권장 조회 흐름
GET /reports/{id}를 폴링합니다. analysis_status와 publication_status를 서로 다른 상태로
처리하세요.
analysis_status == "complete"이면 links.content를 호출합니다. 콘텐츠 준비 중이면 202와
Retry-After: 5가 반환될 수 있습니다.
/content의 status == "ready"이면 본문과 ETag를 저장합니다. 이후에는
If-None-Match로 조건부 조회할 수 있습니다.
감사 기록이나 이미 발송한 화면을 재현해야 한다면 links.canonical을 저장하고 그 URL을
조회합니다. /content는 현재 리비전의 alias이고, canonical URL은 한 리비전을 고정합니다.
canonical API는 부모 리포트에 접근할 수 있는 동안 조회할 수 있으므로 장기 감사가 필요하면
URL뿐 아니라 받은 JSON 본문도 고객사 저장소에 함께 보관하세요.
GET /reports/{id} — 객관 데이터
최상위 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
schema_version | string | 예 | 항상 report.v1. 같은 버전 안에서 필드 의미를 바꾸지 않습니다. |
report_id | string(UUID) | 예 | ATRACE 리포트 ID. |
analysis_status | enum | 예 | awaiting_images, processing, partial, complete, failed. |
publication_status | enum | 예 | 리포트 공개 상태. unpublished, published, revoked. |
summary_status | enum | 예 | 종합 결과 상태. pending, complete, partial, failed. |
vehicle | object | 예 | 차량 식별 정보. |
client_context | object | 예 | 생성 요청 때 받은 파트너 식별자와 metadata. |
creation | object | 예 | 생성 채널과 분석 모드. |
template | object | 예 | 리포트 생성 시 고정된 템플릿 버전과 충족 조건. |
analysis_revision | string(UUID) | null | 예 | 현재 객관 결과 묶음의 리비전. 아직 결과 묶음이 없으면 null. |
slots | array | 예 | 타이어 위치·이미지 종류별 입력 자산과 분석 결과. |
links | object | 예 | 현재 리포트, 콘텐츠, 활성 공유 화면 링크. |
timestamps | object | 예 | 생성·분석 완료·공개·마지막 갱신 시각. |
상태를 해석하는 방법
| 필드 | 값 | 의미 |
|---|---|---|
analysis_status | awaiting_images | 분석할 이미지 등록을 기다리는 중 |
processing | 등록된 슬롯을 분석 중 | |
partial | 성공과 실패가 함께 있고 템플릿 조건을 아직 충족하지 못함 | |
complete | 템플릿의 성공 개수 조건 충족 | |
failed | 성공한 슬롯 없이 분석이 종료됨 | |
publication_status | unpublished | 공유 화면이 공개되지 않음 |
published | 공유 화면이 공개됨 | |
revoked | 이전에 공개된 리포트가 현재 비공개 상태임 | |
summary_status | pending | 종합 판정 대기 중 |
complete | 종합 판정 완료 | |
partial | 일부 결과만 이용 가능 | |
failed | 종합 판정을 만들 수 없음 |
분석 완료와 공유 화면 공개는 다른 축입니다. 자체 렌더링만 필요하다면 analysis_status와
/content 상태를 기준으로 삼고, ATRACE 공유 화면도 사용할 때만 publication_status와
links.share를 함께 확인하세요.
DELETE /reports/{id}/share로 공유 링크만 회수해도 리포트 자체의
publication_status는 바뀌지 않습니다. 이 경우 links.share가 null이 되며, 링크의 만료·회수
상태는 GET /reports/{id}/share를 기준으로 확인합니다.
차량·요청 컨텍스트·생성 정보
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
vehicle.plate_number | string | null | 예 | 생성 요청의 차량 번호. |
client_context.external_inspection_id | string | null | 예 | 파트너 검사 1건의 ID. |
client_context.external_vehicle_id | string | null | 예 | 파트너 차량 ID. |
client_context.metadata | object | 예 | 생성 요청의 사용자 정의 JSON. 전달하지 않으면 {}. |
creation.source_channel | enum | 예 | partner_api, atrace_console, mobile_web. |
creation.mode | enum | 예 | automatic 또는 manual. 수동 리포트는 편마모 콘텐츠를 생성하지 않습니다. |
템플릿
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
template.key | string | 예 | 생성 요청에 적용된 템플릿 키. |
template.version | string | 예 | 생성 당시 고정된 템플릿 버전. |
template.requirements[] | array | 예 | 이미지 종류별 성공 개수 조건. |
requirements[].module_type | string | 예 | 현재는 tire. |
requirements[].image_type | enum | 예 | tread 또는 sidewall. |
requirements[].allowed_positions | string[] | 예 | 이 조건에서 허용하는 타이어 위치. |
requirements[].minimum_success_count | integer | 예 | 허용 위치 중 성공해야 하는 최소 슬롯 수. |
tire_4t_2s의 사이드월 조건은 특정 두 위치가 아니라 네 위치 중 아무 두 위치입니다.
따라서 기존의 위치별 required boolean을 추론하지 말고 requirements의 개수 규칙을 사용하세요.
슬롯과 자산
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
slots[].slot_id | string | 예 | tire.{image_type}.{position} 형식의 안정적 키. |
slots[].module_type | string | 예 | 현재는 tire. |
slots[].slot.position | enum | 예 | front_left, front_right, rear_left, rear_right. |
slots[].slot.image_type | enum | 예 | tread, sidewall. |
slots[].status | enum | 예 | 슬롯의 pending, success, failed. analysis.status와 동일. |
slots[].asset | object | null | 예 | 등록된 입력 자산. 아직 없으면 null. |
asset.asset_id | string(UUID) | 예 | ATRACE가 이 입력을 식별하기 위해 발급한 불투명 ID. |
asset.source.kind | enum | 예 | partner_url 또는 atrace_upload. |
asset.source.url | string | null | 예 | partner_url이면 생성 요청에 제출한 문자열 그대로, atrace_upload이면 null. |
asset.source.client_asset_id | string | null | 예 | 파트너가 선택적으로 제출한 자사 자산 ID. ATRACE 업로드면 null. |
asset_id와 client_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.url과 client_asset_id는 null입니다. 화면에 원본 이미지가 꼭 필요하면 자체
스토리지 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.status | enum | 예 | pending, success, failed. |
analysis.provenance | enum | null | 예 | engine, manual, legacy_projection. 대기 중이면 null. |
analysis.engine | object | null | 예 | 사용한 API·오퍼레이션·결과 스키마. 대기 또는 수동 입력이면 null. |
analysis.result | object | null | 예 | 성공일 때만 결과. |
analysis.quality | object | null | 예 | 성공일 때 판독 여부와 신뢰도. 제공되지 않은 신뢰도는 null. |
analysis.error | object | null | 예 | 실패일 때 안정적인 code와 retryable. |
analysis.completed_at | date-time | null | 예 | 슬롯 분석 종료 시각. 대기 중이면 null. |
분석 엔진·품질·오류 하위 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
analysis.engine.api | string | 예 | 분석 API 제품 식별자. |
analysis.engine.api_version | string | 예 | 호출한 API 버전. |
analysis.engine.operation | enum | 예 | tire.tread 또는 tire.sidewall. |
analysis.engine.result_schema_version | string | 예 | analysis.result의 원천 결과 스키마 버전. |
analysis.engine.requested_functions | string[] | 예 | 분석 요청에 포함된 기능 이름. |
analysis.quality.recognized | boolean | 예 | 해당 슬롯의 핵심 결과를 판독했는지 여부. |
analysis.quality.confidence | number | null | 예 | 제공되는 경우의 신뢰도. 엔진이 제공하지 않으면 null. |
analysis.error.code | string | 예 | 파트너 분기 처리에 사용할 안정적인 공개 오류 코드. |
analysis.error.retryable | boolean | 예 | 같은 입력 또는 교체 입력으로 재시도 가능한 오류인지 여부. |
대기 슬롯은 provenance, engine, result, quality, error, completed_at이 모두
null입니다. 실패 슬롯은 result와 quality가 null이고 error가 채워집니다.
트레드 결과
| 필드 | 타입 | 필수 | 단위·설명 |
|---|---|---|---|
aggregated_depth | object | null | 예 | 종합 잔여 홈깊이 결과. |
aggregated_depth.aggregated_remaining_depth | number | null | 예 | mm. |
aggregated_depth.estimated_lifetime | number | null | 예 | 분석 엔진이 제공한 예상 수명 값. |
individual_depths.individual_remaining_depth | number[] | 예 | mm. 입력 이미지 좌표 순서의 홈별 깊이. |
tire_rotation | number | null | 예 | 입력 이미지를 시계 방향으로 돌려 표시할 각도. |
vehicle_side | enum | null | 예 | left, right, unknown. |
groove_masks[] | array | 예 | 홈별 정규화 폴리곤. |
groove_masks[].depth_mm | number | null | 예 | 같은 인덱스의 홈 깊이(mm). |
groove_masks[].score | number | 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.size | object | null | 예 | 세 정수 모두 인식된 경우의 규격. 부분 인식은 null. |
size.section_width | integer | null | 예 | 단면폭(mm). |
size.aspect_ratio | integer | null | 예 | 편평비(%). |
size.rim_diameter | integer | null | 예 | 림 지름(inch). |
사이드월 응답에는 원문 표기와 speed marker가 포함되지 않습니다. 현재는 speed marker를
안정적으로 분리하는 계약을 제공하지 않으므로 세 정수만 사용하세요. 콘텐츠의 표시 규격도
205/55 · 16인치처럼 세 정수만 조합하며 임의의 speed marker 문자를 만들지 않습니다.
링크와 시각
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
links.self | uri | 예 | 이 리포트의 GET URL. |
links.content | uri | 예 | 현재 콘텐츠 alias. |
links.share | uri | null | 예 | 현재 활성 공유 capability만 반환. 만료·회수·발급 관리는 /share에서 확인. |
timestamps.created_at | date-time | 예 | 리포트 생성 시각. |
timestamps.analysis_completed_at | date-time | null | 예 | 현재 분석 리비전 완료 시각. |
timestamps.published_at | date-time | null | 예 | 현재 공개 상태가 published일 때 공개 시각. |
timestamps.updated_at | date-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_version | string | 예 | 항상 report-content.v1. |
report_id | string(UUID) | 예 | 원본 리포트 ID. |
status | enum | 예 | pending, ready, failed. |
content_revision | string(UUID) | null | 예 | 준비된 불변 콘텐츠 ID. 대기·실패면 null. |
content_profile | object | 예 | 고객·로케일별 콘텐츠 계약. |
generator | object | 예 | 규칙·문구·렌더 투영 버전. |
source | object | 예 | 어떤 report 스키마와 analysis_revision에서 생성됐는지 표시. |
generated_at | date-time | null | 예 | 콘텐츠 기준 시각. 원천 분석 완료 시각이며, 없으면 리포트 생성 시각. |
report_context | object | 예 | 표시용 번호판·검사시각·템플릿 키. |
overall | object | null | 예 | 종합 문구. 준비 전에는 null. |
tires | array | 예 | T1~T4 타이어별 판정·문구. |
sections | array | 예 | 순서가 지정된 리포트 섹션. |
render_data | object | 예 | 오버레이와 규격 표시를 위한 구조화 데이터. |
error | object | null | 예 | 콘텐츠 생성 실패 정보. |
links | object | 예 | 현재 alias, canonical, 원본 report 링크. |
프로필과 생성기 버전
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
content_profile.key | string | 예 | 현재 speedmate-ko. |
content_profile.version | string | 예 | 현재 1.0. 리포트 생성 시 고정. |
content_profile.locale | string | 예 | 현재 ko-KR. |
generator.ruleset_version | string | 예 | 판정 규칙 버전. |
generator.copy_version | string | 예 | 문구 버전. |
generator.projection_version | string | 예 | 렌더 데이터 투영 버전. |
source.report_schema_version | string | 예 | 현재 report.v1. |
source.analysis_revision | string(UUID) | null | 예 | 콘텐츠가 참조한 객관 결과 리비전. |
표시 맥락·종합 결과·링크
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
report_context.plate_number | string | null | 예 | 표시용 차량번호. |
report_context.inspected_at | date-time | null | 예 | 표시할 검사 시각. 생성 정보가 없으면 null. |
report_context.template_key | string | 예 | 리포트에 고정된 이미지 슬롯 템플릿 키. |
overall.severity | enum | 예 | good, caution, critical, unknown. |
overall.severity_label | string | 예 | 종합 상태의 표시 라벨. |
overall.headline | string | 예 | 종합 제목 문구. |
overall.paragraphs | string[] | 예 | 종합 설명 문단. |
links.self | uri | 예 | 현재 alias URL. |
links.canonical | uri | null | 예 | 준비된 불변 콘텐츠 URL. 대기·실패 상태에서는 null. |
links.report | uri | 예 | 원본 report.v1 조회 URL. |
overall 객체 자체는 콘텐츠가 준비된 경우에만 존재하며 대기·실패 상태에서는 null입니다.
새로운 문구 로직이 출시돼도 기존 canonical 콘텐츠는 바뀌지 않습니다. 새 리포트에서 다른
프로필 버전을 선택할 수 있게 될 때는 POST /reports의 content_profile로 명시합니다.
현재 지원값은 { "key": "speedmate-ko", "version": "1.0", "locale": "ko-KR" }입니다.
화면 문구를 머신 조건으로 비교하지 말고 severity, section_id, metrics 같은 구조화 필드를
사용하세요. 외부 출력 문구·판정·렌더 투영이 달라지면 해당 버전을 올리고, 기존 프로필 구현과
canonical 결과는 그대로 유지합니다. 같은 copy_version의 출력은 수정하지 않습니다.
타이어별 콘텐츠
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
tires[].slot_id | string | 예 | 대응하는 트레드 슬롯 ID. |
tires[].tire_index | enum | 예 | T1=앞좌, T2=앞우, T3=뒤좌, T4=뒤우. |
tires[].position | enum | 예 | 타이어 위치 코드. |
tires[].position_label | string | 예 | 표시용 위치 라벨. |
tires[].minimum_remaining_depth_mm | number | null | 예 | 해당 타이어의 최소 잔여 홈깊이(mm). |
tires[].severity | enum | 예 | good, caution, critical, unknown. |
tires[].severity_label | string | 예 | 표시용 상태 라벨. |
tires[].decision_label | string | 예 | 권장 판단 라벨. |
tires[].wear_pattern | object | null | 예 | 편마모 코드·라벨·설명. 수동 리포트는 null. |
tires[].narrative | string | null | 예 | 타이어별 설명 문구. |
편마모 하위 필드
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
tires[].wear_pattern.code | enum | 예 | even_wear, center_wear_overinflation_candidate, both_shoulder_wear_underinflation_candidate, one_shoulder_wear_alignment_candidate, mixed_or_uncertain. |
tires[].wear_pattern.worn_shoulder | enum | null | 예 | 한쪽 가장자리 마모인 경우 left 또는 right; 그 외에는 null. |
tires[].wear_pattern.label | string | 예 | 표시용 유형 라벨. |
tires[].wear_pattern.description | string | 예 | 표시용 유형 설명. |
편마모 유형별 일러스트 묶음이 필요한 경우 API와 별도로 전달할 수 있습니다. 파트너는 전달받은
파일을 wear_pattern.code에 매핑해 자체 정적 리소스로 배포합니다.
섹션
모든 섹션은 section_id, order, title, severity, badge_label, paragraphs,
metrics를 가집니다. 화면 순서는 배열 순서가 아니라 order를 기준으로 정렬하세요.
| 공통 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
sections[].section_id | enum | 예 | 섹션 유형을 식별하는 안정적인 키. |
sections[].order | integer | 예 | 오름차순 렌더링 순서. |
sections[].title | string | 예 | 표시용 섹션 제목. |
sections[].severity | enum | 예 | good, caution, critical, unknown. |
sections[].badge_label | string | null | 예 | 표시용 배지 문구. 배지가 없으면 null. |
sections[].paragraphs | string[] | 예 | 표시용 설명 문단. |
sections[].metrics | object | 예 | section_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_pattern도 null입니다.
클라이언트는 섹션 개수를 고정하지 말고 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_m와
current_tire_distance_m를 사용하고, 차이는 distance_gap_m으로 표시합니다. 별도의 완성된
제동거리 이미지 리소스는 제공하지 않습니다.
트레드 오버레이 좌표
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
render_data.tread_overlays[] | array | 예 | 자산이 등록된 트레드 슬롯의 오버레이 데이터. |
render_data.tread_overlays[].slot_id | string | 예 | 대응하는 트레드 슬롯 ID. |
render_data.tread_overlays[].asset | object | 예 | report와 같은 자산 식별자·원본 출처. |
render_data.tread_overlays[].tire_rotation | number | null | 예 | 엔진이 반환한 시계 방향 회전값. |
render_data.tread_overlays[].vehicle_side | enum | null | 예 | left, right, unknown; 알 수 없으면 null. |
render_data.tread_overlays[].remaining_depths_mm | number[] | 예 | groove_masks와 같은 인덱스 순서. |
render_data.tread_overlays[].groove_masks | array | 예 | report 결과와 같은 입력 이미지 정규화 마스크. |
render_data.tread_overlays[].tread_roi | object | null | 예 | 트레드 영역. |
coordinate_system.space | string | 예 | input_image_normalized. |
coordinate_system.origin | string | 예 | top_left. |
coordinate_system.x_range, y_range | [0,1] | 예 | 좌표 범위. |
coordinate_system.rotation_degrees_clockwise | number | 예 | 표시 전에 적용할 시계 방향 회전. |
coordinate_system.mirror_x | boolean | 예 | 회전 후 좌우 반전 적용 여부. |
coordinate_system.image_orientation_normalized | boolean | 예 | 현재 항상 false; 원본 좌표임을 뜻함. |
coordinate_system.mask_depth_order | string | 예 | same_index; 마스크와 깊이의 인덱스가 대응함. |
권장 순서는 입력 이미지와 정규화 좌표로 오버레이 구성 → 시계 방향 회전 → 필요하면
좌우 반전입니다. source.url == null인 ATRACE 업로드 자산은 파트너 화면에서 원본 URL로
사용할 수 없으므로 오버레이 원본이 필요한 연동은 고객 URL 모드를 선택하세요.
사이드월 표시 투영
| 필드 | 타입 | 필수 | 설명 |
|---|---|---|---|
render_data.sidewall_specs[] | array | 예 | 자산이 등록된 사이드월 슬롯의 표시 투영. |
render_data.sidewall_specs[].slot_id | string | 예 | 대응하는 사이드월 슬롯 ID. |
render_data.sidewall_specs[].asset | object | 예 | report와 같은 자산 식별자·원본 출처. |
render_data.sidewall_specs[].size | object | null | 예 | 인식된 세 정수 규격. 판독하지 못하면 null. |
render_data.sidewall_specs[].size.section_width | integer | null | 예 | 단면폭(mm). |
render_data.sidewall_specs[].size.aspect_ratio | integer | null | 예 | 편평비(%). |
render_data.sidewall_specs[].size.rim_diameter | integer | null | 예 | 림 지름(inch). |
render_data.sidewall_specs[].recognized | boolean | 예 | 표시 가능한 규격을 판독했는지 여부. |
콘텐츠 응답 예시
{
"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"
}
}위 예시는 필드 설명을 위해 tires와 sections 배열을 일부만 표시했습니다. 실제 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.canonical은 null이고 배열은 빈 배열입니다.
캐시와 동시성
준비된 콘텐츠의 응답에는 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을 사용합니다.