S
SEO Blog Agent v1.0.0
Sunucu Aktif

Giriş

SEO Blog Agent API, web siteleriniz için gelişmiş, çoklu model (multi-model) yapay zeka destekli, SEO uyumlu blog makaleleri ve marka profilleri üretmenize olanak tanıyan güçlü bir LangGraph otomasyon hattıdır. Sistem, rakip bulgularını analiz eder, sektörel trendleri belirler ve yüksek kaliteli, özgün, görsel hiyerarşisi düzenlenmiş içerikler üretir.

FastAPI Sürümü >0.100.0
Pipeline Motoru LangGraph Core
Aktif LLM Modelleri Groq, Deepseek, Dashscope

Kimlik Doğrulama

API güvenliği için tüm güvenli (Secure) isteklere geçerli bir API Anahtarı (API Key) eklenmelidir. API Anahtarı'nızı isteklerinize aşağıdaki iki yöntemden biriyle dahil edebilirsiniz:

Yöntem 1: HTTP Header (Önerilen)

X-API-Key
X-API-Key: YOUR_API_KEY

Yöntem 2: Bearer Authorization Header

Authorization
Authorization: Bearer YOUR_API_KEY

API Servisleri

POST

/api/generate

LangGraph pipeline motorunu çalıştırır ve SEO puanı, rakip bulguları ve zengin HTML/Markdown içeriği içeren blog makalesi çıktısı döndürür. Bu istek senkrondur ve sonuçlanması model yanıt hızına bağlı olarak 1-2 dakika sürebilir.

İstek Parametreleri (Request Body)

Alan Adı Tip Zorunlu? Açıklama
client_id string Hayır (Öntanımlı: "dynamic-client") Müşteriyi tanımlayan tekil kimlik bilgisi.
seed_topic string Evet Üretilecek blog konusunun başlığı veya anahtar kelimesi.
client_config object (ClientConfigInput) Evet Şirket / marka detayları ve davranış tercihleri.
verified_internal_links array[object] Hayır (Boş Liste) İçeriğe doğal olarak eklenmesini istediğiniz doğrulanmış site içi linkler.
include_contact_footer boolean Hayır (Öntanımlı: false) Blog sonuna adres ve iletişim bilgileri içeren bir imza alanı eklensin mi.
{
  "client_id": "hanworks",
  "seed_topic": "Yapay Zeka Destekli SEO Uyumlu Blog Üretimi",
  "include_contact_footer": true,
  "client_config": {
    "name": "Hanworks Agency",
    "domain": "https://hanworks.com.tr",
    "city": "İstanbul",
    "country": "turkey",
    "niche": "Yazılım, Tasarım, SEO",
    "tone": "Profesyonel ve açıklayıcı",
    "address": "Kadıköy, İstanbul",
    "address_line": "Kadıköy, İstanbul",
    "phone": "+90 216 000 0000",
    "whatsapp": "+90 555 000 0000",
    "email": "hello@hanworks.com.tr",
    "social_links": ["https://instagram.com/hanworks"],
    "reviewer_name": "Editör Ekibi",
    "use_emoji_headers": true,
    "use_emoji_in_content": false,
    "service_area_note": "Tüm Türkiye'ye uzaktan hizmet sağlamaktayız.",
    "exclude_domains": ["competitor.com"],
    "ai_brand_profile": "Hanworks, işletmeler için modern web ve yazılım çözümleri üretir..."
  },
  "verified_internal_links": [
    {
      "title": "Hizmetlerimiz",
      "path": "https://hanworks.com.tr/hizmetler"
    }
  ]
}
POST

/api/generate/stream

LangGraph pipeline sürecini Server-Sent Events (SSE) akışı aracılığıyla gerçek zamanlı olarak çalıştırır. Her LangGraph düğümü (node) çalıştırıldığında (Rakip analizi, anahat çıkarma, içerik yazımı, kalite kontrol) istemciye anlık durum güncellemeleri ve log mesajları gönderilir. Uzun süren işlemlerde istemciyle bağlantının kopmasını engeller ve kullanıcılara gerçek zamanlı ilerleme çubuğu/durum göstermek için idealdir.

