Açık API

Bu sitenin kendi sorgularında kullandığı JSON uç noktaları, bugün nasıl çalışıyorsa öyle belgelendi. Yalnızca okuma yapar, kayıt gerektirmez.

API anahtarı yok, SLA yok, değişebilirAPI anahtarı, ücretli paket, erişilebilirlik ya da yanıt süresi taahhüdü yoktur. API sürümlenmez: alanlar haber verilmeden eklenebilir, yeniden adlandırılabilir ya da kaldırılabilir; kötüye kullanılan bir uç nokta daha sıkı sınırlanabilir veya kapatılabilir. Bir istek başarısız olduğunda kötü biçimde bozulan bir şey kurmayın.

Genel kurallar

Bütün uç noktalar GET isteklerine JSON (UTF-8) ile yanıt verir. Alan adı yolun bir parçasıdır; Türkçe karakterli (IDN) adlar Unicode olarak da, A-etiketi (xn--…) olarak da gönderilebilir. Tarihler UTC ve ISO 8601 biçimindedir.

Her gözlem, istek anında tek bir sunucu konumundan yapılır ve nereden geldiğini söyler: her bölümde status, source ve observedAt bulunur. Durumu "error" ya da "unsupported" olan bölüm kontrol edilememiş demektir. Bu hiçbir zaman kaydın olmadığını göstermez; kayıt durumunun "not-found" olması da adın tescil edilebileceğinin güvencesi değildir.

Belgelendirme için ayrılmış adlar (example.com, example.net, example.org ile .example, .test, .invalid ve .localhost altındaki her şey) canlı olarak sorgulanmaz ve 422 döner. Bu sayfadaki yanıt örnekleri example.com ile belgelendirme IP aralıklarını yalnızca gösterim amacıyla kullanır; API'yi denemek için kendi yönettiğiniz bir alan adını kullanın.

Alan adı raporu

GET /api/lookup/{domain}

