API Platformu
Alan Adı Araştırması API
Herhangi bir alan adının hangi anahtar kelimelerde sıralandığını, organik rakiplerini, en çok trafik alan sayfalarını ve arama görünürlüğünün tek çağrılık özetini alın.
Herhangi bir alan adının hangi anahtar kelimelerde sıralandığını, organik rakiplerini, en çok trafik alan sayfalarını ve arama görünürlüğünün tek çağrılık özetini alın. Tek bir endpoint, type parametresiyle seçilen dört rapor sunar. Türkiye verisi 61 milyondan fazla anahtar kelimeyi kapsar.
Kimlik Doğrulama
Tüm istekler header tabanlı kimlik doğrulama gerektirir. Her istekte API kimlik bilgilerinizi ekleyin.
| 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/json
Accept-Language: trRapor Tipleri
type | Döndürdüğü | Ücretlendirilen satır |
|---|---|---|
overview | Tek bir özet: kelime sayısı, tahmini trafik ve değeri, ilk 3 / 10 / 20 / 100'deki kelime sayıları, yeni ve kaybedilen kelimeler | 1 |
keywords | Alan adının sıralandığı kelimeler: hacim, CPC, zorluk, niyet, pozisyon, sıralanan URL ve tahmini trafik | dönen satır |
competitors | Aynı kelimeler için yarışan alan adları, ortak kelime sayısına göre. Alan adının kendisi listede yer almaz | dönen satır |
top_pages | Alan adının sayfaları, getirdikleri organik trafiğe göre | dönen satır |
Varsayılan overview'dur. Tek satır döndürdüğü için type gönderilmeyen bir istek en düşük ücreti öder.
{
"type": "keywords",
"domain": "ornek.com.tr",
"limit": 100
}İstek Parametreleri
application/json gövdesi gönderin. Seçilen type için geçerli olmayan bir parametre yok sayılmaz, reddedilir; yanlış yazılmış bir parametre ise hatada adıyla ve bir öneriyle bildirilir. Böylece bir yazım hatası, istediğinizden farklı bir sonucu sessizce döndüremez. JSON null değeri "gönderilmedi" sayılır.
Gövde
domainstringrequiredAraştırılacak alan adı. https://, www., port, yol (path) ve Search Console'un sc-domain: öneki otomatik temizlenir. Uluslararası alan adları (örnek.com.tr) kabul edilir.
typestringdefault: overviewoverview, keywords, competitors veya top_pages.
countrystringdefault: TRArama pazarının iki harfli ülke kodu. Aşağıdaki Pazarlar bölümüne bakın.
languagestringPazarın dili. Varsayılan, pazarın ana dilidir (TR için tr).
limitintegerdefault: 100Döndürülecek satır sayısı, 1–1000. overview ile kullanılamaz.
pageintegerdefault: 1Sayfa numarası. page × limit en fazla 10.000 olabilir. overview ile kullanılamaz.
sortstringkeywords: traffic (varsayılan), volume, position, difficulty, cpc. competitors: common_keywords (varsayılan), avg_position. top_pages: traffic.
directionstringdesc veya asc. position ve avg_position için varsayılan asc'dir (en iyisi önce), diğerleri için desc.
min_volumeintegerYalnızca keywords. Aylık arama hacmi en az bu kadar olan kelimeleri tutar.
max_positionintegerYalnızca keywords. Alan adının bu pozisyonda veya daha iyisinde sıralandığı kelimeleri tutar, 1–100.
intentstringYalnızca keywords. informational, navigational, commercial veya transactional.
containsstringYalnızca keywords. Bu metni içeren kelimeleri tutar, 1–80 karakter, büyük/küçük harf duyarsız (Türkçe İ/ı doğru işlenir).
idempotency_keystringİsteğe bağlı, en fazla 128 karakter. Aynı anahtarla 24 saat içinde tekrarlanan istek, kayıtlı yanıtı ücretsiz döndürür; böylece zaman aşımına uğrayan bir istek güvenle tekrar denenebilir.
{
"type": "keywords",
"domain": "ornek.com.tr",
"limit": 50,
"min_volume": 100,
"max_position": 10,
"intent": "commercial",
"contains": "avukat",
"sort": "volume"
}Pazarlar
GET /v1/domain-research/markets desteklenen tüm ülkeleri ve dillerini listeler. Veri sorgusu yapmaz ve ücretsizdir.
{
"success": true,
"default_country": "TR",
"markets": [
{ "country": "TR", "name": "Turkiye", "languages": ["tr"] },
{ "country": "US", "name": "United States", "languages": ["en", "es"] }
]
}Kod Örnekleri
Bir alan adının en çok trafik getiren kelimelerini almak.
curl -X POST https://data.semust.com/v1/domain-research \
-H "SEMUST-API-USER: kullanici_adiniz" \
-H "SEMUST-API-PASSWORD: sifreniz" \
-H "Content-Type: application/json" \
-H "Accept-Language: tr" \
-d '{
"type": "keywords",
"domain": "ornek.com.tr",
"limit": 100
}'import requests
response = requests.post(
"https://data.semust.com/v1/domain-research",
headers={
"SEMUST-API-USER": "kullanici_adiniz",
"SEMUST-API-PASSWORD": "sifreniz",
"Accept-Language": "tr",
},
json={"type": "keywords", "domain": "ornek.com.tr", "limit": 100},
timeout=120,
)
data = response.json()
if response.status_code != 200:
# Her hatada sabit bir `code` vardır; `retryable` tekrar denemenin işe yarayıp yaramayacağını söyler.
raise SystemExit(f"{data['code']}: {data['error']} {data.get('hint', '')}")
print(f"{data['total']} kelimeden {data['count']} tanesi, ücret ${data['cost']:.6f}")
for row in data["items"]:
print(row["position"], row["keyword"], row["volume"], row["traffic"])const response = await fetch("https://data.semust.com/v1/domain-research", {
method: "POST",
headers: {
"SEMUST-API-USER": "kullanici_adiniz",
"SEMUST-API-PASSWORD": "sifreniz",
"Content-Type": "application/json",
"Accept-Language": "tr",
},
body: JSON.stringify({ type: "keywords", domain: "ornek.com.tr", limit: 100 }),
});
const data = await response.json();
if (!response.ok) {
throw new Error(`${data.code}: ${data.error}`);
}
console.log(`${data.total} kelimeden ${data.count} tanesi, ücret $${data.cost}`);Yanıt
Liste raporları satırları items içinde döndürür; overview bunun yerine tek bir data nesnesi döndürür. total sorgu için var olan satır sayısı, count bu yanıttaki satır sayısıdır.
overview içindeki pozisyon sayıları kümülatiftir: top10, top3'ü de kapsar. Trafik, aylık organik ziyaretin tahminidir. Elimizde olmayan bir değer 0 değil null döner: "cpc": null "CPC verisi yok" demektir, "CPC sıfır" değil.
Aşağıdaki örnekler semust.com için Türkiye pazarından alınmış gerçek yanıtlardır.
{
"success": true,
"type": "overview",
"domain": "semust.com",
"country": "TR",
"language": "tr",
"data": {
"organic": {
"keywords": 136,
"traffic": 1233,
"traffic_value_usd": 1541.15,
"top3": 6,
"top10": 36,
"top20": 89,
"top100": 136,
"new": 86,
"lost": 29,
"improved": 25,
"declined": 23
},
"paid": { "keywords": 0, "traffic": 0, "traffic_value_usd": 0 }
},
"cost": 0.013332,
"cached": false,
"request_id": "3f1c2a9e-5b7d-4c1e-9a2f-8d6e4b0c7a11"
}{
"success": true,
"type": "keywords",
"domain": "semust.com",
"country": "TR",
"language": "tr",
"total": 136,
"count": 3,
"page": 1,
"limit": 3,
"sort": "traffic",
"direction": "desc",
"items": [
{
"keyword": "google search console",
"volume": 60500,
"cpc": 1.57,
"difficulty": 85,
"intent": "navigational",
"position": 19,
"url": "https://semust.com/blog/google-search-console-nedir",
"traffic": 373
},
{
"keyword": "semust",
"volume": 390,
"cpc": 0.31,
"difficulty": 4,
"intent": "informational",
"position": 1,
"url": "https://semust.com/",
"traffic": 154
},
{
"keyword": "18 arama motoru isimleri",
"volume": 320,
"cpc": null,
"difficulty": 0,
"intent": "informational",
"position": 4,
"url": "https://semust.com/blog/en-iyi-arama-motorlari",
"traffic": 19
}
],
"cost": 0.013596,
"cached": false,
"request_id": "9b0e7c4d-2a1f-4e3b-8c5d-6f7a8b9c0d1e"
}{
"success": true,
"type": "competitors",
"domain": "semust.com",
"country": "TR",
"language": "tr",
"total": 2630,
"count": 2,
"page": 1,
"limit": 2,
"sort": "common_keywords",
"direction": "desc",
"items": [
{
"domain": "eksisozluk.com",
"common_keywords": 69,
"avg_position": 10.2,
"keywords": 795972,
"traffic": 33062395
},
{
"domain": "webtekno.com",
"common_keywords": 59,
"avg_position": 19.9,
"keywords": 59032,
"traffic": 977179
}
],
"cost": 0.013464,
"cached": false,
"request_id": "c2d4e6f8-1a3b-4c5d-8e9f-0a1b2c3d4e5f"
}{
"success": true,
"type": "top_pages",
"domain": "semust.com",
"country": "TR",
"language": "tr",
"total": 40,
"count": 2,
"page": 1,
"limit": 2,
"sort": "traffic",
"direction": "desc",
"items": [
{
"url": "https://semust.com/blog/google-search-console-nedir",
"keywords": 9,
"traffic": 594,
"top3": 0,
"top10": 3
},
{
"url": "https://semust.com/blog/yapay-zeka-fotograf-promptlari",
"keywords": 26,
"traffic": 218,
"top3": 2,
"top10": 17
}
],
"cost": 0.013464,
"cached": false,
"request_id": "5e6f7a8b-9c0d-4e1f-a2b3-c4d5e6f7a8b9"
}Yanıt Alanları Referansı
Zarf
| Alan | Tip | Açıklama |
|---|---|---|
success | boolean | İstek başarılıysa true |
type, domain, country, language | string | Normalizasyon ve varsayılanlardan sonra gerçekte sorgulanan değerler |
total | integer | Sorgu için var olan satır sayısı (liste raporları) |
count | integer | Bu yanıttaki satır sayısı (liste raporları) |
page, limit, sort, direction | Uygulanan sayfalama ve sıralama (liste raporları) | |
items | array | Satırlar (liste raporları) |
data | object | Özet (overview) |
cost | number | Bu isteğin ücreti, USD |
cached | boolean | Önbellekten sunulduysa true |
request_id | string | İsteği izlemek için destek ekibine iletin |
overview → data.organic
| Alan | Tip | Açıklama |
|---|---|---|
keywords | integer | Alan adının ilk 100'de sıralandığı kelime sayısı |
traffic | integer | Tahmini aylık organik ziyaret |
traffic_value_usd | number | Bu trafiğin ücretli aramada maliyeti, USD |
top3, top10, top20, top100 | integer | O pozisyonda veya daha iyisinde sıralanan kelime sayısı (kümülatif) |
new, lost | integer | Önceki güncellemeden bu yana sıralamaya giren veya çıkan kelimeler |
improved, declined | integer | Pozisyonu yükselen veya düşen kelimeler |
data.paid, ücretli arama için keywords, traffic ve traffic_value_usd içerir.
keywords satırı
| Alan | Tip | Açıklama |
|---|---|---|
keyword | string | Arama sorgusu |
volume | integer | null | Aylık ortalama arama |
cpc | number | null | Ortalama tıklama başı maliyet, USD |
difficulty | integer | null | Sıralama zorluğu, 0–100 |
intent | string | null | informational, navigational, commercial veya transactional |
position | integer | null | Alan adının pozisyonu |
url | string | null | Sıralanan sayfa |
traffic | integer | null | Bu kelimeden gelen tahmini aylık ziyaret |
competitors satırı
| Alan | Tip | Açıklama |
|---|---|---|
domain | string | Rakip alan adı |
common_keywords | integer | İki alan adının da sıralandığı kelime sayısı |
avg_position | number | null | Rakibin bu ortak kelimelerdeki ortalama pozisyonu |
keywords | integer | null | Rakibin sıralandığı toplam kelime sayısı |
traffic | integer | null | Rakibin toplam tahmini aylık trafiği |
top_pages satırı
| Alan | Tip | Açıklama |
|---|---|---|
url | string | Sayfa |
keywords | integer | Sayfanın sıralandığı kelime sayısı |
traffic | integer | Sayfaya tahmini aylık ziyaret |
top3, top10 | integer | Bu kelimelerden ilk 3 / ilk 10'da olanların sayısı |
Hatalar
Her hata aynı biçimdedir: kodunuzda kullanacağınız sabit bir code, okunabilir bir error mesajı ve aynı isteği tekrar göndermenin işe yarayıp yaramayacağını söyleyen retryable. Faydalı olduğunda hata ayrıca sorunlu field alanını, nasıl düzeltileceğine dair bir hint ipucunu ve geçerli değerleri (allowed) içerir. Accept-Language: tr gönderirseniz error ve hint Türkçe gelir; code her iki dilde aynıdır.
4xx hataları hiçbir ücret alınmadan önce tespit edilir, bu yüzden ücretsizdir. Bu noktadan sonraki bir hata tamamen iade edilir. Bir hata için asla ücret alınmaz.
Kontroller sabit bir sırayla yapılır ve ilk sorun bildirilir: JSON → bilinmeyen parametreler → type → tipin almadığı parametreler → domain → pazar → değerler.
| Durum | Kod | Anlamı | Ne yapmalı |
|---|---|---|---|
| 400 | INVALID_JSON | Gövde bir JSON nesnesi değil | JSON nesnesi gönderin |
| 400 | UNKNOWN_PARAMETER | Tanımadığımız bir parametre; hint en yakın doğru adı önerir | Yazımı düzeltin |
| 400 | INVALID_TYPE | Bilinmeyen type; allowed geçerli olanları listeler | allowed içinden bir değer kullanın |
| 400 | TYPE_UNAVAILABLE | Duyurulmuş ama henüz açılmamış bir rapor | allowed içinden bir değer kullanın |
| 400 | PARAMETER_NOT_ALLOWED | Parametre var ama bu type için değil; hint onu kabul eden tipleri söyler | Kaldırın ya da type'ı değiştirin |
| 400 | DOMAIN_REQUIRED | domain eksik | Bir alan adı gönderin |
| 400 | INVALID_DOMAIN | Alan adı değil (IP, localhost, uzantısız…) | Kayıtlı bir alan adı gönderin |
| 400 | UNSUPPORTED_MARKET | Ülke desteklenmiyor ya da dil o ülkede yok; allowed o ülkenin dillerini listeler | Pazarlar bölümüne bakın |
| 400 | INVALID_PARAMETER | Bir değer aralık dışında veya yanlış tipte; field hangisi olduğunu söyler | Parametrenin kurallarına bakın |
| 400 | PAGE_OUT_OF_RANGE | page × limit 10.000'i aşıyor | Sorguyu filtrelerle daraltın |
| 401 | INVALID_CREDENTIALS | Kullanıcı adı veya şifre yanlış | Kimlik bilgilerinizi kontrol edin |
| 402 | INSUFFICIENT_CREDITS | Bakiye isteği karşılamıyor; required ve balance farkı gösterir | limit'i düşürün ya da bakiye yükleyin |
| 403 | SERVICE_NOT_ENABLED | Alan Adı Araştırması bu API kullanıcısı için etkin değil | Hesabınızda etkinleştirin |
| 403 | IP_NOT_WHITELISTED | IP adresiniz izin listesinde değil | API Erişimi sayfasından ekleyin |
| 409 | REQUEST_IN_PROGRESS | Aynı idempotency_key hâlâ çalışıyor | Bitince tekrar deneyin |
| 413 | REQUEST_TOO_LARGE | Gövde 16 KB'tan büyük | Daha küçük bir gövde gönderin |
| 429 | RATE_LIMIT_EXCEEDED | Dakikalık veya günlük sınırınıza ulaştınız | Yavaşlayın |
| 429 | TOO_MANY_CONCURRENT_REQUESTS | Aynı anda 5'ten fazla istek çalışıyor | Birinin bitmesini bekleyin (Retry-After) |
| 502 | REQUEST_FAILED | Veri alınamadı; retryable tekrar denemenin işe yarayıp yaramayacağını söyler | retryable true ise tekrar deneyin |
| 503 | SERVICE_BUSY | Geçici yoğunluk | Retry-After saniye sonra tekrar deneyin |
| 503 | SERVICE_UNAVAILABLE | Geçici olarak kullanılamıyor | Retry-After saniye sonra tekrar deneyin |
| 504 | TIMEOUT | İstek çok uzun sürdü | Tekrar deneyin; güvenlidir |
| 500 | INTERNAL_ERROR | Bizim tarafımızda bir sorun oluştu | Tekrar deneyin ya da request_id ile destek ekibine yazın |
Verisi olmayan bir alan adı hata değildir: yanıt 200, "total": 0 ve boş bir items listesidir (overview'da sıfırlar) ve taban ücretle ücretlendirilir.
{
"error": "Bilinmeyen parametre: 'limt'",
"code": "UNKNOWN_PARAMETER",
"field": "limt",
"hint": "'limit' mı demek istediniz?",
"retryable": false
}{
"error": "'min_volume' parametresi type=overview ile kullanılamaz",
"code": "PARAMETER_NOT_ALLOWED",
"field": "min_volume",
"hint": "Bu parametreyi kabul eden tipler: keywords",
"retryable": false
}{
"error": "'limit' 1 ile 1000 arasında bir tam sayı olmalıdır",
"code": "INVALID_PARAMETER",
"field": "limit",
"retryable": false
}{
"error": "Bakiyeniz bu istek için yetersiz",
"code": "INSUFFICIENT_CREDITS",
"hint": "limit değerini düşürün ya da bakiye yükleyin",
"retryable": false,
"required": 0.1452,
"balance": 0.05
}{
"error": "Servis şu anda yoğun, lütfen kısa süre sonra tekrar deneyin",
"code": "SERVICE_BUSY",
"hint": "Ücret alınmadı",
"retryable": true,
"request_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7"
}Krediler ve Sınırlar
Krediler
İstek başına bir taban ücret artı dönen her satır için bir ücret:
ücret = $0.0132 + (satır / 1000) x $0.132| İstek | Ücret |
|---|---|
overview (her zaman 1 satır) | $0.013332 |
| Veri yok (0 satır) | $0.013200 |
| 10 satır | $0.014520 |
| 100 satır | $0.026400 |
| 1000 satır (en fazla) | $0.145200 |
Bakiyeden limit satırın ücreti bloke edilir; dönmeyen satırların ücreti hemen iade edilir. Daha az satır istemek daha ucuzdur; limit'i ihtiyacınız kadar ayarlayın.
Önbellek
Sonuçlar 7 gün önbellekte tutulur; alttaki veri aylık güncellenir. Önbellekten dönen yanıt "cached": true ile işaretlenir ve canlı yanıtla aynı ücretle ücretlendirilir.
Sınırlar
Dakikalık ve günlük sınırlar hesabınızda tanımlıdır (429 RATE_LIMIT_EXCEEDED, bkz. Krediler ve Rate Limit). Bundan bağımsız olarak API kullanıcısı başına aynı anda en fazla 5 istek çalışır; altıncısı Retry-After header'ı ile 429 TOO_MANY_CONCURRENT_REQUESTS alır. Önbellekten dönen yanıtlar bu sınıra sayılmaz.
