API Platformu
On-Page API
Tek bir sayfayı Google'ın ve bir tarayıcının gördüğü gibi kontrol edin — Lighthouse skorları ve Core Web Vitals, sayfa içi SEO denetimi ya da ana içeriği metin ve Markdown olarak — istek başına sabit ücretle.
Tek bir sayfayı kontrol edin. Tek bir endpoint, type parametresiyle seçilen üç rapor sunar: tam bir Lighthouse çalıştırması (performans, erişilebilirlik, en iyi uygulamalar ve SEO skorları, Core Web Vitals ve geçemeyen tüm kontroller), hızlı bir sayfa içi SEO denetimi (başlık, açıklama, heading'ler, içerik, linkler, boyut, yüklenme süresi ve bulunan sorunlar) ve sayfanın ana içeriği; bölümlere ayrılmış olarak ve Markdown biçiminde.
60 saniyeden uzun süren istekler
Bu endpoint istekleri her zaman task olarak çalıştırır. 60 saniyeden uzun süren istekler (yavaş bir sayfada Lighthouse bu kadar sürebilir) task_id içeren bir 202 döndürür; sonucu GET /v1/tasks/{task_id} ile alırsınız. Normal 200 dahil her response, task id'yi X-Task-Id header'ında taşır. İsteğin ne kadar bekleyeceğini ?wait= ile değiştirebilir, Idempotency-Key header'ıyla güvenle tekrar deneyebilirsiniz.
Kimlik Doğrulama
| Header | Tip | Açıklama |
|---|---|---|
SEMUST-API-USER | string | API kullanıcınızın kullanıcı adı |
SEMUST-API-PASSWORD | string | API kullanıcınızın şifresi |
Accept-Language | string | İsteğe bağlı. Hata mesajlarını Türkçe almak için tr gönderin |
API kimlik bilgilerinizi API Erişimi sayfasından oluşturun.
SEMUST-API-USER: kullanici_adiniz
SEMUST-API-PASSWORD: sifreniz
Content-Type: application/jsonRapor Tipleri
type | Döndürdüğü | Tipik süre | Ücret |
|---|---|---|---|
lighthouse (varsayılan) | Lighthouse kategori skorları, Core Web Vitals ve geçemeyen kontroller; mobil ya da masaüstü | 10–30 sn | $0.0055 |
audit | Sayfa içi SEO denetimi: başlık, açıklama, heading'ler, kelime sayısı, linkler, boyut, yüklenme süresi ve bulunan sorunlar | ~1 sn (JavaScript ile ~3 sn) | $0.000165 (JavaScript ile $0.00165) |
content | Sayfanın ana içeriği bölümler hâlinde (başlık + metin), bulunan iletişim bilgileri ve istenirse sayfanın tamamı Markdown olarak | ~1 sn | $0.000165 |
Ücret istek başınadır; cihaza, kategorilere ya da Markdown'a göre değişmez. Kontrol edilemeyen bir sayfa (engellenmiş, bulunamayan ya da erişilemeyen) hata döndürür ve ücretlendirilmez (bkz. Hatalar).
{
"type": "lighthouse",
"url": "https://www.python.org/",
"device": "mobile"
}{
"type": "audit",
"url": "https://www.python.org/",
"javascript": true
}{
"type": "content",
"url": "https://www.python.org/",
"markdown": true
}İstek Parametreleri
Seçilen type için geçerli olmayan bir parametre yok sayılmaz, reddedilir; yanlış yazılmış bir parametre hata mesajında öneriyle birlikte belirtilir. JSON null "gönderilmedi" sayılır.
Body
typestringdefault: lighthouselighthouse, audit ya da content.
urlstringZorunlu. Kontrol edilecek sayfa: alan adı içeren, en fazla 2048 karakterlik bir http veya https adresi. Şema yazılmazsa https:// varsayılır. localhost, IP adresleri ve başka şemalar reddedilir (INVALID_URL). Yönlendirmeler izlenir ve son adres döndürülür.
devicestringdefault: mobileYalnızca lighthouse. mobile (PageSpeed Insights'ın test ettiği gibi, yavaşlatılmış bağlantıda orta seviye bir telefon) ya da desktop.
categoriesstring[]Yalnızca lighthouse. performance, accessibility, best_practices, seo değerlerinden herhangi biri; varsayılan dördü birden. Ücret aynıdır; daha azını istemek yalnızca yanıtı kısaltır. metrics yalnızca performance ile döner.
languagestringdefault: enYalnızca lighthouse. Denetim başlıklarının, açıklamalarının ve gösterilen değerlerin dili, ör. tr. Desteklenen diller: GET /v1/on-page/languages.
javascriptbooleandefault: falseYalnızca audit. İçeriğini tarayıcıda oluşturan sayfalar için, denetimden önce sayfayı JavaScript çalıştırarak tarayıcıda açar. Ücreti on katıdır.
markdownbooleandefault: falseYalnızca content. Sayfanın tamamını ayrıca Markdown olarak data.markdown içinde döndürür. Ücret aynıdır.
idempotency_keystringİsteğe bağlı, en fazla 128 karakter. Aynı anahtarla tekrarlanan istek aynı task'ı döndürür — çalışırken 202'sini, bittiğinde saklanan sonucunu — ve bir kez ücretlendirilir. Anahtar, task bittikten sonra 72 saat boyunca ayrılmış kalır. Idempotency-Key header'ıyla aynıdır; ikisini birden gönderirseniz bu alan geçerli olur.
Query
waitintegerdefault: 60Sonucun kaç saniye bekleneceği, 0–80. İstek bu sürenin sonunda hâlâ çalışıyorsa yanıt task_id içeren bir 202 olur. 0 hemen 202 döndürür.
Headers
Idempotency-Keystringİsteğe bağlı. Yukarıdaki idempotency_key gibi çalışır; ikisini birden gönderirseniz body alanı geçerli olur.
GET /v1/on-page/languages, Lighthouse'un sonuçlarını yazabildiği dilleri listeler. Ücretsizdir.
60 saniye sonunda hâlâ çalışan bir istek 202 döndürür. Task'lar ve Uzun Süren İstekler sayfasındaki call() yardımcısı sonuç hazır olana kadar sorgular.
curl -X POST https://data.semust.com/v1/on-page \
-H "SEMUST-API-USER: kullanici_adiniz" \
-H "SEMUST-API-PASSWORD: sifreniz" \
-H "Content-Type: application/json" \
-d '{"type": "lighthouse", "url": "https://www.python.org/", "device": "mobile", "language": "tr"}'import requests
response = requests.post(
"https://data.semust.com/v1/on-page",
headers={
"SEMUST-API-USER": "kullanici_adiniz",
"SEMUST-API-PASSWORD": "sifreniz",
"Accept-Language": "tr",
},
json={"type": "lighthouse", "url": "https://www.python.org/", "language": "tr"},
timeout=90, # ?wait= süresinden uzun (varsayılan 60 saniye)
)
data = response.json()
if response.status_code == 202:
# Hâlâ çalışıyor. Sonucu daha sonra data["poll_url"] adresinden alın
# ya da Task'lar sayfasındaki call() yardımcısını kullanın.
raise SystemExit(f"Task {data['task_id']} hâlâ çalışıyor")
if response.status_code != 200:
# PAGE_BLOCKED / PAGE_UNAVAILABLE: sayfa kontrol edilemedi (ücret alınmadı)
raise SystemExit(f"{data['code']}: {data['error']} {data.get('hint', '')}")
print(data["data"]["scores"])
for audit in data["data"]["failed_audits"]:
print(audit["category"], audit["title"], audit["display_value"])Response
Her rapor, isteği çalıştığı hâliyle — type, normalleştirilmiş url ve o tipe uygulanan seçenekler — ve sonucu tek bir data nesnesinde döndürür.
lighthouse skorları PageSpeed Insights'taki gibi 0–100 arasıdır; istemediğiniz bir kategori null olur. metrics bu çalıştırmanın laboratuvar ölçümleridir. failed_audits, geçemeyen tüm puanlı kontrolleri rapor sırasındaki kategorilere göre gruplar; bir kategori içinde tahmini kazancı en büyük olan önce gelir. Başlıklar ve açıklamalar language dilindedir. Her Lighthouse aracında olduğu gibi laboratuvar sonuçları çalıştırmadan çalıştırmaya biraz değişir.
audit, sayfanın kendi SEO'su hakkında söylediklerini döndürür; issues bulunan sorunları adlarıyla listeler (aşağıdaki listeye bakın). Boş liste, sorun bulunmadığı anlamına gelir.
content, sayfanın ana içeriğini sections içinde, onun dışında kalan her şeyi — menü, kenar çubukları, ilgili bloklar — secondary_sections içinde döndürür.
Aşağıdaki örnekler gerçek yanıtlardır (Lighthouse örneği "language": "tr" ile çalıştırıldı; açıklamalar kısaltıldı).
{
"success": true,
"type": "lighthouse",
"url": "https://www.python.org/",
"device": "desktop",
"categories": ["performance", "accessibility", "best_practices", "seo"],
"language": "tr",
"data": {
"final_url": "https://www.python.org/",
"lighthouse_version": "13.4.0",
"fetched_at": "2026-11-07T03:08:11Z",
"scores": { "performance": 94, "accessibility": 79, "best_practices": 100, "seo": 92 },
"metrics": {
"first_contentful_paint_ms": 641,
"largest_contentful_paint_ms": 1085,
"total_blocking_time_ms": 0,
"cumulative_layout_shift": 0.122,
"speed_index_ms": 641,
"time_to_interactive_ms": 1085
},
"failed_audits": [
{
"id": "render-blocking-insight",
"category": "performance",
"title": "Oluşturma engelleme istekleri",
"description": "İstekler sayfanın ilk oluşturma işlemini engelliyor…",
"score": 0,
"display_value": "Tahmini tasarruf: 370 ms.",
"savings_ms": 350,
"savings_bytes": null
},
{
"id": "unused-css-rules",
"category": "performance",
"title": "Kullanılmayan CSS'yi azaltın",
"description": "Ağ etkinliğinin kullandığı bayt sayısını azaltmak üzere…",
"score": 0,
"display_value": "Tahmini tasarruf: 125 KiB",
"savings_ms": 120,
"savings_bytes": 128464
},
{
"id": "color-contrast",
"category": "accessibility",
"title": "Arka plan ve ön plan renkleri yeterli kontrast oranına sahip değil.",
"description": "Birçok kullanıcı, düşük kontrastlı metni okumakta zorlanır…",
"score": 0,
"display_value": null,
"savings_ms": null,
"savings_bytes": null
}
],
"passed_count": 53,
"failed_count": 18,
"warnings": []
},
"cost": 0.0055,
"cached": false,
"request_id": "0b7e6f1a-3c2d-4e5f-9a8b-1c2d3e4f5a6b"
}{
"success": true,
"type": "audit",
"url": "https://www.python.org/",
"javascript": true,
"data": {
"final_url": "https://www.python.org/",
"status_code": 200,
"score": 98.17,
"title": "Welcome to Python.org",
"description": "The official home of the Python Programming Language",
"canonical": null,
"h1": ["Functions Defined", "All the Flow You’d Expect", "Compound Data Types"],
"headings": { "h1": 5, "h2": 9, "h3": 0, "h4": 0, "h5": 0, "h6": 0 },
"word_count": 537,
"readability": 56.6,
"links": { "internal": 66, "external": 67 },
"images": 1,
"scripts": 7,
"stylesheets": 0,
"size_bytes": 53822,
"transfer_bytes": 11718,
"load_time_ms": 173,
"timing": {
"connect_ms": 20,
"waiting_ms": 11,
"download_ms": 1,
"dom_complete_ms": 172,
"time_to_interactive_ms": 156
},
"issues": ["title_too_short", "render_blocking_resources", "low_content_rate", "no_image_title"],
"fetched_at": "2026-11-07T03:07:49Z"
},
"cost": 0.00165,
"cached": false,
"request_id": "5d4c3b2a-1f0e-4d9c-8b7a-6f5e4d3c2b1a"
}{
"success": true,
"type": "content",
"url": "https://www.python.org/",
"markdown": true,
"data": {
"title": "Functions Defined",
"language": "en",
"sections": [
{
"level": 1,
"heading": "Functions Defined",
"text": "The core of extensible programming is defining functions.\nPython allows mandatory and optional arguments, keyword arguments,\nand even arbitrary argument lists. More about defining functions"
}
],
"secondary_sections": [
{ "level": 2, "heading": "Latest News", "text": "More news" }
],
"word_count": 286,
"contacts": { "emails": [], "phones": [] },
"markdown": "# Functions Defined\n## >>> Python Software Foundation\n\n…"
},
"cost": 0.000165,
"cached": false,
"request_id": "9a8b7c6d-5e4f-4a3b-2c1d-0e9f8a7b6c5d"
}Yanıt Alanları Referansı
Zarf
| Alan | Tip | Açıklama |
|---|---|---|
url | string | Kontrol edilen adres: şema ve host küçük harfle, host ASCII (punycode) biçiminde, #fragment olmadan |
device, categories, language | string, string[], string | Yalnızca lighthouse. Çalıştırmanın kullandığı seçenekler, varsayılanlar doldurulmuş olarak |
javascript | boolean | Yalnızca audit. Sayfanın JavaScript ile açılıp açılmadığı; ücreti belirler |
markdown | boolean | Yalnızca content. Markdown istenip istenmediği |
lighthouse → data
| Alan | Tip | Açıklama |
|---|---|---|
final_url | string | Yönlendirmelerden sonra sayfanın vardığı adres |
lighthouse_version, fetched_at | string, string | null | Lighthouse sürümü ve sayfanın yüklendiği an (ISO 8601, UTC) |
scores | object | performance, accessibility, best_practices, seo: 0–100; istenmediyse null |
metrics | object | null | Milisaniye cinsinden laboratuvar değerleri — first_contentful_paint_ms, largest_contentful_paint_ms, total_blocking_time_ms, speed_index_ms, time_to_interactive_ms — ve birimsiz cumulative_layout_shift. performance istenmediyse null |
failed_audits | object[] | id (Lighthouse'un denetim kimliği), category, title, description ("daha fazla bilgi" linkli Markdown), 0–100 score, display_value, savings_ms ve savings_bytes (tahmini kazanç; uygulanamıyorsa null) |
passed_count, failed_count | integer | İstenen kategorilerde geçen ve geçemeyen puanlı kontrol sayısı |
warnings | string[] | Lighthouse'un çalıştırmayla ilgili kendi notları; ör. bir yönlendirme ya da yavaş yüklenen sayfa |
audit → data
| Alan | Tip | Açıklama |
|---|---|---|
final_url, status_code | string, integer | Yönlendirmelerden sonra yanıt veren adres ve HTTP durum kodu |
score | number | null | 0–100 sayfa içi skor: sayfanın geçtiği kontrollerin ağırlıklı oranı |
title, description, canonical | string | null | Sayfanın <title> etiketi, meta açıklaması ve canonical linki |
h1, headings | string[], object | H1 metinleri ve h1…h6 her seviyedeki heading sayısı |
word_count, readability | integer | null, number | null | Görünür metindeki kelime sayısı ve Flesch okunabilirlik skoru (0–100, yüksek olan daha kolay; İngilizceye göre ayarlıdır) |
links | object | internal (iç) ve external (dış) link sayıları |
images, scripts, stylesheets | integer | null | Sayfadaki sayılar |
size_bytes, transfer_bytes | integer | null | HTML boyutu ve aktarılan (sıkıştırılmış) bayt |
load_time_ms, timing | integer | null, object | Toplam yüklenme süresi ve parçaları: connect_ms, waiting_ms (ilk bayta kadar geçen süre), download_ms, dom_complete_ms, time_to_interactive_ms |
issues | string[] | Bulunan sorunlar, aşağıdaki listeden |
fetched_at | string | null | Sayfanın alındığı an (ISO 8601, UTC) |
issues değerleri: no_https, https_to_http_links, no_title, title_too_long, title_too_short, multiple_title_tags, irrelevant_title, no_description, irrelevant_description, irrelevant_meta_keywords, no_h1_tag, duplicate_meta_tags, not_canonical (canonical link başka bir sayfayı gösteriyor), seo_unfriendly_url, no_doctype, no_encoding_meta_tag, charset_mismatch, meta_refresh_redirect, render_blocking_resources, high_loading_time, high_waiting_time, no_content_encoding, page_over_3mb, large_page_size, small_page_size, low_content_rate, high_content_rate, low_character_count, high_character_count, low_readability_rate, no_image_alt, no_image_title, no_favicon, structured_data_errors, deprecated_html_tags, uses_flash, uses_frames, lorem_ipsum, broken_links, broken_resources.
content → data
| Alan | Tip | Açıklama |
|---|---|---|
title | string | null | İçeriğe göre sayfanın ana başlığı |
language | string | null | İçeriğin dili, ör. tr |
sections, secondary_sections | object[] | level (heading seviyesi), heading ve text (paragraflar satır sonuyla ayrılır). sections ana içeriktir; secondary_sections onu çevreleyen kısımlardır |
word_count | integer | sections içindeki kelime sayısı |
contacts | object | Sayfada bulunan emails (e-posta) ve phones (telefon) |
markdown | string | null | "markdown": true ise sayfanın tamamı Markdown olarak, aksi hâlde null |
Hatalar
Her hata sabit bir code, okunabilir bir error ve retryable içerir; faydalı olduğunda ayrıca field, hint ve allowed. Türkçe mesajlar için Accept-Language: tr gönderin. Bir hata için asla ücret alınmaz. Diğer API'lerle ortak tam liste Hata Kodları sayfasındadır. Bu endpoint'e özgü olanlar:
| Durum | Kod | Anlamı | Ne yapmalı |
|---|---|---|---|
| 202 | — | Hata değil: istek wait saniye sonunda hâlâ çalışıyor | GET /v1/tasks/{task_id} ile sorgulayın; bkz. Task'lar |
| 400 | URL_REQUIRED | url yok | Kontrol edilecek sayfayı gönderin |
| 400 | INVALID_URL | Herkese açık bir http/https adresi değil: başka bir şema, localhost, IP adresi ya da noktasız bir ad | Alan adı içeren bir URL gönderin |
| 400 | INVALID_PARAMETER | ör. bilinmeyen bir device, categories değeri ya da language; field hangisi olduğunu söyler, allowed geçerli değerleri listeler | Alanı düzeltin |
| 422 | PAGE_BLOCKED | Site isteği reddetti (HTTP 401, 403 ya da 429); genellikle Cloudflare gibi bir bot koruması. Durum kodu mesajdadır. Ücret alınmaz | Sayfa için otomatik kontrollere izin verin ya da başka bir sayfa kontrol edin |
| 422 | PAGE_UNAVAILABLE | Sayfa yüklenemedi: bir hata durum koduyla yanıt verdi (ipucunda, ör. HTTP 404), host çözümlenemedi ya da yanıt vermedi veya sayfanın okunabilir içeriği yok. Ücret alınmaz | Adresi kontrol edin; tekrar denemenin işe yarayabileceği durumlarda retryable true olur |
Engellenen bir sayfa neden sonuç değil de hata: Lighthouse eline geçen sayfayı puanlar. Bot korumasının arkasında bu, doğrulama (challenge) sayfasıdır ve onun için verilen "SEO 40" siteniz hakkında hiçbir şey söylemez. Headless tarayıcıları engelleyen siteler çoğu zaman düz bir isteğe yine de yanıt verir; bu yüzden lighthouse'un çalışmadığı yerde javascript olmadan audit çalışabilir.
{
"error": "Site isteği reddetti (HTTP 403)",
"code": "PAGE_BLOCKED",
"field": "url",
"hint": "Cloudflare gibi bot korumaları otomatik kontrolleri sıklıkla engeller. Bu kontrol için korumayı açın ya da başka bir sayfa deneyin. Ücret alınmadı",
"retryable": false,
"request_id": "3f2b1c4d-0000-4000-8000-000000000001"
}{
"error": "Sayfa yüklenemedi",
"code": "PAGE_UNAVAILABLE",
"field": "url",
"hint": "Sayfa HTTP 404 döndürdü. Ücret alınmadı",
"retryable": false,
"request_id": "3f2b1c4d-0000-4000-8000-000000000002"
}Krediler ve Sınırlar
| İstek | Ücret |
|---|---|
lighthouse | $0.0055 |
audit | $0.000165 |
"javascript": true ile audit | $0.00165 |
content (Markdown'lı ya da Markdown'sız) | $0.000165 |
Kontrol edilemeyen bir sayfa (PAGE_BLOCKED, PAGE_UNAVAILABLE) ücretlendirilmez.
Sonuçlar 15 dakika önbellekte tutulur; böylece yeni düzelttiğiniz bir sayfa kısa sürede yeniden kontrol edilir. Önbellekten dönen yanıt "cached": true ile işaretlenir ve canlı yanıtla aynı ücreti öder.
Dakikalık ve günlük sınırlar hesabınızda tanımlıdır (429 RATE_LIMIT_EXCEEDED). API kullanıcısı başına aynı anda en fazla 5 istek çalışır; fazlası Retry-After ile 429 TOO_MANY_CONCURRENT_REQUESTS alır. 202 dönmüş bir istek, task'ı bitene kadar yerini korur. API kullanıcısı başına aynı anda en fazla 100 task bitmemiş durumda olabilir (429 TOO_MANY_PENDING_TASKS). Sorgulamanın kendi limiti vardır ve bunların hiçbirine sayılmaz; bkz. Task'lar.