Birbirinden bağımsız en çok beş bölümden oluşan tek rapor: registration (RDAP; RDAP sunmayan bazı kayıt otoritelerinde 43 numaralı porttan WHOIS), dns, mail (MX, SPF, DMARC), hosting (IP'den ASN ve ağ bilgisi) ve web (tek bir HTTPS isteği ve o istekte sunulan TLS sertifikası). Bir bölümün başarısız olması raporu başarısız kılmaz.

Baştaki "www." atılır. Alt alan adlarında kayıt verisi tescil edilebilir alan adı için, diğer bölümler gönderdiğiniz ana makine adı için sorgulanır.

Parametreler

AdYerAçıklama
domainyolAlan adı ya da ana makine adı, en çok 253 karakter.
sectionssorguregistration, dns, mail, hosting, web adlarının virgülle ayrılmış bir alt kümesi. Tanınmayan adlar yok sayılır; geçerli hiçbir ad yoksa yanıt 400 olur. İstemediğiniz bölümler "skipped" durumuyla döner. Varsayılan: beşi birden.

Durum kodları

DurumAnlamı
200{ "report": … }. Cache-Control: public, max-age=60, s-maxage=300 başlığıyla gönderilir.
400Ad doğrulamadan geçmezse { "error": "invalid-domain", "reason": … }, bölüm adları geçersizse { "error": "invalid-sections", "allowed": […] }.
422Belgelendirme ve test adları için { "error": "reserved-name" }; ad yalnızca özel ya da ayrılmış adreslere çözülüyorsa { "error": "blocked-target" }. Servis bu tür adreslere bağlanmaz.
429{ "error": "rate-limited", "retryAfterSeconds": n } ve Retry-After başlığı.
Örnek istek
curl -s "https://www.orbitprobe.com/api/lookup/yourdomain.com?sections=registration,dns"
Örnek yanıt (gösterim amaçlı değerler, kısaltılmış)
{
  "report": {
    "input": "example.com",
    "ascii": "example.com",
    "unicode": "example.com",
    "registrableDomain": "example.com",
    "isSubdomain": false,
    "tld": "com",
    "generatedAt": "2026-01-01T12:00:00.000Z",
    "dataMode": "live",
    "cached": false,
    "registration": {
      "status": "ok",
      "source": "RDAP · rdap.registry.example",
      "observedAt": "2026-01-01T12:00:00.000Z",
      "durationMs": 412,
      "state": "registered",
      "registrableDomain": "example.com",
      "registrar": "Example Registrar, Inc.",
      "registrarIanaId": "9999",
      "registrarUrl": null,
      "abuseEmail": "abuse@registrar.example",
      "createdAt": "2015-03-01T00:00:00Z",
      "updatedAt": "2025-02-10T00:00:00Z",
      "expiresAt": "2027-03-01T00:00:00Z",
      "statusCodes": ["client transfer prohibited"],
      "nameservers": ["ns1.example.net", "ns2.example.net"],
      "dnssec": false,
      "registrant": { "organization": null, "country": null, "redacted": true },
      "rdapUrl": "https://rdap.registry.example/domain/example.com"
    },
    "dns": {
      "status": "ok",
      "source": "DNS · public recursive resolvers",
      "observedAt": "2026-01-01T12:00:00.000Z",
      "durationMs": 95,
      "resolver": "1.1.1.1, 8.8.8.8",
      "records": [
        { "type": "A", "name": "example.com", "value": "203.0.113.10", "ttl": 300 },
        { "type": "AAAA", "name": "example.com", "value": "2001:db8::10", "ttl": 300 },
        { "type": "MX", "name": "example.com", "value": "mail.example.com", "priority": 10 },
        { "type": "TXT", "name": "example.com", "value": "v=spf1 mx -all" }
      ],
      "failedTypes": [],
      "nxdomain": false
    },
    "mail": {
      "status": "ok",
      "source": "DNS",
      "observedAt": "2026-01-01T12:00:00.000Z",
      "durationMs": 140,
      "mx": [{ "priority": 10, "host": "mail.example.com", "addresses": ["203.0.113.25"], "provider": null }],
      "spf": "v=spf1 mx -all",
      "dmarc": "v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com",
      "dkim": "selector-required",
      "findings": [{ "level": "ok", "code": "…", "title": "…", "detail": "…" }]
    },
    "hosting": {
      "status": "ok",
      "source": "IP lookups",
      "observedAt": "2026-01-01T12:00:00.000Z",
      "durationMs": 310,
      "addresses": [
        { "address": "203.0.113.10", "family": 4, "reverse": null, "asn": 64500, "asName": "EXAMPLE-NET", "prefix": "203.0.113.0/24", "country": null, "networkName": null, "networkOrg": null, "edge": null }
      ],
      "summary": "EXAMPLE-NET (AS64500)"
    },
    "web": {
      "status": "ok",
      "source": "HTTPS request",
      "observedAt": "2026-01-01T12:00:00.000Z",
      "durationMs": 520,
      "finalUrl": "https://example.com/",
      "httpStatus": 200,
      "redirects": [],
      "serverHeader": null,
      "poweredBy": null,
      "hsts": true,
      "responseMs": 180,
      "page": { "title": "Example Domain", "description": null, "keywords": null },
      "headers": [{ "name": "content-type", "value": "text/html; charset=UTF-8" }],
      "tls": {
        "protocol": "TLSv1.3",
        "issuer": "Example CA",
        "subject": "example.com",
        "validFrom": "2025-12-01T00:00:00.000Z",
        "validTo": "2026-03-01T00:00:00.000Z",
        "altNames": ["example.com", "www.example.com"],
        "authorized": true,
        "authorizationError": null
      }
    }
  }
}

DNS yayılımı

GET /api/propagation/{domain}

Sabit bir listedeki açık özyinelemeli çözümleyicilerin her birine aynı soruyu sorar ve aynı yanıtları gruplar. Sonucu "10 çözümleyiciden 9'u bu yanıtı verdi" diye okuyun: listede olmayan çözümleyiciler hakkında hiçbir şey söylemez; anycast çalışan bir çözümleyici başka bir bölgede farklı yanıt verebilir.

Burada "www." korunur, çünkü soru tam olarak gönderdiğiniz ad hakkındadır.

Parametreler

AdYerAçıklama
domainyolSorulacak ana makine adı, en çok 253 karakter.
typesorguA, AAAA, NS, MX, TXT ya da CNAME (büyük/küçük harf fark etmez). Varsayılan: A.

Durum kodları

DurumAnlamı
200{ "report": … }: her çözümleyici için bir satır (durum: answer, no-records, nxdomain, timeout ya da error), birbirinden farklı yanıt grupları ve total, answered, failed sayaçları. Cache-Control: public, max-age=30.
400{ "error": "invalid-domain" } ya da { "error": "invalid-type" }.
422{ "error": "reserved-name" }.
429{ "error": "rate-limited" } ve Retry-After başlığı.
Örnek istek
curl -s "https://www.orbitprobe.com/api/propagation/www.yourdomain.com?type=A"
Örnek yanıt (gösterim amaçlı değerler, kısaltılmış)
{
  "report": {
    "ascii": "www.example.com",
    "unicode": "www.example.com",
    "type": "A",
    "generatedAt": "2026-01-01T12:00:00.000Z",
    "cached": false,
    "answers": [
      {
        "resolver": { "id": "cloudflare", "name": "Cloudflare", "address": "1.1.1.1", "operatorCountry": "US" },
        "status": "answer",
        "values": ["203.0.113.10"],
        "ttl": 300,
        "durationMs": 21,
        "group": 0
      },
      {
        "resolver": { "id": "quad9", "name": "Quad9", "address": "9.9.9.9", "operatorCountry": "CH" },
        "status": "timeout",
        "values": [],
        "ttl": null,
        "durationMs": 2800,
        "group": null
      }
    ],
    "groups": [{ "values": ["203.0.113.10"], "count": 9 }],
    "total": 10,
    "answered": 9,
    "failed": 1,
    "consistent": false
  }
}

Tek amaçlı denetimler

GET /api/tools/{tool}/{domain}

Araç sonuç sayfalarının arkasındaki motorlar, denetim başına tek istek: dkim-checker, subdomain-finder, mta-sts-checker, tls-rpt-checker, bimi-checker, dnssec-checker, reverse-dns ve security-txt-checker (sitedeki araç adresleriyle aynı anahtarlar). Yanıt ok, tool, source, observedAt ve cached alanlarını ve motorun raporunu hiç değiştirilmeden taşır.

Başarısız olan bir sorgu raporun içinde "failed", "error" ya da "unknown" gibi bir durum veya bir bulgu olarak görünür kalır; asla "kayıt yok"a çevrilmez. Baştaki "www." kaldırılır; reverse-dns bunun istisnasıdır: "www." korunur ve IPv4 ya da IPv6 adresi de kabul edilir.

Parametreler

AdYerAçıklama
toolyolYukarıdaki sekiz araç anahtarından biri. Başka bir değer 404 döner.
domainyolAlan adı ya da ana makine adı, en çok 253 karakter; reverse-dns için IP adresi de olabilir (IPv6 adresindeki iki nokta üst üsteleri yüzde kodlamasıyla gönderin).
selectorsorguYalnızca dkim-checker ve bimi-checker. DKIM: gerçek bir iletideki s= selector değeri; boş bırakılırsa yaygın sağlayıcı selector'larından oluşan sabit bir liste denenir. BIMI: varsayılan "default".

Durum kodları

DurumAnlamı
200{ "ok": true, "tool": …, "source": …, "observedAt": …, "cached": …, "report": … }. Cache-Control: public, max-age=60, s-maxage=300.
400{ "ok": false, "code": "invalid-domain", "reason": … } ya da { "ok": false, "code": "invalid-selector" }.
404{ "ok": false, "code": "unknown-tool", "tools": […] }.
422Belgeleme ve test adları için { "ok": false, "code": "reserved-name" }.
429{ "ok": false, "code": "rate-limited", "retryAfterSeconds": n } ve Retry-After başlığı.
Örnek istek
curl -s "https://www.orbitprobe.com/api/tools/tls-rpt-checker/yourdomain.com"
Örnek yanıt (gösterim amaçlı değerler, kısaltılmış)
{
  "ok": true,
  "tool": "tls-rpt-checker",
  "source": "Public DNS (1.1.1.1, 8.8.8.8)",
  "observedAt": "2026-01-01T12:00:00.000Z",
  "cached": false,
  "report": {
    "ascii": "example.com",
    "unicode": "example.com",
    "observedAt": "2026-01-01T12:00:00.000Z",
    "durationMs": 38,
    "cached": false,
    "host": "_smtp._tls.example.com",
    "state": "ok",
    "records": ["v=TLSRPTv1; rua=mailto:tls-reports@example.com"],
    "parsed": { "version": "TLSRPTv1", "valid": true, "rua": [{ "raw": "mailto:tls-reports@example.com", "scheme": "mailto", "valid": true, "target": "example.com" }] },
    "findings": [{ "level": "ok", "code": "RPT_OK", "params": { "n": 1 } }]
  }
}

Etkinlik sayaçları

GET /api/stats/activity

Ana sayfadaki kürenin arkasındaki sayılar: son 24 saatte kaç sorgu çalıştığı, ziyaretçi ülkesine ve sorgulanan adres bloğunun kayıtlı olduğu ülkeye göre. Yalnızca ülke kodları ve sayaçlar tutulur; IP adresi ya da alan adı saklanmaz. Sayaçlar ortak veritabanında 30 gün tutulur ve her sunucu örneği için aynıdır; o depoya ulaşılamadığında yanıttaki `source` alanı `memory` olur ve sayılar yalnızca tek bir süreçten gelir. Ziyaretçi ülkesi CDN başlığından alınır, bu yüzden yaklaşıktır: istatistik değil, kaba bir gösterge olarak değerlendirin.

Durum kodları

DurumAnlamı
200Anlık görüntü. Cache-Control: public, max-age=30. Bu uç noktada hız sınırı yoktur.
Örnek istek
curl -s "https://www.orbitprobe.com/api/stats/activity"
Örnek yanıt (gösterim amaçlı değerler, kısaltılmış)
{
  "windowHours": 24,
  "total": 3,
  "visitors": [{ "country": "TR", "count": 2 }, { "country": "DE", "count": 1 }],
  "hosting": [{ "country": "US", "count": 3 }],
  "generatedAt": "2026-01-01T12:00:00.000Z"
}

Hız sınırları

Sınırlar istemci IP adresi başına ve her uç nokta ailesi için ayrı sayılır. Sunucu önbelleğinden dönen sonuç sınıra sayılmaz. Sınıra ulaşıldığında yanıt, Retry-After başlığıyla birlikte 429 olur; döngü içinde yeniden denemek yerine o süre kadar bekleyin.

Rozet ve MCP araçları aynı motorları kullandığı için bu sınırları paylaşır.

Uç noktaIP adresi başına sınırSunucu önbelleği
/api/lookup/{domain}dakikada 30 · saatte 300300 sn (bir bölüm başarısız olduysa 30 sn)
/api/propagation/{domain}dakikada 12 · saatte 12060 sn
/api/tools/{tool}/{domain}dakikada 10 · saatte 80 (araç başına; DKIM dakikada 10 · saatte 80, subdomain bulucu dakikada 5 · saatte 40)300 sn / 1800 sn
/api/stats/activityyokyok

Önbellek

Raporlar sunucuda ana makine adına ve bölüm listesine göre önbelleğe alınır; önbellek süresi içinde aynı bölümleri yeniden istediğinizde aynı gözlem "cached": true ile ve ilk observedAt zamanlarıyla döner. Yukarıdaki Cache-Control başlıkları tarayıcıların ve CDN'in yanıtı kısa süre yeniden kullanmasına da izin verir. Taze sorguyu zorlayan bir parametre yoktur.

CORS

Bu sayfadaki uç noktalar Access-Control-Allow-Origin: * gönderir ve OPTIONS ön kontrol isteklerini yalnızca GET için yanıtlar. Başka bir kaynaktaki sayfadan çağırabilirsiniz. Çerez okumadıkları için kimlik bilgisi de söz konusu olmaz.

Adil kullanım

Her istek kayıt otoritelerine, DNS çözümleyicilerine ve sorgulanan sitenin kendisine gerçek sorgular gönderir. API'yi etkileşimli araçlar, paneller ve bakmak için bir nedeniniz olan alan adlarının ara sıra kontrolü için kullanın. Alan adı listelerini taramayın, sınırları aşmak için adres değiştirmeyin, çıktıyı yeniden satmayın. Kabul edilebilir kullanım politikası API trafiği için de sitedeki gibi geçerlidir.

Kabul edilebilir kullanım politikası

Giden webhook'lar

Giriş yapmış üyeler izleme uyarılarını, süre hatırlatmalarını ve pazar yeri bildirimlerini kendilerine ait bir adrese gönderebilir: bir Slack gelen webhook'u ya da genel bir https uç noktası (çalışma alanı → Ayarlar → Bildirim kanalları). Bu bölüm alıcının ne aldığını anlatır. Yalnızca giden yöndedir: OrbitProbe bu adreslerde istek kabul etmez ve gelen bir API yoktur.

Alıcılar genel bir sunucuda https olmalıdır (varsayılan port, kimlik bilgisi yok; özel, yerel ve ayrılmış sunucu adları reddedilir, sunucu adı gönderim anında yeniden çözümlenip denetlenir). Yönlendirmeler izlenmez. Alıcı 2xx yanıt verdiğinde iletim tamamlanmış sayılır; art arda beş başarısız iletimden sonra webhook kapatılır ve sahibi çalışma alanında bir bildirim görür.

İstek

AdAçıklama
POSTJSON gövde, Content-Type: application/json; charset=utf-8, User-Agent: OrbitProbe-Webhook/1.0
X-OrbitProbe-EventTür (aşağıya bakın).
X-OrbitProbe-Deliveryİletim kimliği (ntf_<sayı>). Yeniden denemede aynı kalır; böylece yinelenenleri ayıklayabilirsiniz.
X-OrbitProbe-SignatureYalnızca genel uç noktalarda: t=<unix saniye>,v1=<"<t>.<ham gövde>" üzerinden, Ayarlar'da gösterilen imza anahtarıyla hesaplanan HMAC-SHA256, hex>.

Gövde (genel uç noktalar)

AdAçıklama
idİletim kimliği; X-OrbitProbe-Delivery ile aynı.
kindAşağıdaki türlerden biri.
categorywatch, expiry, market veya test.
title, textHesabın dilinde bildirim metni: push bildirimindeki ifadenin aynısı. Sayımlar "M çözümleyiciden N'i" biçimindedir, asla yüzde değildir.
urlÇalışma alanında bakılacak yer.
createdAtOlayın kuyruğa alındığı an (ISO 8601, UTC).
accountAlıcının hesap kimliği; tek bir alıcı birden çok hesaba hizmet edebilsin diye.
dataOlayın kayıtlı ham hali: alan adı, sayımlar, ilan kimliği, tam sayı alt birim olarak tutar ve para birimi vb. Alanlar türe göre değişir; eksik olan bir alan ölçülmemiş demektir, asla "hayır" demek değildir.
Gövde (genel uç noktalar)
{
  "id": "ntf_1042",
  "kind": "watch-changed",
  "category": "watch",
  "title": "Watch: unexpected change",
  "text": "example.com TXT: 9 of 12 resolvers return values that differ from the guarded baseline.",
  "url": "https://www.orbitprobe.com/app/watch/00000000-0000-4000-8000-000000000000",
  "createdAt": "2026-01-01T00:00:00.000Z",
  "account": "00000000-0000-4000-8000-0000000000aa",
  "data": {
    "domain": "example.com",
    "kind": "dns-change",
    "record_type": "TXT",
    "name": "example.com",
    "matched": 3,
    "total": 12,
    "failed": 0,
    "differing": 9,
    "watch_id": "00000000-0000-4000-8000-000000000000",
    "event_id": 77
  }
}

Gövde (Slack)

Slack gelen webhook'ları yalnızca {"text": "…"} alır: başlık, metin ve adres üç satırda; Block Kit ya da ek yoktur. Böylece mesaj her Slack istemcisinde ve Mattermost, Rocket.Chat gibi Slack uyumlu alıcılarda görüntülenir.

Gövde (Slack)
{
  "text": "*Watch: unexpected change*\nexample.com TXT: 9 of 12 resolvers return values that differ from the guarded baseline.\nhttps://www.orbitprobe.com/app/watch/…"
}

İmzayı doğrulama

"<t>.<ham gövde>" üzerinden anahtarınızla HMAC'i yeniden hesaplayın, sabit zamanlı karşılaştırın ve beş dakikadan eski zaman damgalarını reddedin. Hash almadan önce JSON'u ayrıştırıp yeniden serileştirmeyin: alındığı haliyle baytları imzalayın.

İmzayı doğrulama
// Node.js receiver: verify X-OrbitProbe-Signature before trusting the body
import { createHmac, timingSafeEqual } from 'node:crypto';

export function verify(secret, rawBody, header, nowSeconds = Math.floor(Date.now() / 1000)) {
  const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? '');
  if (!m || Math.abs(nowSeconds - Number(m[1])) > 300) return false;
  const expected = createHmac('sha256', secret).update(`${m[1]}.${rawBody}`).digest('hex');
  return timingSafeEqual(Buffer.from(expected, 'hex'), Buffer.from(m[2], 'hex'));
}

