# 한국형 AI 웹 크롤러 API 챗봇·RAG·에이전트에 웹사이트를 읽힐 때, 광고·메뉴·깨진 글자로 가득한 원본 HTML 대신 **LLM이 바로 이해하는 깨끗한 마크다운/JSON**으로 돌려드려요. 한국 웹은 인코딩·구조가 제각각이라 일반 크롤러는 깨지기 쉽지만, 코어핀은 정확히 추출하고 깨진 글자를 자동 복원해요. 출력은 `output_format`(`text`/`markdown`/`html`/`json`)으로 골라 받아요 — RAG 적재엔 `json`(blocks IR), 프롬프트엔 `markdown`. 첨부(`.hwp`·`.pdf` 등)·개인정보 마스킹·기밀 등급 검사도 같은 호출에 묶을 수 있어요(아래 옵션 참고). - **모델 ID**: `crawl` - **Base URL**: `https://api.corepin.ai` - **버전**: `crawl-2026.06` ## 1. 엔드포인트 | Method | Path | 인증 | 단가 | 설명 | |---|---|:-:|---:|---| | POST | `/v1/crawl/scrape` | ✓ | 2원 / 페이지 | 웹 페이지 → 본문 + (옵션) HWP/PDF 첨부 자동 파싱 (여러 URL 일괄, 최대 20개) | | POST | `/v1/crawl/map` | ✓ | 2원 / 사이트 | 사이트에 어떤 페이지들이 있는지 주소 목록을 먼저 훑어보기 (풀크롤 전 미리보기 · sitemap + 1-hop 링크) | | POST | `/v1/crawl/crawl` | ✓ | 2원 / 페이지 | **사이트 통째로** 비동기 크롤 잡 등록 → `job_id` (RAG 적재용 · depth/limit/robots/중복제거 · 링크 따라가기) | | GET | `/v1/crawl/crawl/{job_id}` | ✓ | — | 크롤 잡 상태·결과 폴링 | | GET | `/v1/crawl/crawl` | ✓ | — | 내 크롤 잡 목록 (최근 50개) | | DELETE | `/v1/crawl/crawl/{job_id}` | ✓ | — | 크롤 잡 취소 (이미 긁은 페이지만 청구) | | GET | `/v1/crawl/formats` | ✓ | — | 기능·옵션·첨부 지원 형식·제약 | | GET | `/v1/crawl/version` | ✓ | — | 모델 버전·기능 | `scrape`(단건/소수 URL 즉시) vs `crawl`(사이트 통째로 비동기 잡): 손에 쥔 **특정 URL 몇 개**면 `scrape`, **사이트 전체를 RAG에 적재**하려면 시작 URL 하나로 링크를 따라가는 `crawl`(잡)을 쓰세요. 풀사이트 크롤은 수십~수백 페이지라 시간이 걸려 비동기(잡 등록→폴링)예요. 응답 시간: 본문만 단건 0.3–2초 · 여러 URL 일괄 1–10초(동시 4건) · 첨부 파싱은 첨부 1건당 +0.3–5초(문서 형식·페이지 수에 따라, 동시 3건). 풀사이트 `crawl` 잡은 페이지 수·politeness 지연에 따라 수십 초~수 분(백그라운드). 청구는 **성공한 페이지만**이에요. 접속 불가·본문 없음·robots 차단 등으로 실패한 URL 은 청구되지 않아요(아래 §8). ## 2. POST `/v1/crawl/scrape` 요청은 `application/json` 입니다. `url`(단건) 또는 `urls`(여러 건, 최대 20개) 중 최소 하나를 주세요. 두 필드를 함께 줘도 합쳐서 중복 제거 후 처리합니다. 순수 본문 추출 엔진은 `/v1/doc/parse/url` 과 같은 오픈소스 **trafilatura**(Apache-2.0)를 자체 내재화 — 호출당 외부 비용이 없어요. 크롤 제품으로서 여기에 **첨부 자동 파싱**·robots 준수·인코딩 자동 복원을 더했습니다. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `url` | string | — | 스크랩할 단일 웹 페이지 URL (http/https). | | `urls` | string[] | — | 여러 URL 일괄 (최대 20개). | | `output_format` | string | `markdown` | 응답 형식. `text` / `markdown` / `html` / `json` 중 선택. | | `parse_attachments` | bool | `false` | 페이지에 `.hwp` ·`.hwpx` ·`.pdf` ·`.docx` ·`.xlsx` 등 첨부가 있을 경우 자동 발견·다운로드·파싱해 `attachments[]` 로 함께 반환. 첨부 파싱 페이지당 **+2원**(문서 파서 단가). | | `max_attachments` | int | `10` | 페이지당 파싱할 첨부 최대 개수 (0~50, 비용 폭증 방어). | | `respect_robots` | bool | `false` | true 면 robots.txt Disallow 경로는 `403 blocked_by_robots` 로 거부 (합법 크롤링 증빙). | | `render` | bool | `false` | **JS 렌더(Playwright).** 스크립트로만 그려지는 페이지(SPA)에 사용 — 헤드리스 브라우저로 실제 실행한 DOM을 추출. 렌더 성공 페이지는 **5원**(`crawl_render`). 렌더 불가/포화/실패 시 정적 추출로 **자동 폴백**(그땐 2원). | | `render_wait_ms` | int | `0` | `render=true`일 때 렌더 후 추가 대기(ms, 0~8000) — 지연 로딩 콘텐츠가 채워질 시간. | | `pii_mask` | bool | `false` | 추출 본문·첨부 자동 개인정보 마스킹. **+5원 / 건** (적용된 본문·첨부마다). | | `dlp_grade` | bool | `false` | 추출 본문·첨부 자동 보안 등급·유형 분류. **+20원 / 건**. | | `moderation_check` | bool | `false` | 본문·첨부 유해발화 자동 감지. **+5원 / 건**. | | `mental_health_check` | bool | `false` | 본문·첨부 정신건강 위험 신호 감지. **+10원 / 건**. | | `pii_categories` | string[] | `null` | **`pii_mask=true`일 때만.** 마스킹할 PII 카테고리 화이트리스트 (예: `["kr_rrn","private_phone"]`). 비우면 전체. 코드는 `GET /v1/pii/categories`. | | `dlp_grades` | string[] | `null` | **`dlp_grade=true`일 때만.** 보고할 보안 등급 화이트리스트. 목록 밖이면 `grade`가 `null`. 비우면 전체. 코드는 `GET /v1/dlp/grades`. | | `dlp_types` | string[] | `null` | **`dlp_grade=true`일 때만.** 보고할 보안 유형 화이트리스트. 비우면 전체. 코드는 `GET /v1/dlp/types`. | | `moderation_labels` | string[] | `null` | **`moderation_check=true`일 때만.** 보고할 유해발화 라벨 화이트리스트. 비우면 전체. | | `mental_health_axes` | string[] | `null` | **`mental_health_check=true`일 때만.** 알림 대상 정신건강 축 화이트리스트. 비우면 전체. 코드는 `GET /v1/mental_health/axes`. | > **대상 화이트리스트.** 위 5개 필드는 해당 옵션이 켜졌을 때만 의미가 있고, **비우면 전체 대상**으로 동작해요. JSON body 라 **배열**로 넘깁니다(예: `["kr_rrn","private_phone"]`). 모델 추론 자체는 항상 전체 대상으로 수행되므로 **추가 비용은 없어요** — 화이트리스트는 응답에 담길 결과만 좁혀요. 의미·동작은 [통합 문서 파서](/docs/api/doc)와 동일합니다. **Response 필드** — `results[]` (페이지별) + `meta`. 각 페이지 결과(`CrawlScrapeItem`): | 필드 | 타입 | 설명 | |---|---|---| | `url` | string | 요청한 원본 URL | | `final_url` | string | 리다이렉트 후 최종 URL | | `title` | string | 페이지 제목 (추출된 경우) | | `text` | string | 본문 (plain text) | | `markdown` | string | `output_format=markdown`/`html`/`json`일 때 — 헤더·표·리스트 보존 마크다운 | | `html` | string | `output_format=html`일 때 | | `blocks` | array | `output_format=json`일 때 — IR 블록 배열 | | `pii_applied` | object | `pii_mask=true`일 때 — `{applied, span_count}` | | `dlp_classification` | object | `dlp_grade=true`일 때 — `{grade, grade_confidence, types}` | | `moderation` | object | `moderation_check=true`일 때 | | `mental_health` | object | `mental_health_check=true`일 때 | | `attachments` | array | `parse_attachments=true`일 때 — 발견·파싱한 첨부 목록 (`CrawlAttachmentItem`) | | `rendered` | bool | `render=true`로 JS 렌더해 가져온 페이지면 `true` (그 페이지는 `crawl_render` 5원). 정적/폴백이면 `false`. | | `warnings` | array | 사용자 알림 | | `error` | object | 이 URL 처리 실패 시 — `{code, message}` (실패 URL 은 청구 제외) | 첨부 1건(`CrawlAttachmentItem`): | 필드 | 타입 | 설명 | |---|---|---| | `url` | string | 첨부 다운로드 URL (페이지 기준 절대 경로) | | `filename` | string | 첨부 파일명 (URL 경로 또는 다운로드 파라미터 힌트에서 추출) | | `format` | string | 감지된 형식 (`hwp`/`pdf`/`docx` 등) | | `page_count` | int | 첨부 페이지 수 (첨부 청구 단위 — 페이지당 +2원) | | `text` · `markdown` · `html` · `blocks` | — | 본문 결과 (본문과 동일하게 `output_format` 따라) | | `pii_applied` · `dlp_classification` · `moderation` · `mental_health` | object | +α 옵션이 켜졌을 때 — 첨부 본문에 적용된 결과 | | `needed_ocr` | bool | 스캔 첨부 자동 OCR 발동 여부 | | `ocr_pages_used` | int | OCR 한 페이지 수 (OCR 페이지당 +2원 별도 청구) | | `warnings` | array | 첨부 처리 알림 | | `error` | object | 첨부 1건 실패 시 — `{code, message}` (다른 첨부·본문은 정상 반환) | **예시 — 단건**: ```bash curl -X POST https://api.corepin.ai/v1/crawl/scrape \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://ko.wikipedia.org/wiki/삼성전자", "output_format": "markdown"}' ``` **예시 — 게시글 본문 + HWP 첨부 함께 파싱**: ```bash curl -X POST https://api.corepin.ai/v1/crawl/scrape \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://www.example.go.kr/board/view?id=123", "output_format": "markdown", "parse_attachments": true, "max_attachments": 5 }' ``` ```json { "results": [ { "url": "https://www.example.go.kr/board/view?id=123", "final_url": "https://www.example.go.kr/board/view?id=123", "title": "○○ 사업 공고", "text": "공고번호: 2026061234 / 담당부서: ○○과 / ...", "markdown": "# ○○ 사업 공고\n\n| 항목 | 내용 |\n|---|---|\n| 공고번호 | 2026061234 |\n| 접수마감 | 2026-07-03 18:00 |", "attachments": [ { "url": "https://www.example.go.kr/cmm/fms/FileDown.do?atchFileId=FILE_000123&fileName=보고서.hwp", "filename": "보고서.hwp", "format": "hwp", "page_count": 12, "text": "Ⅰ. 일반사항\n1. 사업명: ○○ 사업 ...", "markdown": "## Ⅰ. 일반사항\n\n1. 사업명: ○○ 사업\n\n| 구분 | 내용 |\n|---|---|\n| 추정가격 | 1,250,000,000원 |" }, { "url": "https://www.example.go.kr/cmm/fms/FileDown.do?atchFileId=FILE_000123&fileName=과업지시서.pdf", "filename": "과업지시서.pdf", "format": "pdf", "page_count": 8, "text": "제1장 과업 개요 ...", "markdown": "## 제1장 과업 개요\n\n..." } ] } ], "meta": { "model_id": "crawl", "model_version": "crawl-2026.06", "processing_time_ms": 3412.8, "request_id": "abc...", "url_count": 1, "success_count": 1, "attachment_count": 2, "attachment_pages": 20, "unit_price_krw": 2, "quota_remaining": 96 } } ``` 위 예시 청구: 본문 1페이지 × 2원 + 첨부 20페이지 × 2원 = **42원**. **예시 — 여러 URL + 개인정보 자동 마스킹**: ```bash curl -X POST https://api.corepin.ai/v1/crawl/scrape \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "urls": ["https://a.example.go.kr/1", "https://b.example.go.kr/2"], "pii_mask": true, "pii_categories": ["kr_rrn", "private_phone"] }' ``` **`meta` 필드 설명**: | 필드 | 설명 | |---|---| | `model_id` | 항상 `crawl`. | | `model_version` | 모델 버전 (예: `crawl-2026.06`). | | `processing_time_ms` | 서버 처리 시간 (ms). | | `request_id` | 요청 추적 ID. | | `url_count` | 요청한 URL 수 (중복 제거 후). | | `success_count` | 본문 추출 성공 페이지 수 — **본체 청구 단위** (페이지당 2원). | | `rendered_count` | 그 중 JS 렌더로 가져온 페이지 수 (`crawl_render` 5원). | | `attachment_count` | 파싱 성공한 첨부 수. | | `attachment_pages` | 첨부 파싱 총 페이지 수 — **첨부 청구 단위** (doc 단가 페이지당 +2원). | | `unit_price_krw` | 본체 단가 (2원). | | `quota_remaining` | 잔여 호출 수 (후불 계정은 큰 정수). | 페이지 단위 실패 시 그 URL만 `{"url": "...", "error": {...}}`로 표시되고, 나머지는 정상 결과를 받아요. 첨부 1건이 실패해도 그 첨부만 `error`로 표시되고 본문·형제 첨부는 정상 반환돼요. ## 3. POST `/v1/crawl/map` 풀크롤 전에 **무엇이 긁힐지 미리 확인**하는 사이트 URL 발견 엔드포인트예요. robots.txt 의 `Sitemap` 지시문 + 표준 위치(`/sitemap.xml`)를 먼저 보고, 부족하면 시작 페이지의 1-hop 동일 사이트 링크를 모아요. 같은 등록 도메인만(co.kr·go.kr·or.kr 등 2단 SLD 고려), 중복 제거. 요청은 `application/json` 입니다. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `url` | string | (필수) | 사이트 시작 URL (http/https). | | `max_urls` | int | `200` | 발견할 URL 최대 개수 (1~2,000). | | `include_subdomains` | bool | `true` | 같은 등록 도메인의 서브도메인 포함. `false` 면 정확히 같은 호스트만. | | `respect_robots` | bool | `true` | robots.txt Disallow 경로는 결과에서 제외. | **Response**: ```json { "urls": [ "https://www.example.go.kr/notice/12345", "https://www.example.go.kr/notice/12346", "https://www.example.go.kr/board/list" ], "meta": { "model_id": "crawl", "model_version": "crawl-2026.06", "processing_time_ms": 612.4, "request_id": "def...", "site": "https://www.example.go.kr", "url_count": 3, "source": "sitemap+links", "robots_blocked": 2, "unit_price_krw": 2, "quota_remaining": 95 } } ``` `meta` 필드: `site`(발견 기준 origin) · `url_count`(반환 URL 수) · `source`(발견 출처 — `sitemap` / `links` / `sitemap+links` / `none`) · `robots_blocked`(`respect_robots=true`로 제외된 URL 수). ```bash curl -X POST https://api.corepin.ai/v1/crawl/map \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://www.example.go.kr", "max_urls": 500}' ``` 청구: 사이트(잡) 1건당 2원 (반환 URL 수와 무관). ## 4. POST `/v1/crawl/crawl` — 풀사이트 비동기 크롤 시작 URL 하나에서 **같은 사이트 링크를 따라가며** depth·개수 한도 안에서 여러 페이지를 긁는 비동기 잡이에요. RAG에 사이트를 통째로 적재할 때 씁니다. 풀사이트 크롤은 시간이 걸려(여러 페이지 + politeness 지연) 즉시 응답이 아니라 **잡을 등록(`202` + `job_id`)하고 폴링**해요. 요청은 `application/json`. 즉시 `job_id` 가 돌아오고 실제 크롤은 백그라운드에서 진행돼요. **Request 필드**: | 필드 | 타입 | 기본 | 설명 | |---|---|---|---| | `url` | string | (필수) | 크롤을 시작할 사이트 URL (http/https). 이 페이지에서 같은 사이트 링크를 따라가요. | | `max_pages` | int | `100` | 크롤할 페이지 최대 개수 (1~2,000, 비용·부하 방어). | | `max_depth` | int | `3` | 시작 페이지에서 따라갈 링크 깊이 (0=시작 페이지만, 최대 10). | | `include_paths` | string[] | `null` | 이 경로 패턴에 맞는 URL만 (예: `["/board","/notice/*"]`). 비우면 전체. | | `exclude_paths` | string[] | `null` | 이 경로 패턴은 제외 (예: `["/login","*.zip"]`). | | `include_subdomains` | bool | `true` | 같은 등록 도메인의 서브도메인도 따라갈지. | | `respect_robots` | bool | `true` | robots.txt Disallow 경로를 건너뛰고 Crawl-delay를 지켜요(합법 크롤링). | | `crawl_delay_s` | float | `0.5` | 같은 도메인 연속 요청 사이 최소 지연(초, 0~10). robots Crawl-delay가 더 크면 그쪽. | | `dedup_content` | bool | `true` | 본문이 같은 중복 페이지를 결과·청구에서 제외(content_hash). | | `render` | bool | `false` | JS 렌더(Playwright). 렌더 페이지당 5원(`crawl_render`), 실패 시 정적 폴백(2원). | | `render_wait_ms` | int | `0` | `render=true`일 때 렌더 후 추가 대기(ms, 0~8000). | | `output_format` | string | `markdown` | `text`/`markdown`/`html`/`json`. | | `parse_attachments` · `max_attachments` | — | scrape와 동일(첨부 자동 파싱). | | `pii_mask` · `dlp_grade` · `moderation_check` · `mental_health_check` | bool | `false` | scrape와 동일한 +α 안전망(본문·첨부에 적용). | | `pii_categories` · `dlp_grades` · `dlp_types` · `moderation_labels` · `mental_health_axes` | string[] | `null` | scrape와 동일한 대상 화이트리스트. | | `webhook_url` | string | `null` | 잡 완료/실패 시 알림 받을 URL(POST, 메타만 — 개인정보 안전). | 동시 진행 잡 한도: API 키당 2개·전체 10개(초과 시 `429`/`503`). 한 잡 최대 2,000 페이지. 잡은 24시간 보관돼요. **제출 — `202 Accepted`**: ```bash curl -X POST https://api.corepin.ai/v1/crawl/crawl \ -H "Authorization: Bearer $COREPIN_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://docs.example.com/", "max_pages": 200, "max_depth": 3, "output_format": "json"}' ``` ```json { "job_id": "682216dec77e474eae9368bbd2a7dba7", "status": "queued", "start_url": "https://docs.example.com/", "status_url": "/v1/crawl/crawl/682216dec77e474eae9368bbd2a7dba7", "meta": {"model_id": "crawl", "model_version": "crawl-2026.06", "unit_price_krw": 2, "max_pages": 200} } ``` **폴링 — `GET /v1/crawl/crawl/{job_id}`** (권장 간격 5초): ```json { "job_id": "682216de...", "status": "done", "start_url": "https://docs.example.com/", "pages_crawled": 187, "success_count": 184, "attachment_pages": 0, "stopped_reason": "completed", "submitted_at": "2026-06-22T02:07:03Z", "finished_at": "2026-06-22T02:09:41Z", "amount_krw": 368, "results": [ { "url": "...", "final_url": "...", "depth": 0, "title": "...", "text": "...", "markdown": "..." }, ... ] } ``` `status`: `queued` → `processing` → `done` / `failed` / `cancelled`. `stopped_reason`: `completed`(다 긁음) / `max_pages`(상한 도달) / `cancelled` / `error`. 결과가 크면 `results`는 압축 저장 후 폴링 시 펼쳐 돌려줘요. 페이지·첨부 실패는 해당 항목에 `error`로 박히고 잡은 계속돼요. **목록 / 취소**: ```bash curl https://api.corepin.ai/v1/crawl/crawl -H "Authorization: Bearer $COREPIN_API_KEY" # 내 잡 50개 curl -X DELETE https://api.corepin.ai/v1/crawl/crawl/682216de... -H "Authorization: Bearer $COREPIN_API_KEY" # 취소 ``` 취소 시 `queued`면 바로 취소, `processing`이면 곧 멈춰요(이미 긁은 페이지만 청구). 청구: 본문 성공 페이지당 2원(JS 렌더 페이지는 5원), 첨부·+α는 scrape와 동일. **성공분만** — 취소·실패분은 미과금. ## 5. GET `/v1/crawl/version` ```bash curl https://api.corepin.ai/v1/crawl/version \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 모델 ID·버전·이름·릴리스 노트·엔드포인트 목록 반환. ## 6. GET `/v1/crawl/formats` ```bash curl https://api.corepin.ai/v1/crawl/formats \ -H "Authorization: Bearer $COREPIN_API_KEY" ``` 기능 목록 + 일반 크롤러 대비 비교표 + **첨부 자동 파싱 지원 형식**(`hwp`·`hwpx`·`hwpml`·`pdf`·`doc`·`docx`·`xls`·`xlsx`·`pptx`·`csv`·`rtf`) + 출력 형식 + +α 옵션 + 한 호출 최대 URL 수(20) + 페이지당 최대 첨부 수(50) 반환. ## 7. 한국 특화 기능 ### 7.1 첨부 자동 파싱 페이지에 `.hwp`·`.pdf`·`.docx`·`.xlsx` 같은 첨부가 걸려 있을 경우 함께 처리해요. `parse_attachments=true` 면 페이지 HTML 의 `href`/`src` 에서 첨부 링크를 발견하고, 다운로드 엔드포인트가 확장자를 URL 에 안 박는 공공 사이트 패턴(`/cmm/fms/FileDown.do?atchFileId=...&fileName=보고서.hwp`)까지 파일명 힌트 파라미터로 알아채요. 발견한 첨부는 한국형 통합 문서 파서에 넘겨 본문과 함께 마크다운/텍스트/JSON 으로 돌려줘요 — 일반 크롤러가 못 푸는 한국 HWP 도 정확히 추출합니다. - 로그인 벽·오류 페이지가 HTTP 200 + HTML 로 오는 경우(공공 사이트 흔함), 바이너리 첨부인데 본문이 HTML 이면 진짜 파일이 아니라고 판단해 `attachment_not_a_file` 로 깨끗이 표시해요(엉뚱한 파싱 방지). - 첨부 1건 최대 30MB. 페이지당 최대 첨부 수는 `max_attachments`(기본 10, 상한 50). ### 7.2 EUC-KR/CP949 레거시 인코딩 복원 EUC-KR/CP949 로 서빙하는 정부·기관 사이트의 깨진 글자(mojibake)를 자동 감지·복원해요. 문서 파서의 인코딩 자동감지 철학을 웹에도 적용한 거예요 — 별도 옵션 없이 항상 동작합니다. ### 7.3 크롤 + 안전 검사 (사내 적재 전) 외부에서 긁은 콘텐츠를 사내 RAG 에 넣기 전, 같은 호출에서 개인정보 자동 마스킹(`pii_mask`)·기밀 등급 분류(`dlp_grade`)·유해발화 감지(`moderation_check`)·정신건강 위험 신호 감지(`mental_health_check`)를 묶어 처리할 수 있어요. 긁은 데이터도 개인정보 보호 검사를 거쳐 들어가요. 본문과 첨부 양쪽에 동일하게 적용됩니다. ### 7.4 robots.txt 준수 + 감사로그 `respect_robots=true`(scrape)면 Disallow 경로는 `403 blocked_by_robots` 로 거부해요. `/map` 은 기본으로 robots 를 존중해 Disallow URL 을 결과에서 제외하고 `robots_blocked` 수를 알려줘요. 어떤 키가 어떤 도메인을 언제 크롤했는지 감사로그로 남아 한국 법무팀 친화적입니다. ### 7.5 SSRF 차단 `http`/`https` 만 허용하고, 내부망·로컬·메타데이터 주소(`127.0.0.1`·`10.x`·`192.168.x`·`169.254.169.254` 등)는 차단합니다. 호스트명은 DNS resolve 후 모든 IP 를 검사하고, 리다이렉트도 매 홉마다 같은 기준으로 다시 검사해요. 페이지 최대 10MB, 첨부 최대 30MB. ## 8. 단가 정리 청구는 **성공한 페이지만**이에요. 접속 불가·본문 없음·robots 차단 등으로 실패한 URL 은 청구되지 않아요 — 요청 시 한도(RPM·월)만 검사하고, 월 카운터·사용 원장에는 성공분만 반영합니다. | 항목 | 단가 | |---|---:| | 본문 스크랩 (`/v1/crawl/scrape`) | 2원 / 성공 페이지 | | 사이트 URL 발견 (`/v1/crawl/map`) | 2원 / 사이트 (반환 URL 수 무관) | | 첨부 파싱 (HWP·PDF·DOCX·XLSX 등) | +2원 / 첨부 문서 페이지 (`doc` 단가) | | 첨부 스캔 자동 OCR | 2원 / OCR한 페이지 (`ocr` 단가, 그 페이지만 추가) | | 옵션 `pii_mask` | + 5원 / 건 (적용된 본문·첨부마다) | | 옵션 `dlp_grade` | + 20원 / 건 | | 옵션 `moderation_check` | + 5원 / 건 | | 옵션 `mental_health_check` | + 10원 / 건 | | JS 렌더 (Playwright, `render=true`) | 5원 / 렌더 페이지 (`crawl_render`) · 실패 시 정적 폴백 2원 | > 월 구독제(안 써도 청구) 대비, Corepin Crawl 은 종량 ₩2/페이지·성공분만·선불/후불이에요. trafilatura 자체 내재화 + CPU-only 라 호출당 외부 비용이 없습니다. 무료 한도 1,000회/월. 후불 정산은 매월 1일 09:00 KST. 본체·첨부·옵션 모두 같은 월 한도·청구를 공유해요(자세한 청구는 [빠른 시작 §5](/docs/quickstart)). ## 9. 오류 코드 페이지 단위 실패는 해당 URL 결과의 `error: {code, message}` 로 표시돼요(전체 호출은 200, 그 URL 만 청구 제외). `/map` 의 입력 검증 실패는 호출 전체가 해당 HTTP 코드로 떨어져요. | HTTP | code | 의미 | |---|---|---| | 400 | `empty_url` | `url`·`urls` 둘 다 비어 있음 | | 400 | `invalid_output_format` | `output_format`이 text/markdown/html/json이 아님 | | 400 | `too_many_urls` | 한 호출 20개 URL 초과 | | 400 | `unsupported_scheme` | http/https 외 스킴 | | 400 | `invalid_url` | URL 에서 호스트를 찾을 수 없음 | | 400 | `url_too_long` | URL 4096자 초과 | | 400 | `blocked_private_address` | 내부망·로컬·메타데이터 주소 (SSRF 차단) | | 403 | `blocked_by_robots` | `respect_robots=true` 인데 robots.txt Disallow 경로 | | 413 | `page_too_large` | 페이지 본문 10MB 초과 | | 413 | `attachment_too_large` | 첨부 30MB 초과 | | 422 | `dns_resolution_failed` | 호스트 DNS 조회 실패 | | 422 | `no_content` | 본문을 못 찾음 (로그인 필요·JS 렌더 페이지 등) | | 422 | `extraction_failed` | 본문 추출 실패 | | 422 | `attachment_not_a_file` | 첨부 링크가 실제 파일이 아니라 웹 페이지(로그인/오류 페이지) | | 502 | `fetch_failed` | 페이지·첨부에 연결 실패 (4xx/5xx 응답 포함) | | 502 | `bad_redirect` / `too_many_redirects` | 리다이렉트 위치 비었거나 너무 많음 | | 502 | `crawl_failed` | 그 외 크롤 처리 실패 | | 502 | `attachment_parse_failed` | 첨부 파싱 실패 | | 503 | `missing_dependency` | 본문 추출 엔진(trafilatura) 미설치 (운영 측 알림) | | 504 | `fetch_timeout` | 페이지·첨부 응답 시간 초과 | 공통 오류 응답·재시도 안내는 [빠른 시작 §6](/docs/quickstart) 참고. `X-Request-ID` 응답 헤더는 모든 응답에 포함돼요. ## 10. 일반 크롤러 대비 비교 | 항목 | 일반 크롤러 | Corepin Crawl | |---|---|---| | 본문 추출 | 보통 (markdown/json) | 강함 (trafilatura) | | 한국 사이트 인코딩 | 약함 (EUC-KR 깨짐) | **자동 복원 (압도적)** | | HWP/PDF 첨부 | 불가 | **자동 발견·파싱** | | 개인정보·기밀 마스킹 | 없음 | **한 호출 통합 (개인정보 보호)** | | 합법성 증빙 | 약함 | **robots 준수 + 감사로그** | | 가격 | 월 구독 (안 써도 청구) | **종량 ₩2/페이지 (선불·후불)** | 문의: <support@corepin.ai>