İstek Parametreleri (Request Body)

Alan Adı Tip Zorunlu? Açıklama
client_id string Hayır (Öntanımlı: "dynamic-client") Müşteriyi tanımlayan tekil kimlik bilgisi.
seed_topic string Evet Üretilecek blog konusunun başlığı veya anahtar kelimesi.
client_config object (ClientConfigInput) Evet Şirket / marka detayları ve davranış tercihleri.
verified_internal_links array[object] Hayır (Boş Liste) İçeriğe doğal olarak eklenmesini istediğiniz doğrulanmış site içi linkler.
include_contact_footer boolean Hayır (Öntanımlı: false) Blog sonuna adres ve iletişim bilgileri içeren bir imza alanı eklensin mi.

SSE Olay Tipleri (Events)

Olay (event) Veri Yapısı (payload) Açıklama
start {"event": "start", "message": "..."} Süreç başlatıldığında gönderilen ilk tetikleme mesajı.
node_completed {"event": "node_completed", "node": "...", "message": "...", "data": { ... }} Her LangGraph adımı bittiğinde tetiklenir. template_render aşamasında nihai blog verisi (post, html, markdown) data parametresi altında döner.
complete {"event": "complete", "message": "..."} Tüm süreç bittiğinde dönen nihai tamamlama bildirimi.
error {"event": "error", "message": "..."} Herhangi bir aşamada hata oluştuğunda döner.
fetch('https://seo.protomind.com.tr/api/generate/stream', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'X-API-Key': 'YOUR_API_KEY'
  },
  body: JSON.stringify({
    client_id: "hanworks",
    seed_topic: "Yapay Zeka Destekli SEO Uyumlu Blog",
    client_config: {
      name: "Hanworks Agency",
      domain: "https://hanworks.com.tr",
      city: "İstanbul",
      niche: "Yazılım",
      tone: "Profesyonel",
      address: "Kadıköy, İstanbul",
      address_line: "Kadıköy, İstanbul",
      phone: "+90 216 000 0000",
      whatsapp: "+90 555 000 0000",
      email: "hello@hanworks.com.tr",
      ai_brand_profile: "Hanworks, modern web tasarımları ve SEO çözümleri geliştiren bir butik ajanstan ibarettir..."
    }
  })
})
.then(response => {
  if (!response.ok) throw new Error(`HTTP Hata: ${response.status}`);
  const reader = response.body.getReader();
  const decoder = new TextDecoder();
  let buffer = '';

  function read() {
    reader.read().then(({ done, value }) => {
      if (done) {
        console.log("Akış sonlandı.");
        return;
      }
      buffer += decoder.decode(value);
      const lines = buffer.split('\n');
      buffer = lines.pop() || '';

      for (const line of lines) {
        const cleanLine = line.trim();
        if (cleanLine.startsWith('data:')) {
          try {
            const payload = JSON.parse(cleanLine.substring(5).trim());
            console.log(`[Durum: ${payload.event}]`, payload.message);

            if (payload.event === 'node_completed') {
              if (payload.node === 'competitor_research') {
                console.log("Rakip bulguları:", payload.data.competitor_findings);
              } else if (payload.node === 'quality_check') {
                console.log("Kalite kontrol skoru:", payload.data.score);
              } else if (payload.node === 'template_render') {
                console.log("🎉 Blog Makalesi Hazır!");
                console.log("HTML İçerik:", payload.data.content_html);
                console.log("Markdown İçerik:", payload.data.final_markdown);
                console.log("Meta Bilgileri:", payload.data.post);
              }
            }
          } catch (e) {
            console.error("JSON parse hatası:", e);
          }
        }
      }
      read();
    });
  }
  read();
});
POST

/api/scan-brand

