이미지 수집

Pre-Signed 모드와 고객 URL 모드, 모듈 스코프 슬롯 키, 캡처 구성(템플릿)을 설명합니다.

분석에 쓰는 이미지 출처는 모드에 따라 다릅니다. 클라이언트는 어느 모드에서도 이미지 바이트를 ATRACE Report API 요청 본문으로 직접 보내지 않습니다.

두 가지 모드

모드 A — 고객 URL

자사 스토리지의 공개 이미지 URL을 줄 수 있을 때 사용합니다.

  • POST /reports의 images[].source.url에 URL을 넣습니다. 자체 자산 ID가 있으면 images[].source.client_asset_id도 함께 보낼 수 있습니다.
  • URL은 HTTPS 공개 URL이어야 하고, 사용자명·비밀번호를 포함할 수 없습니다. 리디렉션은 최대 3회까지 허용되며 매 대상 URL을 다시 검증합니다. 20MB 이하의 성공 이미지 응답이 15초 안에 반환되어야 합니다.
  • 조건을 만족하는 URL을 수락하면 해당 슬롯의 분석이 시작됩니다.
  • GET /reports/{id}는 제출한 URL 문자열과 client_asset_id를 asset.source에 그대로 반환하므로 파트너 화면에서도 같은 URL을 사용할 수 있습니다.

자체 리포트 화면에 원본 이미지를 표시하려면 이 모드를 권장합니다. URL은 리포트를 사용할 기간 동안 파트너 시스템에서 접근 가능하게 유지하세요.

모드 B — ATRACE 발급 업로드 URL

이미지를 호스팅할 곳이 없을 때 사용합니다.

  1. POST /reports를 images 없이 호출하면 upload_targets[]를 받습니다. 각 항목에는 업로드용 PUT URL과 그 원본을 식별하는 고유 UUID asset_id가 있습니다. 템플릿 촬영 구성에 포함된 슬롯 전체가 발급됩니다 — tire_4t_2s·tire_4t_4s는 타이어 4개 위치 × {tread, sidewall} = 8개, tire_4t_0s는 트레드 4개.
  2. 실제로 촬영한 슬롯의 upload_url에만 이미지를 PUT 합니다. 이미지 바이트는 ATRACE Report API 요청 본문을 거치지 않습니다.
  3. POST /reports/{id}/images로 실제 업로드한 asset_id와 해당 슬롯을 함께 등록하면 분석이 시작됩니다. 이미 성공한 슬롯에 새 원본을 등록하면 409(slot_already_succeeded)가 반환됩니다.
{
  "images": [
    {
      "asset_id": "1d2f4836-12f8-4bde-9e51-1aac3d848a50",
      "module_type": "tire",
      "slot": { "position": "front_left", "image_type": "tread" }
    }
  ]
}

v1.1 breaking hard cut

POST /reports/{id}/images에서 슬롯만 보내던 이전 요청 형태는 더 이상 지원하지 않습니다. 반드시 서버가 발급한 asset_id와 그 타깃의 슬롯을 함께 보내세요.

사이드월 위치는 고정이 아닙니다. 현장 요원이 공간 제약으로 특정 방향만 촬영할 수 있어, 사이드월 2장이 (앞좌 + 뒤우) 등 어떤 조합으로든 올 수 있습니다. 그래서 사이드월이 있는 템플릿은 8개 슬롯을 모두 발급하고 파트너 앱은 실제 촬영한 슬롯에만 업로드·등록합니다. 사이드월의 좌·우를 알 수 없으면 좌·우 중 한쪽을 임의로 선택해 업로드해도 됩니다. 구성에 없는 슬롯(예: tire_4t_0s 리포트의 사이드월)은 upload-targets·images·analyze 어디서 보내도 422 validation_error로 거절되며 param이 해당 항목을 가리킵니다.

Pre-Signed 업로드 규약

upload_url은 ATRACE가 발급한 서명 업로드 URL입니다.

  • 메서드: HTTP PUT — 원본 이미지 바이트를 본문에 그대로 실어 보냅니다.
  • Content-Type: image/jpeg 또는 image/png.
  • Cache-Control: 응답의 required_headers가 안내하는 max-age=60을 그대로 보내시면 됩니다. 더 엄격한 값도 허용됩니다(아래 표).
  • 성공 응답: 200.
  • 만료: 발급 후 2시간(7200초).
허용되는 Cache-Control 값

판정 기준은 "재검증 없이 재사용해도 되는 시간이 60초 이하인가" 하나입니다. required_headers가 안내하는 max-age=60이 기본값이고, 그보다 엄격한 값도 그대로 통과합니다.

값결과비고
max-age=60✅ 허용required_headers 안내값
max-age=0 ~ max-age=59✅ 허용60초 이하
no-cache✅ 허용재사용 전 항상 재검증 = 실효 0초
no-store✅ 허용저장 자체를 금지 = 실효 0초
public, max-age=60✅ 허용다른 지시자와 함께 써도 됩니다
s-maxage=60✅ 허용
60✅ 허용숫자만 보내는 형태
max-age=3600❌ 거절60초 초과
public (TTL 없음)❌ 거절TTL을 판정할 수 없음
헤더 누락❌ 거절스토리지 기본값이 60초를 초과합니다

거절되면 어떤 응답이 오나요

