퀵스타트 — 예제 리포트 만들기

미리 준비된 샘플 이미지로 항상 성공하는 예제 리포트를 만들고, 공유 리포트까지 바로 확인합니다.

이 페이지의 호출은 전부 복사해서 그대로 실행할 수 있습니다. 발급받은 테스트 키만 넣으면, 미리 준비된 분석 가능한 샘플 이미지로 예제 리포트를 만들고 — 상태 확인 → 공유 리포트 열람까지 — 한 번에 따라가 볼 수 있습니다.

처음이라면 인증·호스트·모드 개념을 시작하기에서 먼저 보고 오면 좋습니다.

준비물

  • 발급받은 테스트 키 (atr_test_…). 아직 없다면 콘솔에서 프로젝트(test 환경)를 만들고 API 키를 발급하세요 — 전체 키 값은 발급 시 한 번만 표시됩니다. 자세한 절차는 시작하기를 참고하세요.
  • curl, 그리고 JSON 파싱을 위한 jq.
export ATRACE_API_KEY=atr_test_xxxxxxxxxxxxxxxxxxxx

이 예제가 항상 성공하는 이유

아래 이미지 URL은 ATRACE가 호스팅하는 분석 가능한 실차 샘플입니다. 촬영 품질·각도 문제로 분석이 실패할 일이 없으므로, 키만 올바르면 리포트가 끝까지(분석 → 자동 공개) 완료됩니다. 실제 연동에서 쓰는 계약(요청·응답 형태)과 100% 동일하니, 여기서 동작을 확인한 뒤 이미지 URL만 자사 것으로 바꾸면 됩니다.

준비된 샘플 이미지

타이어 4개 위치 × {tread, sidewall} 슬롯에 매핑된 공개 샘플입니다. 트레드 4장은 마모(그루브 깊이)가 서로 다른 실차 샘플이라, 리포트에 위치별로 다른 트레드 깊이가 나타납니다.

슬롯샘플 URL비고
front_left · treadhttps://docs.atrace.ai/samples/tire/tread-a-8mm.jpg트레드 약 8mm
front_right · treadhttps://docs.atrace.ai/samples/tire/tread-a-6mm.jpg트레드 약 6mm
rear_left · treadhttps://docs.atrace.ai/samples/tire/tread-b-4mm.jpg트레드 약 4mm
rear_right · treadhttps://docs.atrace.ai/samples/tire/tread-c-2mm.jpg트레드 약 2mm
front_left · sidewallhttps://docs.atrace.ai/samples/tire/sidewall-205-55R16.jpg규격 205/55R16
rear_right · sidewallhttps://docs.atrace.ai/samples/tire/sidewall-205-65R15.jpg규격 205/65R15
front_right · sidewallhttps://docs.atrace.ai/samples/tire/sidewall-165-60R15.jpgtire_4t_4s에서만 사용
rear_left · sidewallhttps://docs.atrace.ai/samples/tire/sidewall-185-65R14.jpgtire_4t_4s에서만 사용

사이드월 위치는 고정이 아닙니다

위 예시는 사이드월을 앞좌 + 뒤우 조합으로 보냅니다. 현장에서는 공간 제약으로 어느 바퀴를 찍게 될지 달라질 수 있고, 좌·우를 구분할 수 없으면 한쪽을 임의로 골라 보내도 됩니다. 자세한 배경은 이미지 수집을 보세요.

번호판 이미지(plate 모듈)는 아직 지원되지 않습니다. 다만 아래 예제는 plate_number(차량 번호)에 무작위 예시 번호를 만들어 함께 보내, 생성된 샘플 리포트에 차량 번호가 표시되도록 합니다 — plate_number선택 필드이므로 생략해도 됩니다.

방법 1 — 고객 URL 모드 (가장 빠름, 한 번의 호출)

이미지 URL을 요청에 동봉하면 호출 한 번으로 분석이 시작됩니다. template촬영 구성을 정하는 템플릿입니다 — 6장짜리 tire_4t_2s와 8장짜리 tire_4t_4s 중 고릅니다.

트레드 4장 + 사이드월 2장 = 6장.