Türler

watch-changed, watch-target, watch-failed, watch-recovered, watch-partial · expiry · offer-received, offer-countered, offer-accepted, offer-rejected, offer-withdrawn, offer-expired, listing-submitted, listing-approved, listing-paused, listing-removed, agreement-cancelled · test ("Test gönder" düğmesi).

Sınırlar

Hesap başına en fazla 5 webhook ve saatte 20 gönderim; sonrasında olaylar uygulama içi gelen kutusuna ve e-postaya yine ulaşır ama gönderilmez. İletimler beş dakikalık görevin sonraki çalışmalarında en fazla beş kez yeniden denenir. "offer-accepted" olayı yalnızca bir anlaşmayı kaydeder: ödeme, escrow ya da devir anlamına gelmez.

OpenAPI tanımı

Bu uç noktaların makinece okunabilir OpenAPI 3.1 belgesi aynı koddan üretilir: /api/openapi.json

Sık sorulan sorular

API anahtarı gerekiyor mu?

Hayır. API için anahtar ya da hesap yoktur. Bunun yerine istekler IP adresi başına sınırlanır.

API'ye üretim ortamında güvenebilir miyim?

Yalnızca başarısız olması sorun yaratmayacak işlerde. SLA ve sürümleme yoktur; uç noktalar siteye gerektiği için vardır ve siz de kullanabilesiniz diye belgelenmiştir. Sonuçları kendi tarafınızda önbelleğe alın, 429 ve 5xx yanıtlarını ele alın.

example.com neden 422 dönüyor?

Belgelendirme ve test için ayrılmış adlar uygulamanın içindeki örnek verilerle karşılanır, canlı olarak sorgulanmaz. API'yi denemek için gerçek bir alan adı kullanın.

Başarısız bir bölüm, kaydın olmadığı anlamına mı gelir?

Hayır. "error" ve "unsupported", kaynağın o anda sunucumuzdan okunamadığını söyler. Ne bulunduğunu yalnızca durumu "ok" ya da "partial" olan bölüm gösterir; o da yalnızca failedTypes içinde yer almayan türler için.