Lekta HTTP API’si
Üç JSON ucu ve herkese açık bir rozet ucu. Yalnız GET, tek bir statik API anahtarı, sunucudan sunucuya. Denetim eşzamansızdır: başlatırsınız ve aynı adresi yanıt gelene dek yoklarsınız. Rapor JSON’u MCP sunucusunun ve üye web görünümünün döndürdüğüyle bayt bayt aynıdır — tek motor, tek biçim, lekta-score/2026.7.
Kimlik doğrulama
401 · lekta_…Üç JSON ucu da aynı anahtarı alır ve üçü de aynı biçimde okur. İki başlık kabul edilir, şu sırayla bakılır:
- Authorization: Bearer <anahtar>
- x-api-key: <anahtar>
Sunucu, Authorization başlığını startsWith("Bearer ") ile sınar — büyük B, tam bir boşluk. "bearer" diye yazılmış bir başlık eşleşmez ve x-api-key’e düşer; o başlık da yoksa anahtar bozukmuş gibi görünen bir 401 alırsınız. İstemcilerde en sık görülen hata budur. Yalnızca boşluktan oluşan bir x-api-key ise hiç anahtar yok sayılır.
Anahtar biçimi ve saklama
- Anahtar, lekta_ ön ekinin ardından 40 base64url karakterdir — toplam 46 karakter. lekta_ ile başlamayan bir değer veritabanına hiç gidilmeden reddedilir.
- Yalnız anahtarın SHA-256 özeti saklanır, bir de gösterim için ilk 14 karakteri. Ham anahtar üretim anında bir kez gösterilir ve geri getirilemez.
- Hesap başına tek anahtar. Yeni anahtar üretmek özeti ezer ve eskisini anında geçersizleştirir — yaşatma penceresi, kapsam, son kullanma ve ayrı bir iptal yoktur.
- Hiçbir /api/v1 ucunda çerez ya da oturum kimliği yoktur; Turnstile uygulanmaz (anahtar zaten kimliktir) ve hiçbir yerde OAuth yoktur.
Kimlik kapalı düşer
Anahtarın olmaması, bozuk olması, tanınmaması, veritabanının yapılandırılmamış olması ve arama sırasındaki bir veritabanı hatası — hepsi aynı 401’i üretir. Yapılandırılmamış bir arka uç ile bozuk bir anahtar birbirinden ayırt edilemez; 401’i anahtarın yanlış olduğunun kanıtı saymayın.
401 gövdesi, birebir:
{
"error": "invalid_api_key",
"hint": "Authorization: Bearer lekta_... or x-api-key: lekta_... (get a key on /en/panel/api)"
}curl -H "Authorization: Bearer lekta_..." \
"https://lekta.dev/api/v1/me"curl -H "x-api-key: lekta_..." \
"https://lekta.dev/api/v1/me"Uçlar
4Bu dördü, /api altındaki herkese açık HTTP yüzeyinin TAMAMIDIR. Tek diğer makine yüzeyi MCP ucudur; sayfanın sonunda anlatılıyor.
GET /api/v1/me
200 · 401Doğru bağlantı testi budur: anahtarın kime ait olduğunu ve ne kadar kota kaldığını söyler, karşılığında hiçbir şey harcamaz.
Parametre almaz. Sorgu dizesi tamamen yok sayılır.
200 gövdesi:
{
"email": "you@example.com",
"plan": "free",
"quota": {
"perDay": 15,
"usedToday": 3,
"remaining": 12,
"perDomainPerDay": 10
}
}- Anahtar hiçbir biçimde yankılanmaz, ön eki bile. Hesap kimliği, görünen ad ve avatar bilerek verilmez.
- Hiçbir şey harcamaz: denetim başlatmaz, kotadan düşmez, dışarı çıkmaz. İki veritabanı okuması.
- Günlük kota bittikten sonra da 200 dönmeye devam eder. Bu bilinçlidir — bağlantı testi sınırda kırılmamalı.
- Bu uçta hiçbir oran sınırı yoktur. Dakikada bir yoklamak amaçlanan kullanımdır.
- usedToday koşu bittiğinde yazılır, başladığında değil; süren bir denetimin çevresindeki iki hızlı çağrı aynı sayıyı bildirebilir.
- Sayım sorgusu başarısız olursa 0 döner, yani yanıt kotanın tamamı duruyormuş gibi görünür ve bunu belirten bir işaret yoktur. Sessizce iyimserdir.
- Sınırlarınızı sabit yazmak yerine buradan okuyun: plana göre değişir ve dağıtım başına ayarlanabilir.
GET /api/v1/audit
200 · 202 · 400 · 401 · 429Parametreler
url (sorgu). Yokluğu boş girdi gibi davranır ve 400 döner. Okunan tek parametre budur — bilinmeyen sorgu parametreleri yok sayılır. Her şeyden önce normalleştirme koşar:
- Girdinin başı sonu kırpılır. Boş girdi 400’dür.
- Şema yoksa başına https:// eklenir; yani example.com/x kabul edilir.
- URL olarak ayrıştırılabilmeli ve protokol http: ya da https: olmalıdır.
- Ana makine adı bir nokta içermeli ya da tam olarak localhost olmalıdır.
- Parça (#) atılır, ana makine adı küçük harfe çevrilir ve sondaki noktalar silinir; böylece example.com. ile example.com aynı oran sınırı kovasını paylaşır.
- Sorgu dizesi KORUNUR ve sayfa kimliğinin parçasıdır: ?a=1 ile ?a=2 iki ayrı denetimdir — ama oran sınırında aynı ana makine kovasıdır.
- Normalleştirilmiş URL hem önbellek anahtarı, hem oran sınırı anahtarı, hem de report.url olarak geri dönen değerdir.
Yoklama döngüsü
- Anahtarınızla GET /api/v1/audit?url=… çağırın.
- Taze bir hedef 202 {"status":"running","retryAfterSec":5} döner; retry-after başlığı aynı sayıyı taşır.
- AYNI isteği 200 alana dek tekrarlayın.
- 200 size ya {"status":"done","report":…} ya da {"status":"error","error":…} verir.
İş kimliği, durum adresi, geri arama ve webhook YOKTUR. Tutamak normalleştirilmiş URL’dir; aynı URL’yi isteyen ikinci çağıran süren koşuya katılır. Sunucu, koşuyu isteğin içinde bilerek beklemez. Dönen retryAfterSec kadar bekleyip yoklayın ve HTTP istemcinizin zaman aşımını koşunun kendisi için 75 saniyenin üstüne alın.
curl -H "Authorization: Bearer lekta_..." \
"https://lekta.dev/api/v1/audit?url=https://example.com/pricing"Durum kodları
Bu işleyici kendi başına hiç 5xx üretmez. Her yanıt content-type: application/json; charset=utf-8 ve cache-control: no-store taşır.
Dört invalid_url gerekçesi
Bu dizeler her iki dilde de İngilizce ve birebir döner — telde giden metin budur.
Başarı gövdeleri status alanından, hata gövdeleri error alanından dallanır. İkisi asla bir arada gelmez ve ortak bir zarf yoktur. Yalnız HTTP durumuna bakan bir istemci, başarısız bir denetimi başarı sanar; çünkü {"status":"error"} HTTP 200 ile gelir.
Hata nesnesi
- cause: "engine" — mesaj her zaman aynı sabit cümledir. Gerçek hata sunucu günlüğüne yazılır ve asla iletilmez: “The audit could not complete on the server side. Try again in a minute.”
- cause: "timeout" — mesaj motorun kendi metnidir; 75 sn sınırını ve hangi evrede takıldığını söyler (queued, static-fetch, robots, render ya da scoring).
Rapor nesnesi
{"status":"done"} içinde döner. Aynı nesne MCP üzerinden lekta_report’un döndürdüğü ve üye web görünümünün çizdiği nesnedir.
Kontrol nesnesi
Kapalı söz dizileri
Sunucudan asla çıkmayanlar
Tek merkezî bir filtre bu API’ye, MCP sunucusuna ve üye web görünümüne birebir aynı uygulanır. basis.source, basis.url, basis.note ve capSuggestion sunucudan asla çıkmaz: basis yalnız tag ve date taşır. fix metni ise tam gelir.
Hata olmayanlar
Yönlendirme döngüsü, HTTP hatası, engellenmiş bir hedef ya da kimlik isteyen bir hedef yine 200 {"status":"done"} döndürür; raporun notu U, skoru null olabilir. Bu, mutsuz bir hedefin BAŞARILI denetimidir, başarısız bir istek değil.
Bir çağrı ne harcar
Taze bir koşu, web ile ortak günlük havuzdan bir denetim harcar, motoru başlatır ve hedefe ağ üzerinden gider — robots.txt’sine, HTML’ine ve başsız bir çizime. Önbellek isabeti, hata önbelleği isabeti, 401, 400 ve 429 yollarında bunların HİÇBİRİ olmaz; aynı URL’nin tekrarlanan 202 yoklamaları da hiçbir şey eklemez. Kota başlangıçta değil BİTİŞTE sayılır, yani sınıra bir kalmış bir çağıran birden çok koşuyu havada tutabilir.
GET /api/v1/audits
200 · 401Panelde izlediğiniz sitelerdeki not düşüşleri, yeniden eskiye. Dakikada bir yoklanmak üzere tasarlandı; Zapier’in "Grade Dropped" tetikleyicisi tam olarak bunu çağırır. Hiçbir şey harcamaz: kota yok, denetim yok, dış ağ yok, tek veritabanı okuması ve hiç oran sınırı yok.
limit (isteğe bağlı). Yokluğu, sayı olmaması, sıfır ya da negatif olması — hepsi 100’e düşer; kesirler aşağı yuvarlanır, büyük değerler kırpılır. Varsayılan da tavan da 100’tir. İmleç, kaydırma ve since parametresi yoktur. Tek durumlar 200 — boş liste dahil — ve 401’dir.
[
{
"id": 4821,
"url": "https://example.com/pricing",
"prevGrade": "A",
"newGrade": "B",
"prevScore": 92,
"newScore": 78,
"prevEngineVersion": "lekta-score/2026.7",
"engineVersion": "lekta-score/2026.7",
"prevAt": "2026-09-08T09:12:44.000Z",
"at": "2026-09-09T09:14:02.000Z"
}
]200 gövdesi ÇIPLAK bir JSON dizisidir, nesne değil. Bazı istemciler ve şema doğrulayıcılar en üstte nesne bekler; bunu değiştirmek Zapier tetikleyicisini kırardı, o yüzden değişmeyecek. id, YENİ koşunun audits satır kimliğidir: benzersiz, değişmez ve tekilleştirme için amaçlanan anahtar.
İki kez okunmayı hak eden davranışlar
- Yalnız DÜŞÜŞLER görünür ve yalnız birbirini izleyen iki YETKİLİ koşu arasında. Bir koşu, hedef durumu ok ise ve rapor degraded değilse yetkilidir. ok olmayan ve degraded koşular karşılaştırmadan tamamen çıkarılır; yani prevGrade, kelimenin tam anlamıyla önceki satır değil, son GEÇERLİ nottur.
- U bilerek sıralanmaz. U’nun taraflardan birinde olduğu hiçbir geçiş düşüş sayılmaz ve hiç görünmez. Sıra A+ > A > A- > B > C > D > F’dir.
- Yalnız izlenen siteler görünür. Kaydetmediğiniz URL’lerin tek seferlik denetimleri buraya hiç düşmez.
- limit’ten az öğe almanız başka olmadığı anlamına GELMEZ. Uç 500 geçiş okur, düşüşlere süzer, sonra keser. Bundan daha çok yetkili geçişi olan bir hesap eski düşüşleri sessizce kaybeder.
- Veritabanı arızası tam olarak sessizliğe benzer: sorgu kendi istisnasını yutar ve boş dizi döner, yani 200 [] ile bir kesinti birbirinden ayırt edilemez. Yoklamanızı buna göre kurun.
- Listelenen bir düşüşte bile prevScore ve newScore null olabilir.
GET /api/badge/{token}
200 · 404- Herkese açık — anahtar yok. Yoldaki jetonun kendisi tüm yetkidir: site sahibi rozeti gömerek notunu yayımlamayı seçer. Jetonu panelden yenilemek ya da silmek eskisini anında 404 yapar.
- Jeton biçimi 10 ila 64 karakter: A-Z, a-z, 0-9, alt çizgi ve tire. Sorgu parametresi okunmaz.
- 200 image/svg+xml döner — title öğesi olan satır içi bir rozet. Yetkili koşu yoksa "not audited" yazar; varsa notu ve kazanılan puanı gösterir, kısmi kapsamda ölçülebilir toplamı da ekler.
- 404 text/plain ve "not found" gövdesiyle döner: bozuk jeton, tanınmayan jeton ya da yapılandırılmamış veritabanı. 404 gövdeleri JSON DEĞİLDİR — JSON diye ayrıştıran istemci hata fırlatır.
- cache-control: public, max-age=3600. Burada paylaşılan önbelleklerin ve CDN’lerin sunabileceği tek uç budur; yani bir not değişikliği rozete bir saate kadar gecikmeyle yansıyabilir. 404’ler cache-control taşımaz.
- Son YETKİLİ koşuyu gösterir; böylece geçici bir arıza rozeti U’ya düşürmez. Jetonu elinde tutan herkese notu, skoru ve kısmi kapsam puanlarını sızdırır — ama bulguları değil. Bu bilinçlidir.
Hata kodları
5- Hiçbir x-ratelimit-* başlığı yoktur. Tek oran sinyali retry-after’dır ve yalnız 429’larda ve 202’de görünür.
- Sınırlayıcının içeride hesapladığı insan cümleleri JSON’da yer almaz. Yalnız error ve retryAfterSec vardır.
- Arıza davranışı katmana göre değişir ve istemci bunu bilmeli: kimlik KAPALI düşer, 401’e. Kota AÇIK düşer — sayaç okunamazsa kapılar hiç çalışmaz. Kalıcılık açık düşer, yani bir koşu başarılı olup dönebilir ve hiç sayılmamış, hiç listelenmemiş olabilir. Düşüş listesi boş diziye açık düşer.
Sınırlar
3Üç bağımsız katman. Bir çağrının üçünü de geçmesi gerekir.
Hedef ana makine başına — tüm müşteriler için ortak
- Ana makine başına dakikada 1 denetim.
- Ana makine başına kayan saatte 5 denetim.
- Ana makine başına eşzamanlılık 1; biri koşarken gelen ret 15 saniye beklemenizi ister.
- Bu katman denetlenen siteyi korumak için vardır, paket satmak için değil — dolayısıyla aynı ana makineyi denetleyen BAŞKA bir müşteri size 429 aldırabilir.
- Yoklamayı mümkün kılan istisna: tam o normalleştirilmiş URL zaten havadaysa sınırlayıcı sizi geçirir. Koşu sürerken aynı ana makinedeki FARKLI bir URL yine reddedilir.
Hesap başına, günlük
- Ücretsiz: günde 15 denetim, alan adı başına 10. Pro: günde 500, alan adı başına 200.
- API günlük havuzu web sitesiyle ORTAKTIR. Tarayıcıda başlattığınız bir denetim, o gün API’nin yapabileceğini azaltır.
- Sayaç 00:00 UTC’de sıfırlanır.
MCP — ayrı havuz
- Ücretsiz: 1 site üzerinde günde 10 taze denetim. Pro: 50 site üzerinde günde 200.
- Önbellekten okuma, diff ve düzeltme planı ücretsizdir.
- İki havuz birbirini tüketmez.
Sonuç önbelleği, hata önbelleği, havadaki işler haritası ve hedef bazlı sınırlayıcı — dördü de web sürecinin BELLEĞİNDE yaşar. Yeniden başlatmayı ya da dağıtımı atlatamazlar ve örnekler arasında paylaşılmazlar. Bu sayfadaki her önbellek ve oran sınırı penceresi tek bir sürecin elinden gelenin en iyisidir, dağıtık bir garanti değil. Denetim başına sert süre sınırı 75 saniyedir. Bunların hepsi dağıtım başına ayarlanabilir; kendi sınırlarınızın yetkili kaynağı GET /api/v1/me’dir.
Önbellek ve tazelik
15 min · 60 s- Rapor önbelleği 15 dakika, hata önbelleği 60 saniye; ikisi de normalleştirilmiş URL ile anahtarlanır ve 500 girdiden sonra en eski atılır.
- Önbellek isabeti bedavadır: kota yok, oran sınırı yok, ağ yok.
- HTTP düzeyinde her JSON yanıtı cache-control: no-store taşır. Pencere yalnız SUNUCU tarafı tekilleştirme penceresidir; aşağı tarafta hiçbir şey önbelleklenmez.
- Bir kural çökerken üretilen degraded rapor saklanır ama ASLA servis edilmez. Sonraki çağrı taze koşu başlatır.
- JSON’daki tüm zaman damgaları ISO 8601 UTC’dir ve sonunda Z taşır.
Diğer makine yüzeyleri
/mcphttps://lekta.dev/mcp adresinde, JSON-RPC 2.0 konuşan durumsuz bir streamable-HTTP MCP ucu. initialize, ping ve tools/list anahtar istemez; tools/call aynı anahtarı aynı iki başlık yazımıyla alır. Beş araç:
- Hiç anahtar göndermemek 401 değil, araç düzeyinde hatayla HTTP 200 döndürür. 401, MCP istemcilerini onları çökerten bir OAuth keşif akışına sokuyordu. Var olan ama geçersiz bir anahtar ise gerçek bir 401 alır.
- CORS asimetriktir: /mcp OPTIONS’a yanıt verir ve access-control-allow-origin: * gönderir. /api/v1/* hiç CORS başlığı göndermez ve OPTIONS işleyicisi yoktur — sunucudan sunucuyadır, tarayıcıdan çapraz köken çağrıları çalışmaz.
- /api/ ve /mcp dil ön eki ara katmanının DIŞINDADIR. API çağıranların yerel ön ekine ihtiyacı yoktur ve ona uymamalıdırlar; API yanıtları content-security-policy başlığı taşımaz ve dil çerezi kurmaz.
/api/v1/* uçlarını tarayıcıdan çağırmayın. CORS başlığı yoktur, üstelik anahtarınız sayfanın içinde olurdu.
Kapsam, kararlılık ve iletişim
lekta-score/2026.7Bunlar ÜRETİM uçlarıdır. https://lekta.dev tek ortamdır: kum havuzu, hazırlık ortamı ya da ayrı bir geliştirici sunucusu yoktur. Test hesabı gerçek URL’leri denetler ve gerçek kota harcar.
API, istek zincirinde hiçbir üçüncü taraf satıcı API’si çağırmaz. Bir koşu yalnız sizin verdiğiniz hedef URL’yi çeker — robots.txt’sini ve HTML’ini, kendini LektaBot olarak tanıtarak — başka hiçbir şeyi değil.
Zapier entegrasyonumuz da tam bu uçları kullanır: "Grade Dropped" tetikleyicisi /api/v1/audits adresini yoklar ve id üzerinden tekilleştirir, "Audit a URL" eylemi /api/v1/audit adresini çağırır ve günlük kotadan düşer, bağlantı testi ise /api/v1/me’yi çağırır.
Yalnız GET. Yanıtlara yeni alanlar habersiz eklenebilir, bu yüzden hoşgörülü ayrıştırın. Kaldırmalar ve biçim değişiklikleri değişiklik günlüğünde duyurulur; skoru etkileyen her motor değişikliği ölçülmüş bir kayma tablosuyla yayımlanır.