# 무작위 예시 번호판 (선택 필드 plate_number). 직접 지정하거나 생략해도 됩니다.
PLATE="$((RANDOM%90+10))가$((RANDOM%9000+1000))"

curl -X POST https://app.atrace.ai/api/v1/reports \
  -H "Authorization: Bearer $ATRACE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-4t2s-001" \
  -d '{
    "plate_number": "'"$PLATE"'",
    "external_inspection_id": "quickstart-4t2s-001",
    "template": "tire_4t_2s",
    "images": [
      { "module_type": "tire", "slot": { "position": "front_left",  "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-a-8mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "front_right", "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-a-6mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_left",   "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-b-4mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_right",  "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-c-2mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "front_left",  "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-205-55R16.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_right",  "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-205-65R15.jpg" } }
    ]
  }'

트레드 4장 + 사이드월 4장 = 8장. 위 6장에 사이드월 2장(앞우 + 뒤좌)을 더합니다.

# 무작위 예시 번호판 (선택 필드 plate_number). 직접 지정하거나 생략해도 됩니다.
PLATE="$((RANDOM%90+10))가$((RANDOM%9000+1000))"

curl -X POST https://app.atrace.ai/api/v1/reports \
  -H "Authorization: Bearer $ATRACE_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: quickstart-4t4s-001" \
  -d '{
    "plate_number": "'"$PLATE"'",
    "external_inspection_id": "quickstart-4t4s-001",
    "template": "tire_4t_4s",
    "images": [
      { "module_type": "tire", "slot": { "position": "front_left",  "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-a-8mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "front_right", "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-a-6mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_left",   "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-b-4mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_right",  "image_type": "tread" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/tread-c-2mm.jpg" } },
      { "module_type": "tire", "slot": { "position": "front_left",  "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-205-55R16.jpg" } },
      { "module_type": "tire", "slot": { "position": "front_right", "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-165-60R15.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_left",   "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-185-65R14.jpg" } },
      { "module_type": "tire", "slot": { "position": "rear_right",  "image_type": "sidewall" },
        "source": { "url": "https://docs.atrace.ai/samples/tire/sidewall-205-65R15.jpg" } }
    ]
  }'

응답(202)에는 report_id이미 사용 가능한 share_url이 들어 있습니다.

{
  "report_id": "rpt_01HXEXAMPLE",
  "status": "processing",
  "share_url": "https://app.atrace.ai/r/sh_abcdef"
}

완료 확인 (폴링)

share_url은 생성 즉시 받지만, 분석·공개가 끝나야 열람 가능해집니다. GET /reports/{id}를 폴링해 statuspublished가 되면 완료입니다.

REPORT_ID=rpt_01HXEXAMPLE   # 위 응답의 report_id로 교체

for i in $(seq 1 60); do     # 최대 약 5분 (5초 × 60)
  REP="$(curl -s "https://app.atrace.ai/api/v1/reports/$REPORT_ID" \
    -H "Authorization: Bearer $ATRACE_API_KEY")"
  STATUS="$(echo "$REP" | jq -r '.status')"
  SUMMARY="$(echo "$REP" | jq -r '.summary_status // "-"')"
  echo "[$i] status=$STATUS summary_status=$SUMMARY"
  # published = 자동 공개 완료(열람 가능). partial/failed = 자동 흐름 종료(수동 검토 필요).
  case "$STATUS" in published|partial|failed) break ;; esac
  sleep 5
done

if [ "$STATUS" = "published" ]; then
  echo "완료! 공유 리포트: $(echo "$REP" | jq -r '.share_url')"
else
  echo "자동 공개되지 않음 (status=$STATUS). partial/failed는 수동 공개(POST /publish)가 필요합니다."
fi
  • 종료 조건은 status == "published"입니다 — 자동 공개가 끝나 share_url을 열람할 수 있고, 필수 슬롯이 모두 성공했으면 summary_statuscomplete입니다. 열람 링크는 (재구성하지 말고) 응답의 share_url 값을 그대로 쓰세요.
  • 이 퀵스타트의 큐레이션 샘플은 항상 모든 필수 슬롯이 성공하므로 곧바로 published에 도달합니다.
  • 자사 이미지로 바꾼 뒤 일부 필수 슬롯이 시간 내 끝나지 않으면 statuspartial(또는 failed)이 됩니다. partial자동 공개되지 않으며, 검토 후 POST /reports/{id}/publish로 수동 공개해야 열람할 수 있습니다.
  • 429·5xx에는 지수 백오프로 재시도하세요. 자세한 상태 전이는 리포트 생성 흐름을 보세요.

