POST/api/v1/hira-extract/extract

EDI 수량·금액 자동정리

EDI·처방전 사진을 올리면 약품별 수량·처방량·단가·금액을 표로 정리해 드립니다. 숫자를 하나하나 옮겨 적고 계산이 맞는지 검산하던 일을 대신하고, 다시 확인이 필요한 항목만 콕 집어 알려 줍니다.

무료 10500원 / 이미지OpenAPI 스펙(JSON)

바로 실행

이미지를 올려 바로 실행해 결과를 확인하세요. (비로그인은 하루 실행 횟수 제한)

POST/api/v1/hira-extract/extract

이미지를 자동으로 정렬·보정한 뒤 표를 읽어, 약품별 수량·일수·총처방량·단가·총금액을 추출합니다. 값은 이미지에서 읽어낸 원본이며, 계산·기준가 대조는 검증에만 씁니다. 약가코드가 비표준(대학병원 자체코드 등)이어도 약품명은 제공되고 라인별 needsReview로 확인 여부를 표시합니다.

엔드포인트

POST https://marketapi.nadoo.ai/api/v1/hira-extract/extract

인증

헤더타입필수설명
x-api-keystring필수대시보드 발급 API 키 (pk_live_…)
Content-Typestring필수application/json
Idempotency-Keystring선택재시도 이중 과금 방지 (권장: UUID). 재시도 시 같은 키 + 같은 본문이면 재처리 없이 최초 결과를 반환하고, 같은 키로 다른 본문을 보내면 422. 키를 안 보내면 매 요청이 별건 처리됨.

요청 본문 (JSON)

필드타입필수설명
imagestring택1base64 인코딩 이미지
imageUrlstring(uri)택1이미지 https URL (서버 다운로드)
templateIdstring선택특정 프롬프트 템플릿 버전으로 추출 (미지정 시 활성 최신본)

응답 200 OK

필드타입설명
requestIdstring요청 식별자
documentTypestringdrug_table=약품표. 아니면 business_registration/receipt/other 등 표 없음 사유
foundTableboolean약품 표 검출 여부
itemsobject[]약품 라인아이템 (아래 스키마)
items[].drugCodestring | null약가코드 — 보이는 그대로(9자리 아닐 수 있음)
items[].drugNamestring | null약품명 (코드 비표준이어도 제공)
items[].quantitynumber | null수량(처방횟수·환자수 포함)
items[].daysnumber | null일수(투약일수)
items[].prescribedQtynumber | null총처방량(총사용량/총투여량)
items[].unitPricenumber | null단가
items[].totalAmountnumber | null총금액
items[].codeInMasterboolean약가 마스터 조회 성공 여부
items[].suggestedDrugCodestring | null코드 미조회 시 약품명 매칭으로 추정한 약가코드(교정 제안). drugCode(OCR 원본)를 대체하지 않고 status도 올리지 않음. 오독·절단·원내코드 복구용
items[].priceCheckstring단가 검증 — current(현재가 일치)/historical(과거가·단가변동)/mismatch/none
items[].statusstringGREEN(정상)/YELLOW(확인 권장)/RED(오류·확인 필요)
items[].needsReviewboolean사람 확인 필요 여부
items[].reviewstring[]확인 사유
summaryobjectitems(행수)·needsReview(확인필요 수)·byStatus(green/yellow/red)·completeExtraction(합계 대조 전체추출 여부)
geometry.rotationnumber적용된 회전각(0/90/180/270), 반시계 방향 — 서비스 보정과 표 검출기 자체 보정을 합산한 값. 0=보정 없음. sourceoriented 를 재현하려면 반시계로 이 각도만큼 회전
geometry.source / geometry.orientedobject업로드 원본 / 회전 보정 후 크기 { width, height }
geometry.cropobject | null표 크롭 영역. 크롭본이 정본일 때만 채워지고, 크롭 실패·원본 재추출 시 null
geometry.crop.cornersobject[]회전 보정본 기준 꼭짓점 4개 { x, y } — 시계방향 좌상·우상·우하·좌하
geometry.crop.sourceCornersobject[]업로드 원본 기준 꼭짓점 4개(역회전 적용). 회전 없으면 corners와 동일
geometry.crop.box / sourceBoxobject같은 영역의 { x, y, width, height } 표현
geometry.crop.normalizedobject회전 보정본 기준 0~1 비율 좌표(해상도 무관)
geometry.crop.scorenumber | null표 검출 신뢰도
metaobject진단(참고) — imageReadable·imageIssues[]·rotationApplied·cropped·droppedSummaryRows·template. 외부 처리에 불필요하면 무시 가능
cost.krw / cost.freenumber / boolean과금액 / 무료 처리 여부
balanceKrwnumber처리 후 잔액

응답 예시

