# Read API 응답 형식, field별 상세

> Read API 응답 형식: markdown과 word_count부터 final_url, rendered까지 페이지에 대해 반환되는 모든 field, 그리고 job 결과. KYC 없이, 암호화폐 결제.

- URL: https://webreaderapi.com/ko/docs/response/
- 마지막 업데이트: 2026-10-22
- 발행자: WebReaderAPI (https://webreaderapi.com)

모든 `/read` 호출은 하나의 JSON object를 반환합니다: 요청한 형식의 페이지 콘텐츠, 메타데이터, 그리고 무슨 일이 있었고 얼마가 들었는지 알려주는 세 field입니다. Job 결과도 동일한 object를 재사용합니다.

**빠른 답변 — WebReaderAPI read 응답에는 무엇이 들어 있나요?**

**WebReaderAPI** `/read` 응답에는 `markdown`(또는 `text`, `html`) 형식의 페이지 콘텐츠, 메타데이터(`title`, `description`, `author`, `published_at`, `language`, `site_name`, `word_count`), 그리고 fetch에 관한 정보(`final_url`, `status_code`, `rendered`, `credits_used`)가 담겨 있습니다. 일반 페이지는 1 크레딧이 들며, 2026년 10월 기준 US$0.07/1K 페이지부터 시작합니다. KYC 없이, 암호화폐 결제.

## 어떤 field가 fetch를 설명하나요?

이 field는 성공한 응답에 항상 포함됩니다.

| 필드 | 타입 | 의미 |
| --- | --- | --- |
| `url` | string | 보낸 주소 |
| `final_url` | string | redirect 후 실제로 읽은 주소 (최대 5회) |
| `status_code` | integer | 사이트가 최종 주소에 대해 반환한 HTTP 상태이며, 보통 200입니다 |
| `fetched_at` | string | 가져온 시각, UTC 기준 ISO 8601 |
| `rendered` | boolean | 헤드리스 브라우저가 페이지를 렌더링한 경우 `true` |
| `credits_used` | integer | 이 페이지에 청구된 크레딧: 1, 브라우저 사용 시 2, `country` 사용 시 10 추가; PDF는 시작된 10페이지당 1 |

## 어떤 필드가 페이지를 설명하나요?

메타데이터는 페이지 자체에서 가져옵니다: title 태그, meta 태그, 구조화 데이터, 그리고 화면에 보이는 작성자 표기입니다. 페이지가 제공하지 않는 필드는 없으므로 사용 전에 확인하세요.

| 필드 | 타입 | 의미 |
| --- | --- | --- |
| `title` | string | 페이지 또는 글 제목 |
| `description` | string | 페이지가 스스로에 대해 제공하는 요약 |
| `language` | string | 콘텐츠의 언어 코드, 예: `en` 또는 `de` |
| `author` | string | 페이지에 명시된 작성자 |
| `published_at` | string | 페이지에 명시된 게시 날짜 |
| `site_name` | string | 사이트 자체의 이름 |
| `word_count` | integer | 본문 추출 후 `max_chars` 전까지, 반환된 콘텐츠의 단어 수 |

## 콘텐츠 자체는 어디에 있나요?

선택한 `format` 이름으로 지정된 콘텐츠 필드 하나가 반환됩니다.

| 필드 | When | Content |
| --- | --- | --- |
| `markdown` | `format=markdown` (기본값) | Markdown 형식의 제목, 문단, 목록, 표, 링크; `include_images=true` 사용 시 이미지도 포함 |
| `text` | `format=text` | 빈 줄로 문단을 구분한 일반 텍스트 |
| `html` | `format=html` | 스크립트, 스타일, 광고를 제외한 본문의 정리된 HTML |
| `links` | `include_links=true` | 페이지에서 발견된 링크의 `{url, text}` 목록, 절대 URL |

*전체 응답 (값은 예시입니다)*

```json
{
  "url": "https://example.com/guides/compost",
  "final_url": "https://example.com/guides/compost-at-home",
  "status_code": 200,
  "fetched_at": "2026-10-22T10:02:44Z",
  "rendered": false,
  "credits_used": 1,
  "title": "Compost at home: a beginner's guide",
  "description": "What to put in a compost bin, and what to leave out.",
  "language": "en",
  "author": "Sam Rivera",
  "published_at": "2026-09-14",
  "site_name": "Example Garden",
  "markdown": "# Compost at home: a beginner's guide\n\nA compost bin turns kitchen scraps into soil...\n\n## What goes in\n\n- Fruit and vegetable peels\n- Coffee grounds\n\nSee also [Choosing a bin](https://example.com/guides/bins).",
  "word_count": 1184,
  "links": [
    { "url": "https://example.com/guides/bins", "text": "Choosing a bin" }
  ]
}
```

## 렌더링된 페이지와 일반 페이지는 어떻게 구분하나요?

`rendered`을 보세요. `render=auto`을 사용하면 API가 먼저 원본 HTML을 읽고, 해당 HTML에 텍스트가 너무 적을 때만 브라우저를 실행하며, 그때 `rendered`를 `true`으로, `credits_used`를 2로 설정합니다. 자주 읽는 사이트가 항상 렌더링된 상태로 돌아온다면 처음부터 `render=true`를 보내세요. 비용은 동일하고 낭비되는 첫 단계를 건너뛸 수 있습니다.

페이지가 렌더링되지 않은 채로 돌아왔지만 내용이 빈약하다면 `word_count`을 브라우저에서 보이는 것과 비교하세요. 수치가 낮으면 보통 콘텐츠에 JavaScript가 필요하다는 뜻이므로 `render=true`로 한 번 다시 시도하세요.

## final_url이 url과 다른 이유는 무엇인가요?

사이트가 리다이렉트하기 때문입니다. 단축 링크, 오래된 주소, 빠진 끝 슬래시, 언어 전환 등은 모두 다른 곳으로 보냅니다. API는 최대 5개의 리다이렉트를 따라가며 최종적으로 읽은 주소를 `final_url`에 보고합니다.

RAG 인덱스에서 문서의 정식 출처로 `final_url`을 저장하세요. 같은 `final_url`에서 끝나는 서로 다른 두 `url` 값은 같은 페이지이므로, 임베딩하기 전에 중복을 제거할 수 있습니다.

## 작업 결과는 어떤 모습인가요?

`GET https://webreaderapi.com/api/v1/jobs/{job_id}`은 `job_id`, `status` (`queued`, `running` 또는 `done`), `results`, `next_cursor` 그리고 작업의 실행 중인 `credits_used`을 반환합니다. `results`의 각 항목은 두 가지 형태 중 하나입니다:

- 읽힌 페이지에 대한, 위에서 설명한 그대로의 전체 `/read` 응답;
- 읽히지 않은 페이지에 대한 `{url, error}`, 여기서 `error`은 [API 오류](https://webreaderapi.com/ko/docs/errors/)와 동일한 `code`과 `message`을 가집니다.

결과가 더 준비되어 있는 동안 `next_cursor`이 존재하며, `cursor`로 다시 보내면 받을 수 있습니다. [배치 및 크롤링 페이지](https://webreaderapi.com/ko/docs/crawl/)에 전체 폴링 루프가 있습니다.

*작업 결과 페이지 (값은 예시입니다)*

```json
{
  "job_id": "job_5c1e8a90d2",
  "status": "done",
  "results": [
    { "url": "https://example.com/blog/post-1", "final_url": "https://example.com/blog/post-1", "status_code": 200, "rendered": false, "credits_used": 1, "title": "Post one", "markdown": "# Post one\n\n...", "word_count": 802 },
    { "url": "https://example.org/members/area", "error": { "code": "target_refused", "message": "The site refused the request.", "target_status": 403 } }
  ],
  "credits_used": 1
}
```

## 오류 응답은 어떤 모습인가요?

오류는 HTTP 상태 400 이상과 JSON 본문 `{"error": {"code", "message"}}`로 돌아옵니다. 사이트 자체가 요청을 거부한 경우 `target_status`은 사이트가 보낸 상태를 알려줍니다. 오류에는 요금이 부과되지 않습니다. [오류 페이지](https://webreaderapi.com/ko/docs/errors/)에 모든 코드와 원인, 재시도가 도움이 되는지 여부가 나열되어 있습니다.

## 응답 형식: 자주 묻는 질문

### max_chars를 설정하면 Markdown이 잘리나요?

예. content 필드는 해당 문자 수에서 멈춥니다. `word_count`은 여전히 추출된 전체 콘텐츠를 나타내므로 얼마나 빠졌는지 확인할 수 있습니다.

### author 또는 published_at이 없는 이유는 무엇인가요?

페이지가 읽을 수 있는 방식으로 이를 명시하지 않기 때문입니다. 많은 페이지가 저자나 날짜를 제공하지 않습니다. 없는 필드는 빈 값으로 반환되지 않고 생략됩니다.

### Markdown의 링크는 절대 URL인가요?

`links` 목록의 링크는 절대 URL입니다. 코드가 Markdown 본문의 두 형태를 모두 받아들이도록 작성하고, 상대 링크는 `final_url`을 기준으로 해석하세요.

### 전체 페이지의 원본 HTML을 얻을 수 있나요?

가장 가까운 것은 `main_content=false`과 함께 `format=html`을 사용하는 것으로, 스크립트와 스타일이 제거된 전체 페이지를 반환합니다. 바이트 단위의 원본 HTML은 v1에 포함되지 않습니다.

---

WebReaderAPI: WebReaderAPI는 AI 에이전트를 위한 웹 리더 API로, 모든 공개 웹페이지를 깔끔한 Markdown으로 변환하며 신분증 업로드 없이 암호화폐로 결제합니다. US$0.07/1K 페이지부터 시작하는 선불 크레딧은 만료되지 않으며, robots.txt를 준수합니다. KYC 없음 — 신분증도, 셀피도, 서류도 없습니다. 암호화폐로 결제하세요.