방법 2 — Pre-Signed 모드 (자체 스토리지 없이, bash 스크립트)

자사 이미지 호스팅이 없다면 ATRACE 스토리지에 직접 PUT으로 업로드합니다. 서명 URL에 PUT 하는 흐름이 처음이면 헷갈리기 쉬우므로, 아래 스크립트가 전 과정을 대신 처리합니다 — 샘플을 내려받아 업로드하고, 슬롯을 등록한 뒤, 완료까지 폴링합니다.

# 스크립트 내려받기
curl -O https://docs.atrace.ai/scripts/atrace-quickstart.sh
chmod +x atrace-quickstart.sh

# 실행 (키만 있으면 됩니다)
export ATRACE_API_KEY=atr_test_xxxxxxxxxxxxxxxxxxxx
./atrace-quickstart.sh                       # tire_4t_2s (6장)
TEMPLATE=tire_4t_4s ./atrace-quickstart.sh   # tire_4t_4s (8장)

스크립트가 하는 일은 다음과 같습니다.

리포트 생성images 없이 POST /reports를 호출하면, 타이어 8개 슬롯 전체의 upload_targets(스토리지 PUT URL)를 받습니다. 스크립트는 무작위 예시 번호판(plate_number)도 함께 보내 완성된 샘플 리포트에 차량 번호가 표시되도록 합니다(선택 필드).

# 무작위 예시 번호판 (선택 필드 plate_number).
PLATE="$((RANDOM%90+10))가$((RANDOM%9000+1000))"

curl -X POST https://app.atrace.ai/api/v1/reports \
  -H "Authorization: Bearer $ATRACE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "plate_number": "'"$PLATE"'", "external_inspection_id": "quickstart-presigned-001", "template": "tire_4t_2s" }'

샘플 다운로드 + PUT 업로드 — 각 슬롯의 upload_url에 이미지 바이트를 그대로 PUT 합니다. 업로드는 스토리지로 바로 가고, ATRACE Report API를 거치지 않습니다.

curl -X PUT "<upload_url>" \
  -H "Content-Type: image/jpeg" \
  --data-binary @tread-a-8mm.jpg
# → HTTP 200

슬롯 등록 (= 분석 자동 시작) — 실제로 업로드한 슬롯만 등록합니다. 슬롯은 중첩 형태 (slot: { position, image_type })로 보냅니다.

curl -X POST https://app.atrace.ai/api/v1/reports/$REPORT_ID/images \
  -H "Authorization: Bearer $ATRACE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "images": [
    { "module_type": "tire", "slot": { "position": "front_left", "image_type": "tread" } }
  ] }'

완료 폴링 + 공유 리포트 열람 — 방법 1과 동일하게 status=published까지 폴링한 뒤 share_url을 엽니다.

Pre-Signed PUT 규약 (이대로 보내면 됩니다)

  • 메서드: HTTP PUT.
  • 본문: 원본 이미지 바이트 그대로(--data-binary). multipart·base64 아님.
  • Content-Type: image/jpeg 또는 image/png.
  • 성공 응답: 200.
  • 만료: 발급 후 12시간. 그 안에 업로드를 마치면 됩니다.

결과 확인

공유 리포트(share_url)를 브라우저에서 열면, 위치별(T1~T4) 타이어 카드가 보입니다. 트레드는 측정된 그루브 깊이(mm), 사이드월은 인식된 규격이 표시됩니다. 이 예제는 마모 정도가 다른 트레드를 일부러 골랐으므로 위치마다 다른 깊이가 나타납니다.

위치라벨트레드 그루브 깊이
앞좌T1약 8mm
앞우T2약 6mm
뒤좌T3약 4mm
뒤우T4약 2mm

이제 이미지 URL만 자사 것으로 바꾸면 실제 연동 코드가 됩니다.

다음 단계

On this page