# 한국형 OCR API 한국어 사업 문서·계약서·인쇄물·영수증의 텍스트를 추출하는 API. - **모델 ID**: `ocr` - **Base URL**: `https://api.corepin.ai` ## 1. 엔드포인트 | Method | Path | 인증 | 단가 | 설명 | |---|---|:-:|---:|---| | POST | `/v1/ocr` | ✓ | 2원 / 페이지 | 이미지 1장 → 즉시 응답 | | POST | `/v1/ocr/batch` | ✓ | 1원 / 페이지 | 여러 이미지 동기 일괄 (최대 20장) | | POST | `/v1/ocr/bulk` | ✓ | 0.5원 / 페이지 | 대량 비동기 작업 (최대 250장 · job_id 발급) | | POST | `/v1/ocr/bulk/init` | ✓ | — | 대용량 path — 업로드용 PUT URL 발급 (≤1,000장) | | POST | `/v1/ocr/bulk/upload` | ✓ | 0.5원 / 페이지 | 대용량 path — 업로드 완료 후 잡 제출 | | GET | `/v1/ocr/bulk/{job_id}` | ✓ | — | bulk 작업 상태/결과 조회 | | GET | `/v1/ocr/bulk` | ✓ | — | 내 bulk 작업 목록 (최근 50개) | | DELETE | `/v1/ocr/bulk/{job_id}` | ✓ | — | 대기 중인 bulk 작업 취소 | 응답 시간 기준: 즉시 (1–3초) · 일괄 (1–10분) · 대량 (최대 24시간). ## 2. POST `/v1/ocr` 요청은 `multipart/form-data`입니다. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `image` | binary | (필수) | 이미지 파일. `png` / `jpg` / `webp`, 최대 10MB. | | `format` | string | `text` | 응답 형식. `text` / `markdown` / `json` 중 선택. | | `max_tokens` | int | `2048` | 응답 토큰 상한 (1 ~ 4096). | **Response 필드**: | 필드 | 타입 | 설명 | |---|---|---| | `text` | string | 추출 텍스트 (줄바꿈 보강된 본문). | | `markdown` | string | `format=markdown`일 때만 — 헤더·구분자 처리된 마크다운. | | `structured` | object | `format=json`일 때만 — `lines` 배열 + 영수증인 경우 `receipt` 구조. | | `meta.model_id` | string | `ocr` | | `meta.model_version` | string | 모델 버전 (예: `ocr-2026.05`) | | `meta.processing_time_ms` | float | 서버 처리 시간 (ms) | | `meta.request_id` | string | 요청 추적 ID | | `meta.quota_remaining` | int | 잔여 호출 수 (후불은 `null`) | **예시**: ```bash curl -X POST https://api.corepin.ai/v1/ocr \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "image=@receipt.png" \ -F "format=text" ``` ```json { "text": "스타벅스 코리아 강남역 신논현점\nTEL 02-555-0100\n주문번호 A-2741\n2026-05-14 14:32\n아메리카노 (Tall) x2 9,000\n...", "meta": { "model_id": "ocr", "model_version": "ocr-2026.05", "processing_time_ms": 612.4, "request_id": "4c74bd30c53e497ca8a71f05aead6012", "quota_remaining": 99988 } } ``` `format=json` 응답 예: ```json { "structured": { "lines": ["스타벅스 코리아 강남역 신논현점", "TEL 02-555-0100", "..."], "receipt": { "header": ["스타벅스 코리아", "강남역 신논현점"], "items": [ {"name": "아메리카노 (Tall)", "qty": 2, "price": "9,000"} ], "totals": [ {"label": "합계", "amount": "31,200원"} ], "footer": ["감사합니다 :)"] } }, "meta": { "..." } } ``` ## 3. POST `/v1/ocr/batch` 여러 이미지를 한 번에 처리합니다. 요청은 `multipart/form-data`, `image` 필드를 여러 번 첨부하세요. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `image` | binary (반복) | (필수) | 이미지 파일 1~20장. 각 최대 10MB. | | `format` | string | `text` | 응답 형식. `text` / `markdown` / `json`. 모든 페이지에 동일 적용. | | `max_tokens` | int | `2048` | 장당 최대 토큰. | **Response**: ```json { "results": [ { "filename": "p1.png", "text": "..." }, { "filename": "p2.png", "text": "..." } ], "meta": { "model_id": "ocr", "model_version": "ocr-2026.05", "processing_time_ms": 2840.5, "request_id": "...", "page_count": 2, "unit_price_krw": 1, "quota_remaining": 998 } } ``` 페이지 단위 실패 시 그 페이지만 `{"filename": "...", "error": {...}}`로 표시되고, 나머지는 정상 결과를 받습니다. **예시**: ```bash curl -X POST https://api.corepin.ai/v1/ocr/batch \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "image=@page1.png" -F "image=@page2.png" -F "image=@page3.png" \ -F "format=markdown" ``` ## 4. POST `/v1/ocr/bulk` — 대량 비동기 대량 작업을 큐에 넣고 즉시 `job_id`를 받아요. 실제 처리는 백그라운드 작업에서 진행되고, 결과는 GET으로 폴링해서 받으세요. 페이지당 0.5원 (단건 대비 75% 할인). 폴링 권장 5초, 점진 증가 최대 60초. **Request 필드** (multipart): | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `image` | binary (반복) | (필수) | 이미지 1~250장. 각 최대 10MB. | | `format` | string | `text` | `text` / `markdown` / `json`. | | `max_tokens` | int | `2048` | 장당 최대 토큰. | **Response** (202 Accepted): ```json { "job_id": "a1b2c3...", "status": "queued", "page_count": 80, "status_url": "/v1/ocr/bulk/a1b2c3...", "meta": { "model_id": "ocr", "unit_price_krw": "0.5", "request_id": "..." } } ``` **GET `/v1/ocr/bulk/{job_id}` 응답**: ```json { "job_id": "a1b2c3...", "status": "done", "page_count": 80, "completed_pages": 80, "format": "text", "submitted_at": "2026-05-16T11:00:00Z", "started_at": "2026-05-16T11:00:03Z", "finished_at": "2026-05-16T11:08:21Z", "amount_krw": 40, "results": [ { "text": "..." }, ... ] } ``` `status` 값: `queued` / `processing` / `done` / `failed` / `cancelled`. 완료된 잡은 24시간 동안 보관돼요. **취소** — `DELETE /v1/ocr/bulk/{job_id}`로 아직 시작 안 한 (status=queued) 잡만 취소할 수 있어요. processing 중인 잡은 끝까지 처리돼요. ```bash # 제출 curl -X POST https://api.corepin.ai/v1/ocr/bulk \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -F "image=@page1.png" -F "image=@page2.png" -F "image=@page3.png" \ -F "format=text" # 상태 폴링 curl https://api.corepin.ai/v1/ocr/bulk/$JOB_ID \ -H "Authorization: Bearer $COREPIN_API_KEY" # 내 잡 목록 curl https://api.corepin.ai/v1/ocr/bulk \ -H "Authorization: Bearer $COREPIN_API_KEY" # 취소 (queued만) curl -X DELETE https://api.corepin.ai/v1/ocr/bulk/$JOB_ID \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` ### 4.1 대용량 path — `/v1/ocr/bulk/init` + `/v1/ocr/bulk/upload` (≤1,000장) 기본 path (위) 한도는 250장이지만, 직접 업로드 path는 한 잡당 **1,000장**까지 가능해요. 동작 순서는: 1. `POST /v1/ocr/bulk/init`으로 업로드용 PUT URL N개 받음 2. 클라이언트가 각 URL에 HTTP PUT으로 이미지를 직접 업로드 3. `POST /v1/ocr/bulk/upload`로 `key` list와 옵션 제출 → `job_id` 4. 이후 GET / DELETE는 기본 path와 같은 엔드포인트 사용 (`/v1/ocr/bulk/{job_id}`) ```bash # 1. init — 3장 업로드용 PUT URL 발급 curl -s -X POST https://api.corepin.ai/v1/ocr/bulk/init \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"count": 3, "content_types": ["image/png","image/png","image/png"]}' # → {"upload_id":"...","uploads":[{"key":"...","put_url":"https://...","expires_in":3600}, ...]} # 2. 각 이미지를 PUT URL로 직접 업로드 curl -X PUT "$PUT_URL" -H "Content-Type: image/png" --data-binary @page1.png # 3. 잡 제출 curl -X POST https://api.corepin.ai/v1/ocr/bulk/upload \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"items":[{"key":"...","filename":"page1.png","content_type":"image/png"}, ...],"format":"text"}' ``` 단가·동시 부하 제한·취소 동작은 기본 path와 완전히 동일. 차이는 한도 (대용량 path가 더 큼)와 클라이언트가 직접 업로드 (서버 메모리 부담 적음). ## 5. 오류 응답 | HTTP | code | 의미 | |---|---|---| | 400 | `empty_image` | 업로드된 이미지가 비어 있음 | | 400 | `invalid_format` | `format` 값이 text/markdown/json이 아님 | | 400 | `invalid_max_tokens` | `max_tokens`가 1~4096 범위 밖 | | 429 | `quota_active_jobs` | 같은 API 키의 동시 진행 bulk 잡 한도 초과 (default 3). 기존 잡이 done/cancelled가 된 뒤 재제출. `Retry-After: 60` 헤더 포함. | | 503 | `queue_full` | 전체 bulk 큐가 가득 찼어요 (default 20). 잠시 후 재제출. `Retry-After: 120` 헤더 포함. | | 401 | `missing_api_key` / `invalid_api_key` | 인증 실패 | | 413 | `image_too_large` | 10MB 초과 | | 429 | `rate_limited` / `concurrency_limit` | 속도 한도 초과 | | 502 | `upstream_error` | OCR 처리 오류 | | 504 | `upstream_timeout` | 처리 시간 초과 | 공통 오류 응답·재시도 안내는 [빠른 시작 §6](/docs/quickstart) 참고. ## 6. 코드 예제 ### Python ```python import requests with open("receipt.png", "rb") as f: r = requests.post( "https://api.corepin.ai/v1/ocr", headers={"Authorization": f"Bearer {YOUR_KEY}"}, files={"image": f}, data={"format": "json"}, timeout=60, ) r.raise_for_status() print(r.json()["structured"]) ``` ### Node.js ```javascript import fs from "fs"; import FormData from "form-data"; const form = new FormData(); form.append("image", fs.createReadStream("receipt.png")); form.append("format", "markdown"); const r = await fetch("https://api.corepin.ai/v1/ocr", { method: "POST", headers: { Authorization: `Bearer ${process.env.COREPIN_API_KEY}`, ...form.getHeaders() }, body: form, }); const out = await r.json(); console.log(out.markdown); ```