API Endpoint Nasıl Test Edilir: DNS, TLS, Başlık ve CORS
Önemli bilgi
"API çöktü" neredeyse hiçbir zaman tek bir sorun değildir. Altı katmanda test edin (DNS, 443 portu, TLS, HTTP durumu, CORS, payload) ve ilk başarısız olan katmanda durun. Tipik suçlular: hiç yayılmamış bir DNS kaydı, gece süresi dolan bir sertifika veya curl sorunsuz çalışırken tarayıcı çağrılarını bozan eksik bir Access-Control-Allow-Origin başlığı.
Şimdi kontrol edin

Okumaya başlayın
- "API çöktü" neden hiçbir zaman tek bir sorun değildir
- Rahatça deneyebileceğiniz gerçek bir endpoint seçin
- Katman 1: Ana bilgisayar adı çözümleniyor mu?
- Katman 2: 443 portu açık mı?
- Katman 3: TLS sertifikası geçerli mi?
- Katman 4: Yanıt başlıklarını okuyun
- Sağlıklı bir JSON yanıtı nasıl görünür
- Katman 5: Yalnızca tarayıcı çağrılarını bozan başlık
- Preflight tuzağı: Başlık ekleyene kadar çalışır
- Katman 6: Payload beklediğiniz biçimde mi?
- Belirti → katman → araç
- Sıkça Sorulan Sorular
"API çöktü" neden hiçbir zaman tek bir sorun değildir
Bir API çağrısı başarısız olduğunda, istemcinizin gösterdiği hata genellikle gerçekte bozulan şeyin birkaç katman üstünde üretilir. Failed to fetch bildiren bir tarayıcı, ana bilgisayar adının çözümlenmediğini, TCP bağlantısının reddedildiğini, TLS el sıkışmasının reddedildiğini ya da sunucunun gayet sağlıklı bir 200 döndürdüğünü ama tarayıcının eksik bir CORS başlığı yüzünden onu attığını söyleyemez. Dört durum da aynı mesajı üretir.
Çözüm tahmin etmeyi bırakıp yığını sırayla yürümektir. Her katman ancak altındaki başarılıysa anlamlıdır, bu yüzden başarısız olan ilk katman gerçek hatanızdır; sonrasındaki her şey gürültüdür.
Kontrol etmeye değer altı katman var ve hepsi birlikte yaklaşık iki dakika sürer:
- DNS: ana bilgisayar adı bir IP'ye çözümleniyor mu?
- 443 portu: dinleyen bir şey var mı, yoksa bağlantı reddediliyor veya filtreleniyor mu?
- TLS: sertifika geçerli, süresi dolmamış ve tam zincirle mi sunuluyor?
- HTTP durumu: sunucu gerçekte ne döndürüyor: 200, 401, 429, 503?
- CORS: yanıt, tarayıcının gövdeyi size vermesi için gereken başlıkları taşıyor mu?
- Payload: JSON, kodunuzun beklediği biçimde mi?
Bir endpoint'in durumunu ve başlıklarını şimdi kontrol edin
Rahatça deneyebileceğiniz gerçek bir endpoint seçin
Uygulamak için gerçek veri döndüren, API anahtarı gerektirmeyen ve aynı isteği yirmi kez çalıştırdığınız için sizi sınırlamayacak canlı bir endpoint gerekir. Bu, bariz adayların çoğunu eler: neredeyse her yaygın herkese açık API artık sizi bir kayıt formu ve bir token arkasına alıyor; yani başarısız bir istek, test ettiğiniz katman yerine hep kimlik bilgilerinizden kaynaklanıyor olabilir.
Aşağıdaki örnekler, 100'den fazla ülkede 60.000'den fazla yeri kapsayan Arapça bir namaz vakti servisi olan Waqt Azan (مواقيت الصلاة) sitesinin ücretsiz namaz vakti API'sini kullanır. Öğretici bir endpoint olarak üç nedenle iyi çalışır: anahtar ve kimlik doğrulama başlığı yoktur, HTML yerine yapılandırılmış JSON döndürür ve izin verici bir CORS politikası belirler. Böylece curl komutları olduğu gibi çalışır, fetch() örneği de katı bir Content-Security-Policy olmayan bir sayfanın konsolunda çalışır.
Endpoint, ülke ve şehir slug'ını doğrudan yolda alır:
# Prayer times for a city — no API key, no headers required
curl -s https://waqtazan.com/api/v1/timings/saudi-arabia/riyadh
# The same data as a subscribable calendar feed
curl -s https://waqtazan.com/api/v1/ical/saudi-arabia/riyadh.icsGerçekten hata ayıkladığınız ana bilgisayarla değiştirin: ister herkese açık bir API, ister kendi staging sunucunuz, ister üçüncü taraf bir webhook alıcısı test edin, altı katman aynıdır.
Katman 1: Ana bilgisayar adı çözümleniyor mu?
DNS sık görülen bir suçludur. Bir kayıt değiştirildi ve yayılmadı, bir wildcard kaldırıldı ya da API hiç oluşturulmamış bir alt alan adında duruyor.
Her şeyden önce ana bilgisayar adını çözümleyin. Bu adım hiçbir şey döndürmüyorsa uygulamanızı yeniden başlatmak işe yaramaz: istemciniz bir soket açacak kadar bile ilerleyemez.
dig +short waqtazan.com A
nslookup waqtazan.com
# Compare what different resolvers see — catches mid-propagation records
dig +short waqtazan.com A @1.1.1.1
dig +short waqtazan.com A @8.8.8.8Bir kaydı değiştirdikten hemen sonra iki herkese açık çözümleyici birbirinden farklı yanıt veriyorsa kayıt hâlâ yayılıyordur ve API, her istemcinin hangi çözümleyiciye düştüğüne bağlı olarak aralıklı bozuk görünür (coğrafi yönlendirme yapan bir CDN her çözümleyiciye sürekli farklı bir adres verebilir, bu yüzden ayarladığınız kayıtla karşılaştırın). Tüm kayıt kümesini görmek için bir DNS sorgusu yapın ya da bir kaydı değiştirdikten hemen sonra küresel çözümleyicilerde yayılmayı DNS yayılma denetleyicisi ile kontrol edin.
Burada boş bir yanıt, Chrome'da doğrudan ERR_NAME_NOT_RESOLVED ve Node'da getaddrinfo ENOTFOUND hatasına karşılık gelir: tam çözüm listesi için ERR_NAME_NOT_RESOLVED yazısına bakın.
Endişelenmemeniz gereken bir şey: birçok API bir CDN'in arkasındadır, bu yüzden A kaydı kaynak sunucuyu değil bir CDN uç noktasını gösterir. Bu beklenen bir durumdur. Önemli olan hangi IP'nin geldiği değil, bir yanıt alıp almadığınızdır.
Katman 2: 443 portu açık mı?
Ana bilgisayar adı çözümleniyor, yani bir adres var. Şimdi üzerinde bir şeyin dinleyip dinlemediğini öğrenin. İstemcilerin aynı şekilde bildirmeyi sevdiği üç çok farklı arızayı burada ayırırsınız:
- Açık: TCP el sıkışması tamamlanır. Sonraki katmana geçin.
- Reddedildi: ana bilgisayar anında bir RST ile yanıt verdi. Orada bir şey var ama o porta bağlı hiçbir şey yok; genellikle servis çökmüştür veya yalnızca localhost'ta dinliyordur.
- Filtreleniyor: bağlantı zaman aşımına kadar takılı kalır. Bir güvenlik duvarı ya da güvenlik grubu paketleri sessizce düşürür; isteğiniz bu yüzden başarısız olmadan önce bir dakika veya daha fazla bekler (macOS'ta 75 saniye).
# Time-boxed TCP check: -w limits the connect on Linux; on macOS use -G 5 instead
nc -vz -w 5 waqtazan.com 443
# Or with curl: --connect-timeout caps the connect; 000 means no response came back
curl -s -o /dev/null -w '%{http_code}\n' --connect-timeout 5 https://waqtazan.com/Reddedilen ve filtrelenen bir bağlantı tamamen farklı çözümler gerektirir, bu yüzden hangisine sahip olduğunuzu bilmek değerlidir. Port denetleyicisi ikisini ayırt eder ve ağınızın dışından test eder; bu önemlidir, çünkü ofis VPN'inizden açık görünen bir port, herkese açık internetten güvenlik duvarıyla kapalı olabilir.
curl durum kodu olarak 000 yazdırıyorsa hiçbir HTTP yanıtı gelmemiştir. Genellikle istek 1–3. katmanlarda başarısız olmuştur (DNS yanıtı yok, reddedilen veya filtrelenen port, başarısız TLS el sıkışması), ancak bağlantıyı kabul edip sonra kapatan ya da hiç yanıt vermeyen bir sunucu da 000 verir; çalışan son adımı görmek için -v ekleyin. Reddedilme durumunu ayrıntılı olarak ERR_CONNECTION_REFUSED yazısı anlatır.
Katman 3: TLS sertifikası geçerli mi?
443 portu açık ama açık bir port çalışan bir HTTPS endpoint'i demek değildir. Sertifikalar klasik bir gece arızasıdır, çünkü belirli bir tarihte sona erer ve yenileme otomasyonu sessizce başarısız olur.
Sertifikanın aynı anda üç şartı sağlaması gerekir: süresi dolmamış olmalı, adı istediğiniz ana bilgisayar adıyla eşleşmeli ve sunucu tam ara sertifika zincirini göndermeli. Üçüncüsü sinsi olandır: eksik bir zincir tarayıcılarda çoğu zaman çalışır, çünkü Chrome eksik ara sertifikayı kendisi indirir ve Firefox ara sertifikaları önceden yükler; oysa Node, Python, Java ve OpenSSL tabanlı curl derlemeleri başarısız olur (macOS ile gelen curl Apple'ın doğrulayıcısını kullanır ve geçebilir). Klasik "tarayıcımda çalışıyor ama production'da çalışmıyor" hata raporunun kaynağı budur.
# Expiry dates and subject
echo | openssl s_client -connect waqtazan.com:443 -servername waqtazan.com 2>/dev/null \
| openssl x509 -noout -subject -dates
# Full chain as presented by the server
openssl s_client -connect waqtazan.com:443 -servername waqtazan.com -showcerts < /dev/null-showcerts çıktısındaki sertifikaları sayın. Tek başına bir sertifika genellikle eksik bir ara sertifika anlamına gelir. SSL sertifika denetleyicisi sona erme tarihini, zincirin eksiksizliğini ve ana bilgisayar adı eşleşmesini tek seferde raporlar; SSL sertifika zinciri nedir yazısı ara sertifikanın neden bu kadar önemli olduğunu açıklar.
-servername seçeneğini koruyun: OpenSSL 1.1.1 ve sonrası SNI'yı -connect ana bilgisayar adından doldurur, ancak macOS ile gelen LibreSSL openssl bunu yapmaz ve bir IP adresine bağlandığınızda hiçbir sürüm yapmaz. SNI olmadan paylaşımlı bir sunucu size varsayılan sertifikasını verir ya da Cloudflare gibi el sıkışmasını keser ve var olmayan bir ad uyuşmazlığının peşine düşersiniz.
Katman 4: Yanıt başlıklarını okuyun
TLS iyi, yani sonunda gerçek bir HTTP konuşmanız var. Şimdi istemcinizin sizin için özetlediğini değil, sunucunun gerçekte ne söylediğini okuyun. Yalnızca başlıkları yazdırın: gövde yine de indirilip atılır, yani bu, istemcinizin gönderdiği GET'in aynısıdır.
curl -s -D - -o /dev/null https://waqtazan.com/api/v1/timings/egypt/cairoÖnce durum satırını, sonra content-type'ı, sonra geri kalanı okuyun. Bu iki alan, başka bir şey okumadan önce isteğin başarılı olup olmadığını ve gövdenin JSON olup olmadığını söyler.
Sağlıklı bir JSON yanıtı nasıl görünür
Yukarıdaki komutu 27 Ekim 2026'da test endpoint'ine karşı çalıştırmak, diğerlerinin yanı sıra şu başlıkları döndürdü:
| Başlık | Değer | Size ne söyler |
|---|---|---|
HTTP/2 | 200 | İstek başarılı oldu ve sunucu HTTP/2 konuşuyor |
content-type | application/json | HTML hata sayfası değil, JSON alacaksınız |
content-length | 567 | Boş bir gövde değil, gerçek bir payload |
access-control-allow-origin | * | Tarayıcıların bu yanıtı okumasına izin var |
server | cloudflare | Kaynağın önünde bir CDN var |
alt-svc | h3=":443" | Sonraki istekler için HTTP/3 duyuruluyor |
Katman 5: Yalnızca tarayıcı çağrılarını bozan başlık
Saatlerin kaybolduğu katman burasıdır, çünkü curl ile tarayıcının gerçekten ayrıştığı katmandır. CORS'u sunucu değil tarayıcı uygular. Access-Control-Allow-Origin eksikse sunucu yine de eksiksiz ve doğru bir 200 döndürür; tarayıcı yalnızca gövdeyi JavaScript'inize vermeyi reddeder.
Yani belirti şudur: curl kusursuz çalışır, Postman kusursuz çalışır ve tarayıcı konsolu isteğin CORS politikası tarafından engellendiğini söyler. Sunucuda hiçbir sorun yoktur. Yanıtta yalnızca bir başlık eksiktir.
Test endpoint'i access-control-allow-origin: * döndürür; bu yüzden herhangi bir origin'den yapılan sade bir fetch() çalışır:
// Run it in the console of a tab on a site without a strict CSP, such as example.com
// (this page's own CSP blocks it). It works there because ACAO is set to *
const r = await fetch('https://waqtazan.com/api/v1/timings/egypt/cairo')
console.log(await r.json())Preflight tuzağı: Başlık ekleyene kadar çalışır
İkinci bir tuzak daha var ve bu endpoint onu güzel gösteriyor. Basit bir istek (özel başlıksız düz bir GET) başarılı olur. Ancak özel bir başlık eklediğiniz ya da Content-Type: application/json ile POST yaptığınız anda tarayıcı önce bir OPTIONS preflight gönderir ve preflight yanıtının kendi CORS başlıklarını taşıması gerekir (MDN).
Preflight'ı ayrı test edin, çünkü o farklı bir kod yolundan gelen farklı bir yanıttır:
curl -s -D - -o /dev/null -X OPTIONS \
-H 'Origin: https://example.com' \
-H 'Access-Control-Request-Method: GET' \
https://waqtazan.com/api/v1/timings/egypt/cairo27 Ekim 2026 itibarıyla bu preflight, content-type: text/html ile bir 200 döndürüyor ve hiç access-control-allow-origin başlığı içermiyor; dolayısıyla düz GET sorunsuz çalışsa bile tarayıcıdan gelen preflight'lı bir istek engellenir.
Tuzak tam olarak budur: entegrasyonunuz geliştirmede çalışır, bir Authorization ya da X-Request-Id başlığı eklersiniz ve sunucu tarafında hiçbir değişiklik olmadan bozulur. Yalnızca herkese açık veriye ihtiyacınız varsa isteği basit tutun, çalışmaya devam eder.
Katman 6: Payload beklediğiniz biçimde mi?
Son katman, kodunuzun gerçekten önemsediği katmandır. Geçerli JSON'lu bir 200, bir alan yeniden adlandırıldıysa, bir tür sayıdan string'e döndüyse ya da bir zaman damgası ayrıştırmadığınız bir biçimde geliyorsa yine de sizi bozabilir.
Ayrıştırıcıyı yazmadan önce gerçek yanıta bakın. Bu endpoint hem görüntü için biçimlendirilmiş saatleri hem de ISO zaman damgalarını döndürür; kopyalamaya değer bir kalıp: yerelleştirilmiş string'ler insanlar içindir, ISO değerleri kod içindir:
{
"city": { "slug": "riyadh", "name_ar": "الرياض", "name_en": "Riyadh" },
"country": "saudi-arabia",
"date": "2026-10-26",
"times": { "fajr": "4:38 ص", "dhuhr": "11:37 ص", "maghrib": "5:17 م" },
"timesISO": { "fajr": "2026-10-26T01:38:00.000Z", "dhuhr": "2026-10-26T08:37:00.000Z" },
"method": "umm_al_qura"
}Her zaman makinece okunabilir alanı ayrıştırın. Burada bu timesISO demektir, asla times değil: görüntü string'leri yerelleştirilmiştir ve yerel ayar değiştiği anda biçimleri değişir.
Yapıyı hızlıca incelemek için yanıtı jq'ya aktarın: curl -s <url> | jq keys üst düzey alanları listeler, jq '.times' ise ham gövdeyi kaydırmadan içine iner.
Belirti → katman → araç
Her seferinde altısını da yürümek yerine doğrudan önemli katmana atlamak için bunu kullanın:
| Gördüğünüz | Başarısız katman | Şununla kontrol edin |
|---|---|---|
ERR_NAME_NOT_RESOLVED, ENOTFOUND | 1 — DNS | DNS sorgusu |
ECONNREFUSED, anında hata | 2 — Port | Port denetleyicisi |
| İstek takılır, sonra zaman aşımına uğrar | 2 — Filtrelenen port | Port denetleyicisi |
CERT_HAS_EXPIRED, UNABLE_TO_VERIFY_LEAF_SIGNATURE | 3 — TLS | SSL denetleyicisi |
| Tarayıcıda çalışır, curl veya Node'da başarısız olur | 3 — Eksik zincir | SSL denetleyicisi |
401, 429, 503 | 4 — HTTP durumu | HTTP Başlık Kontrolü |
| curl'de çalışır, tarayıcıda engellenir | 5 — CORS | HTTP Başlık Kontrolü |
Unexpected token '<', "<!DOCTYPE "... is not valid JSON | 4 — HTML hata sayfası | HTTP Başlık Kontrolü |
| Eksik veya yanlış türde alanlar | 6 — Payload | curl … | jq |
Gecikme bu merdivenin biraz dışında kalır. Tüm katmanlar geçiyor ama yanıtlar yavaşsa, ana bilgisayara gidiş dönüş süresini ping ile ölçün ve ad çözümlemenin kendisinin darboğaz olup olmadığını bir DNS hız testi ile kontrol edin.
Herhangi bir endpoint'in gerçek yanıt başlıklarını görün
Bir API'nin döndürdüğü kesin durum kodunu, content-type ve CORS başlıklarını görün. İstek sunucu tarafından yapılır, bu yüzden tarayıcı önbelleği veya eklentiler sonucu bozamaz. Ücretsiz, kayıt gerekmez.
Kaynaklar
Sıkça Sorulan Sorular
Postman olmadan bir API endpoint'i nasıl test edilir?
API'm neden curl'de çalışıyor ama tarayıcıda başarısız oluyor?
curl'ün 000 durum kodu döndürmesi ne anlama gelir?
Bir API'nin herkes için mi yoksa sadece benim için mi kapalı olduğunu nasıl anlarım?
Bir API neden 200 döndürüyor ama JSON ayrıştırıcım hata veriyor?
CORS preflight nedir ve ne zaman olur?
API'nin DNS'ini kendi çözümleyicimle mi yoksa herkese açık bir çözümleyiciyle mi test etmeliyim?
443 portunun açık olması HTTPS endpoint'inin çalıştığı anlamına gelir mi?
İlgili Makaleler
İlgili Araçlar
HTTP Başlık Kontrolü
HTTP yanıt başlıklarını ve güvenlik başlıkları derecelendirmesini analiz edin
DNS Sorgulama
Tüm DNS kayıtları alan adının kendi ad sunucularından, Google ve Cloudflare önbelleğiyle yan yana
Port Kontrolü
Port bağlantısını ve servis kullanılabilirliğini test edin
SSL Sertifika Kontrolü
SSL sertifika geçerliliğini ve güvenlik ayrıntılarını doğrulayın
Ping Testi
Ping, jitter ve paket kaybınızı ölçün, 34 bulut bölgesine pinginizi görün ve herhangi bir siteye ya da IP'ye 11 şehirden ping atın