Girilen şirket bilgileri ve web sitesi ayrıntılarını (City, Tone, Niche, Domain vb.) analiz ederek yapay zeka modeline özel bir marka kimliği ve davranış profili üretir. Profil daha sonra `ClientConfigInput` altındaki `ai_brand_profile` parametresi olarak blog üretiminde kullanılarak tutarlı bir marka dili sağlanabilir.

İstek Parametreleri (Request Body)

Alan Adı Tip Zorunlu? Açıklama
client_config object (ClientConfigInput) Evet Müşterinin taranacak ve marka profili çıkarılacak web adresi ve iletişim detayları.
{
  "client_config": {
    "name": "Hanworks Agency",
    "domain": "https://hanworks.com.tr",
    "city": "İstanbul",
    "niche": "Yazılım Geliştirme",
    "tone": "Samimi ve kurumsal",
    "address": "Kadıköy, İstanbul",
    "address_line": "Kadıköy, İstanbul",
    "phone": "+90 216 000 0000",
    "whatsapp": "+90 555 000 0000",
    "email": "iletisim@hanworks.com.tr"
  }
}
GET

/api/health

Sistem durumunu, servis bağlantılarını ve konfigüre edilmiş API anahtarlarının varlığını test eder. Herhangi bir kimlik doğrulama gerektirmeyen genel (Public) bir uç noktadır.

curl -X GET "https://seo.protomind.com.tr/api/health"

Veri Modelleri Detayları

ClientConfigInput

Müşteri detaylarını ve yapay zekanın yazım davranışlarını belirleyen parametre nesnesi.

Parametre Veri Tipi Varsayılan Değer Açıklama
name string (Zorunlu) - Şirket / Marka ismi (İçerikte imza olarak ve adres kısmında yer alır).
domain string (Zorunlu) - Web sitesi adresi (İç bağlantılar için baz URL alınır).
city string (Zorunlu) - Hizmet verilen/bulunulan şehir.
country string "turkey" Bulunulan ülke.
niche string (Zorunlu) - Şirketin hizmet/sektör nişi (örn. "Yazılım Çözümleri", "Lojistik Hizmetleri").
tone string (Zorunlu) - Yazım dili / tonlaması (örn. "Samimi ve kurumsal", "Eğitici").
address string (Zorunlu) - Açık adres bilgisi.
address_line string (Zorunlu) - Kısa adres satırı (İlçe, Şehir olarak girilir).
phone string (Zorunlu) - Telefon numarası.
whatsapp string (Zorunlu) - WhatsApp iletişim numarası.
email string (Zorunlu) - E-posta adresi.
social_links array[string] [] Sosyal medya bağlantıları listesi.
reviewer_name string "" İçeriği inceleyen / onaylayan kişi ismi.
use_emoji_headers boolean true Başlıklarda konuyla alakalı emoji kullanımı.
use_emoji_in_content boolean false Gövde paragraflarında emoji kullanımı.
service_area_note string "" Hizmet bölgesine dair not (örn. "İstanbul Anadolu Yakası").
exclude_domains array[string] [] Rakip araştırmasında analiz dışı tutulacak web adresleri.
ai_brand_profile string "" Marka kimlik detaylarını barındıran metin. (Boşsa web sitesi taranarak LLM tarafından doldurulur).

GenerateRequest & VerifiedInternalLinkInput

Doğrulanmış iç bağlantıların yapısal detayları ve istek nesnesi şeması.