{
  "requestId": "3f9a1c2e-...",
  "documentType": "drug_table",
  "foundTable": true,
  "items": [
    { "drugCode": "658106350", "drugName": "OO정",
      "quantity": 83, "days": null, "prescribedQty": 2355,
      "unitPrice": 312, "totalAmount": 734760,
      "codeInMaster": true, "priceCheck": "current",
      "status": "GREEN", "needsReview": false, "review": [] }
  ],
  "summary": { "items": 4, "needsReview": 0,
    "byStatus": { "green": 4, "yellow": 0, "red": 0 },
    "completeExtraction": true },
  "geometry": {
    "rotation": 90,
    "source": { "width": 3024, "height": 4032 },
    "oriented": { "width": 4032, "height": 3024 },
    "crop": {
      "score": 0.93,
      "corners": [{"x":210,"y":340},{"x":3820,"y":340},{"x":3820,"y":2660},{"x":210,"y":2660}],
      "box": { "x": 210, "y": 340, "width": 3610, "height": 2320 },
      "sourceCorners": [{"x":340,"y":212},{"x":2660,"y":212},{"x":2660,"y":3822},{"x":340,"y":3822}],
      "sourceBox": { "x": 340, "y": 212, "width": 2320, "height": 3610 },
      "normalized": { "x": 0.052, "y": 0.112, "width": 0.895, "height": 0.767 }
    }
  },
  "meta": { "imageReadable": true, "imageIssues": [],
    "rotationApplied": 0, "cropped": true, "droppedSummaryRows": 1,
    "template": { "key": "edi-extract", "version": 3 } },
  "cost": { "krw": 500, "free": false },
  "balanceKrw": 49700
}

예시 (cURL)

curl -X POST https://marketapi.nadoo.ai/api/v1/hira-extract/extract \
  -H "x-api-key: pk_live_xxxxxxxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"imageUrl":"https://.../edi.jpg"}'

대용량 업로드 (presigned, 권장)

base64는 요청 크기 한계(본문 25MB·원본 ~18MB, 초과 시 413 payload_too_large)가 있어, 대용량·대량은 presigned 업로드가 안정적입니다(용량 무제한 — 이미지를 GCS로 직접 PUT). ① 업로드 URL 발급 → ② 이미지 PUT → ③ imageUrl로 추출.

# 1) 업로드 URL 발급
curl -X POST https://marketapi.nadoo.ai/api/v1/uploads \
  -H "x-api-key: pk_live_xxxxxxxx" -H "Content-Type: application/json" \
  -d '{"contentType":"image/jpeg"}'
# → { "uploadUrl": "https://storage.googleapis.com/...(PUT)", "imageUrl": "https://...(read)", "expiresIn": 3600 }

# 2) 이미지 업로드(PUT) — Content-Type 일치
curl -X PUT "<uploadUrl>" -H "Content-Type: image/jpeg" --data-binary @edi.jpg

# 3) 추출 — imageUrl 로 전달(base64 불필요)
curl -X POST https://marketapi.nadoo.ai/api/v1/hira-extract/extract -H "x-api-key: pk_live_xxxxxxxx" -H "Content-Type: application/json" \
  -d '{"imageUrl":"<imageUrl>"}'

대량 비동기 (수천 장)

POST/api/v1/hira-extract/extract-batch-async

이미지 배열을 접수하고 { jobId }를 즉시 반환합니다(백그라운드 처리). GET /api/v1/jobs/{jobId}로 진행률·신호등 집계·항목별 상태를 폴링합니다. 대량은 imageUrls 권장.

curl -X POST https://marketapi.nadoo.ai/api/v1/hira-extract/extract-batch-async \
  -H "x-api-key: pk_live_xxxxxxxx" -H "Content-Type: application/json" \
  -d '{"imageUrls":["https://.../a.jpg","https://.../b.jpg"], "templateId":"..."}'
# → { "jobId": "...", "status": "queued", "pollUrl": "/api/v1/jobs/..." }

폴링 · 결과 조회

GET /api/v1/jobs/{jobId} 는 기본적으로 경량 응답(항목별 itemCount·foundTable·byStatus·extractionId)을 반환합니다. 수천 장 배치에서 폴링마다 전체 items를 싣지 않기 위함입니다. 실제 약품 라인아이템은 아래 두 방법으로 가져옵니다.

방법설명
GET /api/v1/jobs/{jobId}?items=1폴링 응답의 각 항목에 items(단건 /extract와 동일 스키마)를 병합해 반환. 소·중량 배치에 편리.
GET /api/v1/extractions/{extractionId}항목별 extractionId개별 추출 상세를 단건 조회(items·summary). 대량 배치에서 필요한 항목만 골라 받을 때.
# 1) 진행률 폴링(경량)
curl https://marketapi.nadoo.ai/api/v1/jobs/<jobId> -H "x-api-key: pk_live_xxxxxxxx"
# → { status, done, total, ok, trafficLights,
#     results: [ { index, status, itemCount, foundTable, byStatus, extractionId } ] }

# 2) 폴링에 items 포함
curl "https://marketapi.nadoo.ai/api/v1/jobs/<jobId>?items=1" -H "x-api-key: pk_live_xxxxxxxx"
# → results[].items 에 약품 라인아이템(단건 /extract 와 동일 스키마) 포함

# 3) 개별 항목 상세(extractionId 로 온디맨드)
curl https://marketapi.nadoo.ai/api/v1/extractions/<extractionId> -H "x-api-key: pk_live_xxxxxxxx"
# → { extractionId, documentType, foundTable, items: [...], summary: {...} }

참고: 대량 추출은 비동기(extract-batch-async)만 제공합니다. 동기 extract-batch는 없습니다(단건 /extract를 병렬 호출하거나 비동기 배치를 사용하세요).

에러 응답

HTTPerror의미
401invalid_keyAPI 키 누락/무효
402insufficient_credit무료 소진 + 잔액 부족
400no_image / bad_json이미지 또는 JSON 본문 오류
413payload_too_large요청 본문 25MB 초과 → presigned 업로드 사용
502processor_error처리 실패(과금분 자동 환불)

시작하기 (키 발급)