TTL이 60초를 넘거나 값을 판정할 수 없으면 원본 등록 단계(POST /reports/{id}/images)에서 422 validation_error(param: "asset_id", retryable: false)로 거절됩니다. 업로드(PUT) 자체는 200으로 성공하므로, 실패는 등록 응답에서 확인하시면 됩니다. 이 경우 같은 asset_id에 다시 올리지 마시고 새 타깃을 발급받아 주세요.

만료·재촬영·교체

업로드 URL이 만료됐거나 재촬영해야 하면 기존 URL이나 asset_id를 재사용하지 않습니다.

  1. POST /reports/{id}/upload-targets에 필요한 slots를 보내 새 타깃을 발급받습니다.
  2. 새 upload_url에 이미지를 PUT 합니다.
  3. 새 asset_id와 슬롯을 POST /reports/{id}/images?replace=true에 등록합니다.
{
  "slots": [
    {
      "module_type": "tire",
      "slot": { "position": "front_left", "image_type": "tread" }
    }
  ]
}

현재 슬롯에 이미 적용된 **같은 asset_id**로 /images 등록을 재시도하는 것은 멱등입니다. 반면 재촬영은 항상 새 타깃을 발급받아야 합니다. 교체 또는 재분석 중에는 기존 공개 공유 링크가 일시적으로 열리지 않고, 새 분석이 성공하면 자동으로 다시 공개됩니다.

ATRACE 발급 URL로 올린 자산은 GET /reports/{id}에서 다음처럼 표시됩니다.

{
  "asset_id": "1d2f4836-12f8-4bde-9e51-1aac3d848a50",
  "source": {
    "kind": "atrace_upload",
    "url": null,
    "client_asset_id": null
  }
}

이 모드의 업로드 URL은 업로드 작업을 위한 단기 URL이며 리포트 표시용 원본 URL 계약이 아닙니다. asset_id로 URL을 조합하지 마세요. 자체 렌더링 화면에서 원본 이미지가 필요하다면 고객 URL 모드를 사용하세요.

클라이언트는 이미지 바이트를 API 요청 본문으로 직접 보내지 않습니다

/images 엔드포인트는 참조(asset_id·슬롯)만 받습니다. Pre-Signed 모드의 클라이언트는 원본 바이트를 업로드 타깃 URL로 직접 PUT 합니다.

이미지 요구사항

  • 포맷: PNG 또는 JPEG.
  • 해상도: 정식 분석 이미지는 긴 변 1920px를 권장합니다. 더 큰 원본은 이 크기로 줄여 보내기를 권장하며, 그대로 보내면 전송량과 지연이 늘어날 수 있습니다.
  • JPEG 압축 품질: 트레드 0.90, 사이드월 0.95를 권장합니다. precheck와 저속 망용 값은 이미지 품질을 참고하세요.
  • 회전: 클라이언트가 EXIF 회전을 보정할 필요가 없습니다. AI가 시각적으로 회전을 판단하고, 리포트 시각화 시 이미지를 바로 세웁니다. HEIC/EXIF 정규화도 불필요합니다. AI Engine API를 직접 호출해 자체 화면에 그릴 때는 응답의 tire_rotation으로 호출자가 세웁니다(트레드 그루브 오버레이).

모듈 스코프 슬롯 키

이미지는 { module_type, slot }로 식별합니다. slot의 형태는 모듈마다 다릅니다.

{
  "module_type": "tire",
  "slot": { "position": "front_left", "image_type": "tread" }
}
module_typeslot 형태
tire{ position: front_left | front_right | rear_left | rear_right, image_type: tread | sidewall }
dashboard{} 또는 { kind } (단일)
plate{} (단일)
exterior{ panel: ... }

현재는 tire 모듈만 지원합니다. 계기판(dashboard)·번호판(plate)·외장(exterior)은 추후 확장 예정이며, 위 표는 참고용입니다. position은 타이어 전용이며 slot 안에 들어갑니다. 새 모듈이 추가돼도 기존 계약은 깨지지 않습니다.

캡처 구성은 템플릿이 정한다

리포트가 어떤 이미지를 몇 장 요구하는지는 템플릿이 정의합니다(고정 8장이 아닙니다).

템플릿구성upload_targets / slots[]/content 섹션
tire_4t_2s트레드 4장 + 사이드월 2장 = 6장8개5개
tire_4t_4s트레드 4장 + 사이드월 4장 = 8장8개5개
tire_4t_0s트레드 4장, 사이드월 없음 (v1.3)트레드 4개4개 (sidewall_spec 없음)

template 필드를 생략하면 기본 템플릿 tire_4t_2s가 적용됩니다. 성공 조건은 GET /reports/{id} 응답의 template.requirements[]에 생성 당시 버전과 함께 고정됩니다. 예를 들어 tire_4t_2s의 사이드월은 네 위치 중 특정 두 곳이 아니라 아무 두 슬롯의 성공이 조건입니다.

촬영 구성은 리포트를 만들 때 정해지고 바뀌지 않습니다. tire_4t_0s 리포트는 requirements[]에 트레드 항목 하나만 있고, 사이드월 슬롯은 어느 진입점에서도 422 validation_error입니다. 사이드월을 제외하면 리포트에서 타이어 규격 표기와 앞뒤 규격 일치 확인이 빠지며(공유 링크 페이지 포함), 트레드 마모·제동거리· 편마모·위치별 편차·종합 소견은 그대로입니다. 템플릿은 리포트마다 지정하므로 같은 API 키로 매장에 따라 다른 템플릿을 보낼 수 있습니다.

다음 단계

On this page