# Format respons Read API, field demi field

> Format respons Read API: field tiap halaman dari markdown dan word_count hingga final_url dan rendered, plus hasil job. Bayar pakai kripto tanpa KYC.

- URL: https://webreaderapi.com/id/docs/response/
- Terakhir diperbarui: 2026-10-22
- Penerbit: WebReaderAPI (https://webreaderapi.com)

Setiap panggilan `/read` mengembalikan satu objek JSON: konten halaman dalam format yang Anda minta, metadatanya, dan tiga field yang memberi tahu Anda apa yang terjadi dan berapa biayanya. Hasil job menggunakan objek yang sama.

**Jawaban singkat — Apa saja isi respons read dari WebReaderAPI?**

Respons **WebReaderAPI** `/read` memuat konten halaman dalam `markdown` (atau `text` atau `html`), metadatanya (`title`, `description`, `author`, `published_at`, `language`, `site_name`, `word_count`), dan fakta tentang pengambilan: `final_url`, `status_code`, `rendered`, dan `credits_used`. Halaman biasa memakai 1 kredit, dari US$0,07/1K halaman per Oktober 2026. Tanpa KYC; bayar dengan kripto.

## Field mana yang menjelaskan proses pengambilan?

Field-field ini selalu ada dalam respons yang berhasil.

| Field | Tipe | Arti |
| --- | --- | --- |
| `url` | string | Alamat yang Anda kirim |
| `final_url` | string | Alamat yang benar-benar dibaca, setelah redirect (maksimal 5) |
| `status_code` | integer | Status HTTP yang dikembalikan situs untuk alamat final, biasanya 200 |
| `fetched_at` | string | Waktu fetch, ISO 8601 dalam UTC |
| `rendered` | boolean | `true` saat browser headless membangun halaman |
| `credits_used` | integer | Kredit yang ditagih untuk halaman ini: 1, 2 dengan browser, ditambah 10 dengan `country`; PDF 1 per 10 halaman yang dimulai |

## Field mana yang menjelaskan halaman?

Metadata berasal dari halaman itu sendiri: tag title, meta tag, structured data, dan byline yang terlihat. Field yang tidak disediakan halaman akan absen, jadi uji dulu sebelum digunakan.

| Field | Tipe | Arti |
| --- | --- | --- |
| `title` | string | Judul halaman atau artikel |
| `description` | string | Ringkasan yang diberikan halaman tentang dirinya sendiri |
| `language` | string | Kode bahasa konten, seperti `en` atau `de` |
| `author` | string | Penulis yang tercantum di halaman |
| `published_at` | string | Tanggal publikasi yang dinyatakan halaman |
| `site_name` | string | Nama situs itu sendiri |
| `word_count` | integer | Jumlah kata dalam konten yang dikembalikan, setelah ekstraksi dan sebelum `max_chars` |

## Di mana kontennya sendiri?

Satu field konten dikembalikan, dinamai sesuai `format` yang Anda pilih.

| Field | When | Content |
| --- | --- | --- |
| `markdown` | `format=markdown` (default) | Heading, paragraf, list, tabel, dan link dalam Markdown; gambar juga dengan `include_images=true` |
| `text` | `format=text` | Teks biasa, paragraf dipisahkan baris kosong |
| `html` | `format=html` | HTML bersih dari konten utama, tanpa script, style, atau iklan |
| `links` | `include_links=true` | Daftar `{url, text}` untuk tautan yang ditemukan di halaman, URL absolut |

*Respons lengkap (nilai bersifat ilustratif)*

```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" }
  ]
}
```

## Bagaimana cara membedakan halaman yang dirender dari halaman biasa?

Lihat `rendered`. Dengan `render=auto`, API terlebih dahulu membaca HTML mentah; browser hanya dijalankan ketika HTML tersebut memuat terlalu sedikit teks, lalu menyetel `rendered` ke `true` dan `credits_used` ke 2. Jika situs yang sering Anda baca selalu kembali dalam keadaan dirender, kirim `render=true` sejak awal: biayanya sama dan Anda melewati langkah pertama yang sia-sia.

Jika halaman kembali tanpa dirender tetapi kontennya tipis, bandingkan `word_count` dengan apa yang Anda lihat di browser. Jumlah yang rendah biasanya berarti konten membutuhkan JavaScript; coba ulang sekali dengan `render=true`.

## Mengapa final_url bisa berbeda dari url?

Karena situs melakukan redirect. Tautan pendek, alamat lama, garis miring di akhir yang hilang, atau pergantian bahasa semuanya mengarahkan Anda ke tempat lain. API mengikuti hingga 5 redirect dan melaporkan alamat yang akhirnya dibaca di `final_url`.

Simpan `final_url` sebagai sumber kanonik sebuah dokumen di indeks RAG. Dua nilai `url` berbeda yang berakhir di `final_url` yang sama adalah halaman yang sama, jadi Anda bisa membuang duplikatnya sebelum melakukan embedding.

## Seperti apa hasil job?

`GET https://webreaderapi.com/api/v1/jobs/{job_id}` mengembalikan `job_id`, `status` (`queued`, `running` atau `done`), `results`, `next_cursor` dan `credits_used` job yang sedang berjalan. Setiap item `results` berbentuk salah satu dari dua bentuk:

- respons `/read` lengkap, persis seperti yang dijelaskan di atas, untuk halaman yang berhasil dibaca;
- `{url, error}` untuk halaman yang tidak berhasil dibaca, di mana `error` memiliki `code` dan `message` yang sama dengan [API error](https://webreaderapi.com/id/docs/errors/).

`next_cursor` ada selama masih ada hasil lain yang siap; kirim kembali sebagai `cursor` untuk mengambilnya. [Halaman batch dan crawl](https://webreaderapi.com/id/docs/crawl/) memiliki polling loop lengkap.

*Halaman hasil job (nilai bersifat ilustratif)*

```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
}
```

## Seperti apa respons error?

Error dikembalikan dengan status HTTP 400 atau lebih dan body JSON `{"error": {"code", "message"}}`. Ketika situs itu sendiri menolak permintaan, `target_status` memberikan status yang dikirim situs. Tidak ada error yang ditagih. [Halaman errors](https://webreaderapi.com/id/docs/errors/) mencantumkan setiap kode beserta penyebabnya dan apakah mencoba ulang dapat membantu.

## Format respons: pertanyaan umum

### Apakah Markdown terpotong saat saya menyetel max_chars?

Ya. Field content berhenti pada jumlah karakter tersebut. `word_count` tetap menjelaskan seluruh konten yang diekstrak, jadi Anda bisa melihat berapa banyak yang tersisa di luar.

### Mengapa author atau published_at tidak ada?

Karena halaman tidak menyatakannya dengan cara yang bisa dibaca. Banyak halaman tidak mencantumkan penulis atau tanggal. Field yang tidak ada dihilangkan, bukan dikembalikan kosong.

### Apakah tautan di Markdown bersifat absolut?

Tautan di daftar `links` bersifat absolut. Tulis kode Anda agar menerima kedua bentuk di body Markdown, dan selesaikan yang relatif terhadap `final_url`.

### Bisakah saya mendapatkan HTML mentah dari seluruh halaman?

Yang paling mendekati adalah `format=html` dengan `main_content=false`, yang mengembalikan seluruh halaman setelah dibersihkan dari script dan style. HTML asli byte demi byte bukan bagian dari v1.

---

WebReaderAPI: WebReaderAPI adalah API pembaca web untuk AI agent yang mengubah halaman web publik apa pun menjadi Markdown bersih, dibayar dengan kripto tanpa unggah identitas. Kredit prabayar mulai dari US$0,07/1K halaman tidak pernah kedaluwarsa, dan robots.txt dihormati. Tanpa KYC — tanpa identitas, tanpa selfie, tanpa dokumen. Bayar dengan kripto.
