Hızlı yanıt
WebReaderAPI ile bir web sitesini nasıl Markdown'a dönüştürürüm?
Başlangıç URL'sini bir sayfa limit ile POST https://webreaderapi.com/api/v1/crawl adresine gönderin. WebReaderAPI siteyi arka planda okur, yalnızca aynı alan adında, sitemap'ini, robots.txt'ini ve Crawl-delay'ini izleyerek, iş başına 10.000 sayfaya kadar. Markdown sayfalarını işten, her seferinde bir sonuç sayfası olarak toplayın. Her sayfa okuma 1 kredi (tarayıcı ile 2) tutar, Ekim 2026 itibarıyla $0,07/1K sayfa'den. KYC yok; kripto ile ödeme.
İşlere kısa bir bakış
| Batch | Toplu iş başına 100 URL'ye kadar: POST https://webreaderapi.com/api/v1/batch |
|---|---|
| Tarama (crawl) | İş başına bir web sitesi tarama (crawl), 10.000 sayfaya kadar, sitemap'ini, robots.txt'ini ve Crawl-delay'ini izleyerek: POST https://webreaderapi.com/api/v1/crawl |
| Sonuçlar | GET https://webreaderapi.com/api/v1/jobs/{job_id}, ardından bir sonraki sonuç sayfası için ?cursor=… |
| Faturalandırma | Her sayfa okuma bir /read çağrısı gibi faturalandırılır; robots.txt tarafından atlanan sayfalar ve başarısız sayfalar ücretsizdir |
| Bir crawl'ın kapsamı | Tek alan adı; diğer alan adlarına bağlantılar listelenir ancak okunmaz |
| Bir işi iptal etme | v1'de yok: ödemeye hazır olduğunuz en fazla sayfa sayısını limit olarak ayarlayın |
Bir batch işi başlatın
POST/api/v1/batch
Aynı seçeneklerle 100 URL'ye kadar arka planda okur. Seçenekler /read adlarını ve değerlerini kullanır. Yanıt iş ID'sidir; değerler örnektir.
Kimlik doğrulama: Authorization: Bearer API_KEY header'ında API anahtarı.
İstek gövdesi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
urls | array of strings | Evet | 1 ila 100 arası http veya https URL'si. Yinelenenler bir kez okunur. |
options | object | Hayır | url dışında herhangi bir /read parametresi: format, main_content, render, include_links, include_images, country, max_chars, timeout. |
{
"urls": [
"https://example.com/blog/post-1",
"https://example.com/blog/post-2",
"https://example.org/news/launch"
],
"options": {
"format": "markdown",
"max_chars": 50000
}
}Yanıt 202 Accepted
{
"job_id": "job_5c1e8a90d2"
}Kod örnekleri
curl -s "https://webreaderapi.com/api/v1/batch" \
-H "Authorization: Bearer $WEBREADER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}}'import os
import requests
resp = requests.post(
"https://webreaderapi.com/api/v1/batch",
headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
json={"urls": ["https://example.com/blog/post-1", "https://example.com/blog/post-2"], "options": {"format": "markdown"}},
timeout=30,
)
print(resp.json()["job_id"])const res = await fetch('https://webreaderapi.com/api/v1/batch', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ urls: ['https://example.com/blog/post-1', 'https://example.com/blog/post-2'], options: { format: 'markdown' } }),
});
console.log((await res.json()).job_id);Bir tarama (crawl) işi başlatın
POST/api/v1/crawl
Başlangıç URL'sinden tek bir web sitesini genişlik öncelikli olarak okur. Tarayıcı (crawler) başlangıç URL'sinin alan adında kalır, robots.txt içinde belirtilen veya /sitemap.xml adresinde bulunan sitemap'i kullanır ve robots.txt ile Crawl-delay kurallarına uyar. Değerler örnektir.
Kimlik doğrulama: Authorization: Bearer API_KEY header'ında API anahtarı.
İstek gövdesi
| Alan | Tür | Zorunlu | Açıklama |
|---|---|---|---|
url | string | Evet | Başlangıç sayfası; örneğin bir dokümantasyon sitesinin ana sayfası. |
limit | integer | Hayır | Okunacak en fazla sayfa sayısı, 10.000'e kadar. İş bu sayıya ulaştığında durur. |
max_depth | integer | Hayır | Başlangıç URL'sinden en fazla kaç bağlantı adımı uzakta gidileceği. |
include_paths | array of strings | Hayır | Tutulacak basit yol kalıpları; örneğin /docs/*. |
exclude_paths | array of strings | Hayır | Atlanacak basit yol kalıpları; örneğin /blog/tag/*. |
options | object | Hayır | Her sayfaya uygulanan, url dışında herhangi bir /read parametresi. |
{
"url": "https://docs.example.com/",
"limit": 500,
"max_depth": 3,
"include_paths": [
"/docs/*"
],
"exclude_paths": [
"/docs/archive/*"
],
"options": {
"format": "markdown"
}
}Yanıt 202 Accepted
{
"job_id": "job_8b27f41c0e"
}Kod örnekleri
curl -s "https://webreaderapi.com/api/v1/crawl" \
-H "Authorization: Bearer $WEBREADER_API_KEY" \
-H "Content-Type: application/json" \
-d '{"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]}'import os
import requests
resp = requests.post(
"https://webreaderapi.com/api/v1/crawl",
headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
json={"url": "https://docs.example.com/", "limit": 500, "include_paths": ["/docs/*"]},
timeout=30,
)
print(resp.json()["job_id"])const res = await fetch('https://webreaderapi.com/api/v1/crawl', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ url: 'https://docs.example.com/', limit: 500, include_paths: ['/docs/*'] }),
});
console.log((await res.json()).job_id);İş durumunu ve sonuçları alın
GET/api/v1/jobs/{job_id}
İşin durumunu ve hazır olan sonraki sonuçları döndürür. results dizisindeki her öğe ya tam bir /read yanıtıdır ya da okunamayan bir sayfa için {url, error}. next_cursor mevcutsa, cursor değerini ona ayarlayarak tekrar çağırın; yoksa henüz hazır başka sonuç yoktur. Değerler örnektir.
Kimlik doğrulama: Authorization: Bearer API_KEY header'ında API anahtarı.
Parametreler
| Ad | Konum | Tür | Zorunlu | Açıklama |
|---|---|---|---|---|
job_id | path | string | Evet | /batch veya /crawl tarafından döndürülen ID. |
cursor | query | string | Hayır | Sonraki sonuçları almak için önceki çağrıdaki next_cursor değeri. |
Yanıt 200
{
"job_id": "job_8b27f41c0e",
"status": "running",
"results": [
{
"url": "https://docs.example.com/docs/install",
"final_url": "https://docs.example.com/docs/install",
"status_code": 200,
"rendered": false,
"credits_used": 1,
"title": "Install",
"markdown": "# Install\n\nRun the installer...",
"word_count": 418
},
{
"url": "https://docs.example.com/docs/private",
"error": {
"code": "blocked_by_robots",
"message": "robots.txt disallows this page for WebReaderAPI."
}
}
],
"next_cursor": "c_000002",
"credits_used": 1
}Kod örnekleri
curl -sG "https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e" \
-H "Authorization: Bearer $WEBREADER_API_KEY" \
-d cursor=c_000002import os
import requests
resp = requests.get(
"https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e",
headers={"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]},
params={"cursor": "c_000002"},
timeout=30,
)
job = resp.json()
print(job["status"], len(job["results"]), job.get("next_cursor"))const res = await fetch('https://webreaderapi.com/api/v1/jobs/job_8b27f41c0e?cursor=c_000002', {
headers: { Authorization: `Bearer ${process.env.WEBREADER_API_KEY}` },
});
const job = await res.json();
console.log(job.status, job.results.length, job.next_cursor);Bir işin bitmesini nasıl beklerim?
/jobs/{job_id} çağrısını yoklayıp cursor'ı koruyun. Gelen sonuçları işleyin, ardından cursor değerini next_cursor olarak ayarlayarak tekrar çağırın. next_cursor yoksa ve status done ise, her şey elinizde demektir; yoksa ve iş hâlâ running ise, bekleyip aynı cursor ile yeniden sorun.
Yoklamaya her 2 saniyede bir başlayın ve yeni bir şey gelmediği sürece beklemeyi 30 saniyeye kadar ikiye katlayın. Bir sitenin Crawl-delay değerine uyan bir tarama biraz zaman alabilir, yani uzun bir bekleme normaldir ve hiçbir ücrete tabi değildir.
import os
import pathlib
import re
import time
import requests
JOBS = "https://webreaderapi.com/api/v1/jobs"
HEADERS = {"Authorization": "Bearer " + os.environ["WEBREADER_API_KEY"]}
def save_job(job_id, folder="pages"):
out = pathlib.Path(folder)
out.mkdir(exist_ok=True)
cursor, wait, saved = None, 2, 0
while True:
params = {"cursor": cursor} if cursor else {}
job = requests.get(f"{JOBS}/{job_id}", headers=HEADERS, params=params, timeout=30).json()
for item in job["results"]:
if "error" in item:
print("skipped", item["url"], item["error"]["code"])
continue
name = re.sub(r"[^a-z0-9]+", "-", item["final_url"].lower()).strip("-")[:120]
(out / f"{name}.md").write_text(item["markdown"], encoding="utf-8")
saved += 1
if job.get("next_cursor"):
cursor, wait = job["next_cursor"], 2
continue
if job["status"] == "done":
return saved
time.sleep(wait)
wait = min(wait * 2, 30)
if __name__ == "__main__":
print(save_job("job_8b27f41c0e"), "pages saved")
Bir tarama hangi sayfaları okur?
Bir tarama URL'nizden başlar ve genişlik öncelikli olarak, max_depth sayısına kadar, her seferinde bir bağlantı adımı dışa doğru ilerler. Ayrıca az sayıda bağlantının işaret ettiği sayfaları bulmak için sitenin sitemap'ini, robots.txt içinde verilen adresten veya /sitemap.xml adresinden okur.
- Yalnızca aynı alan adı. Diğer alan adlarına giden bağlantılar,
include_linksistediğinizde sonuçlarda listelenir ancak okunmaz. - Yol filtreleri.
include_pathsveexclude_paths,/blog/*gibi basit kalıpları alır. - Her sayfa için tek kopya. Bir site canonical URL bildirdiğinde, birden fazla adres üzerinden ulaşılan bir sayfa bir kez okunur.
- Kesin bir durma noktası. İş,
limitsayfa okuduğunda sona erer.
Bir tarama siteye nasıl saygı gösterir?
Her istek WebReaderAPI/1.0 (+https://webreaderapi.com/bot/) User-Agent'ini taşır ve tarayıcı, robots.txt kurallarına WebReaderAPI için veya hiçbiri onu adlandırmıyorsa tüm botlar için uyar. İzin verilmeyen sayfalar atlanır ve results içinde blocked_by_robots hatasıyla görünür; hiçbir ücrete tabi değildir.
robots.txt bir Crawl-delay belirlediğinde, tarayıcı siteye yapılan iki istek arasında bu süre kadar bekler. Bir site robots.txt'inde Content-Signal: ai-input=no bildirirse, sayfalarını sizin için okumayız. Bir site isteğimizi reddederse, verdiği yanıtı döndürürüz: CAPTCHA'ları asla çözmeyiz, hesaplara giriş yapmayız veya bir engeli ya da ödeme duvarını aşmaya çalışmayız.
Bir tarama ne kadar tutar?
Okunan her sayfa, bir /read çağrısının tutacağı kadar tutar: 1 kredi, sayfa bir tarayıcı gerektirdiyse 2, country ile birlikte 10 daha. Atlanan ve başarısız sayfalar ücretsizdir. İşin credits_used değeri, o ana kadar faturalananı toplar.
Tarayıcı olmadan okunan 500 sayfalık bir dokümantasyon sitesi yaklaşık 500 kredi kullanır; 10.000 sayfa paketi ($3,75) bunu çok kez karşılar. v1'de bir iş iptal edilemediğinden limit sizin harcama sınırınızdır: ödemeye hazır olduğunuz en fazla sayfa sayısına ayarlayın.
Batch ve tarama: sık sorulan sorular
/batch mi yoksa birçok /read çağrısı mı kullanmalıyım?
URL'ler zaten elinizdeyse ve her yanıta tek tek ihtiyacınız yoksa /batch kullanın. Bu, eşzamanlılık ve yeniden denemeleri yönetmekten sizi kurtarır. Bir agent'ın şu anda tek bir sayfaya ihtiyacı olduğunda /read kullanın.
İş sonuçları ne kadar saklanır?
Hazır olur olmaz toplayın. Sonuçlar siz onları çekene kadar bekler; teslim edildikten sonra sayfa içeriğinin hiçbir kopyası saklanmaz, bu yüzden ihtiyacınız olanı kendi tarafınızda saklayın.
Bir tarama başka web sitelerine giden bağlantıları takip edebilir mi?
Hayır. Bir tarama tek bir alan adı okur. Diğer alan adları, istediğinizde bağlantı olarak görünür ve okunmalarını istiyorsanız bu URL'leri /batch adresine gönderebilirsiniz.
Başlamış bir taramayı durdurabilir miyim?
v1'de hayır. İş limit sayfada durur, bu yüzden bütçenize uyan bir sınır seçin. Zaten okunan sayfalar faturalanmış kalır; hiç okunmayan sayfalar ücretsizdir.