Parametre (VerifiedInternalLinkInput) Tipi Zorunlu? Açıklama
title string Hayır (Boşsa link URL'inden otomatik üretilir) Bağlantı (Anchor) metni (örn. "Bizimle İletişime Geçin").
path string (Zorunlu) Evet Linkin yönlendirileceği hedef URL (örn. "https://example.com/contact").

GenerateResponse

Yapay zeka blog ve SEO üretim motorundan dönen yanıt şeması.

Alan Tip Açıklama
success boolean İşlemin başarıyla tamamlandığını gösterir.
status string Yayın durumu. Kalite kontrolü (QC) başarıyla geçerse `"published"`, aksi takdirde editör onayı gerektiren `"needs_review"` değerini alır.
score float Blog içeriğinin SEO ve kalite kontrol skoru (0 - 100 arası).
issues array[string] Kalite kontrolü sırasında tespit edilen sorunların listesi (örn. "H2 başlığında eksiklik", "Kısa paragraf").
competitor_findings array[object] Rakip analizi sırasında bulunan web sitelerinin, kelime sayıları ve SEO hedeflerinin listesi.
post object (PostDataResponse) Parçalanmış ve yapılandırılmış blog içeriği nesnesi.
final_markdown string Üretilen blog yazısının ham Markdown (MD) sürümü (Frontmatter ile birlikte).
content_html string Üretilen blog yazısının HTML'e dönüştürülmüş ve başlık hiyerarşisi optimize edilmiş gövde metni.
Entegrasyon İpucu: CKEditor Entegrasyonu

Dönen content_html içeriği, tüm başlık hiyerarşisi (H2, H3), kalınlaştırmalar (strong) ve doğrulanmış iç bağlantılar ile birlikte temiz HTML formatındadır. Bu içeriği **CKEditor 5** editörüne aktarmak için aşağıdaki yöntemi kullanabilirsiniz:

// CKEditor örneği başlatıldıktan sonra veriyi set etmek için:
ClassicEditor
  .create(document.querySelector('#editor'))
  .then(editor => {
    // API'den dönen content_html değerini yükleyin
    editor.setData(response.content_html);
  })
  .catch(error => {
    console.error(error);
  });

PostDataResponse

FastAPI şemasına uyan yapılandırılmış blog makale alanları.

Alan Tip Açıklama
title string Blog makalesinin ana başlığı.
slug string URL uyumlu slug formatı (örn. "yapay-zeka-ve-seo").
excerpt string Özet/Makale giriş özeti.
category string Blog kategorisi.
keywords array[string] Makalede hedeflenen anahtar kelimeler listesi.
seo_title string Arama motorları için optimize edilmiş başlık (Meta Title).
seo_description string Arama motorları için optimize edilmiş açıklama (Meta Description).
tldr string Çok Kısa Özet (Too Long; Didn't Read).
intro_paragraph string Makalenin ilk giriş paragrafı.
h2_1_title string Makalenin ilk H2 başlığı.
h2_1_body string Makalenin ilk H2 içeriği.
h3_1_title string Varsa H3 alt başlığı.
bullet_points array[object] Makaledeki listeli / maddeli önemli noktalar (Her eleman `label` ve `text` alanlarını barındırır).
how_to object Makale içindeki yapısal adımlar ("Rehber" veya "Nasıl Yapılır" şeması). `title` ve `steps` (title, description dizisi) alanlarını içerir.
faqs array[object] Sıkça sorulan sorular (`question` ve `answer` nesne dizisi).
tip_text string Okuyuculara yönelik faydalı ipucu veya püf noktası metni.
conclusion_title string Sonuç bölümü başlığı.
closing_paragraph string Sonuç bölümü açıklama paragrafı.
hashtags array[string] Sosyal paylaşım için önerilen hashtag listesi.

Hata Kodları (Error Responses)

API servislerinin üretebileceği olası HTTP hata kodları.

HTTP Durumu Hata Tanımı Olası Sebepler
401 Unauthorized "Invalid or missing API Key..." X-API-Key veya Bearer jetonu yanlış girilmiş ya da eklenmemiş.
422 Unprocessable Entity "Validation Error" İstek gövdesi (Request Body) pydantic modellerine uygun değil veya zorunlu alanlar eksik.
500 Internal Server Error "GROQ_API_KEY is not configured..." Sunucu tarafında LLM entegrasyon anahtarları eksik veya kod çalışma hatası meydana geldi.
504 Gateway Timeout "Blog üretimi zaman aşımına uğradı" LangGraph pipeline çalışması varsayılan zaman aşımı süresini (900 saniye) aştı.