Nasıl çalışır
Bu yöntem pull modelidir: içerik Seomio'da durur, siteniz ihtiyaç duydukça API'den okur. Sitenizde yeni bir yazma ucu açmanız, veritabanı alanı eklemeniz gerekmez — mevcut şablonunuza bir liste ve bir detay sayfası bağlamanız yeterlidir.
Bu yöntem şuralarda iyi
- • Statik/JAMstack siteler (Next.js, Nuxt, Astro)
- • Blog bölümünü tamamen Seomio'ya bırakmak isteyenler
- • Kendi şablonunuzda tam kontrol istediğiniz durumlar
Webhook daha uygun olabilir
- • İçeriğin kendi veritabanınızda durmasını istiyorsanız
- • Yayın anında bildirim/otomasyon tetiklemek istiyorsanız
- • Site tarafında dış servise bağımlı kalmak istemiyorsanız
Kimlik doğrulama
Tüm istekler secret key ile kimliklenir. Anahtar sizin çalışma alanınızı temsil eder; yalnızca kendi yayınlanmış içeriklerinize erişim verir.
- 1
Anahtarınızı alın
Panel → Ayarlar → Çalışma Alanı ekranında Secret Key alanını kopyalayın. - 2
Sunucu tarafında saklayın
Anahtarı ortam değişkenine koyun (SEOMIO_SECRET_KEY). Tarayıcıya düşen hiçbir koda yazmayın — anahtar herkese açık olursa üçüncü kişiler de içeriklerinizi çekebilir. - 3
Her isteğe başlık olarak ekleyin
x-secret-key: <anahtar>veyaAuthorization: Bearer <anahtar>— ikisi de kabul edilir.
Anahtarı istemci tarafında kullanmayın
fetch çağrınız tarayıcıda çalışıyorsa anahtar herkese görünür. Çağrıyı sunucu bileşeninde, API route'unda veya build sırasında yapın; tarayıcıya yalnızca hazır içeriği gönderin.Temel bilgiler
Tüm uç noktalar aynı zarf yapısını kullanır; hata durumunda da aynı biçim döner.
| Alan | Tip | Açıklama |
|---|---|---|
| Temel adres | URL | https://api.seomio.com.tr |
| Metot | HTTP | Yalnızca GET — bu uçlar salt okunurdur. |
| success | boolean | Her yanıtın ilk alanı. false ise data yerine message alanına bakın. |
| data | array | object | Liste uçlarında dizi, detay ucunda tek nesne. |
| pagination | object | Yalnızca liste ucunda: total, page, limit, pages. |
| Kapsam | — | Yalnızca yayınlanmış (published) yazılar döner. Taslak, arşiv ve silinmiş içerikler API'de görünmez. |
Blog listesi
Yayınlanmış yazıları sayfalanmış olarak, en yeniden eskiye doğru döndürür.
/api/public/blog| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| x-secret-key | header | Evet | Çalışma alanı anahtarınız (veya Authorization: Bearer). |
| page | number | Hayır | Sayfa numarası. Varsayılan: 1. |
| limit | number | Hayır | Sayfa başına kayıt. Varsayılan: 20. |
| language | string | Hayır | Dil kodu ile filtre (tr, en…). Çok dilli üretim kullanıyorsanız her dil için ayrı liste çekebilirsiniz. |
curl -X GET "https://api.seomio.com.tr/api/public/blog?page=1&limit=10" \
-H "x-secret-key: SIZIN_SECRET_KEYINIZ"{
"success": true,
"data": [
{
"_id": "6840f1c2a91b4e0012ab77d3",
"title": "PVC Zemin Bakımı: Dayanıklılığı Nasıl Korursunuz?",
"slug": "pvc-zemin-bakimi",
"excerpt": "PVC zeminlerin ömrünü uzatan bakım adımları.",
"keyword": "pvc zemin bakımı",
"coverImageUrl": "https://cdn.seomio.com.tr/blog-images/cover-8f21.png",
"publishedDate": "2026-08-19T09:00:00.000Z",
"readingTimeMinutes": 8,
"wordCount": 1850,
"language": "tr",
"createDate": "2026-08-18T21:14:03.000Z"
}
],
"pagination": {
"total": 42,
"page": 1,
"limit": 10,
"pages": 5
}
}Liste yanıtı hafiftir
content alanı gelmez — yazının tam HTML gövdesi yalnızca detay ucundadır. Liste sayfanızı kart görünümü için gereken alanlarla (title, excerpt, coverImageUrl, readingTimeMinutes) kurun.Blog detayı
Tek bir yazıyı slug değeriyle, tam HTML gövdesi ve SEO alanlarıyla birlikte getirir.
/api/public/blog/{slug}| Alan | Tip | Zorunlu | Açıklama |
|---|---|---|---|
| x-secret-key | header | Evet | Çalışma alanı anahtarınız. |
| slug | path | Evet | Liste yanıtındaki slug değeri — kendi URL yapınızda da bunu kullanmanız önerilir. |
curl -X GET "https://api.seomio.com.tr/api/public/blog/pvc-zemin-bakimi" \
-H "x-secret-key: SIZIN_SECRET_KEYINIZ"{
"success": true,
"data": {
"_id": "6840f1c2a91b4e0012ab77d3",
"title": "PVC Zemin Bakımı: Dayanıklılığı Nasıl Korursunuz?",
"slug": "pvc-zemin-bakimi",
"content": "<div class=\"key-takeaways\">...</div><h2>Giriş</h2><p>...</p>",
"excerpt": "PVC zeminlerin ömrünü uzatan bakım adımları.",
"keyword": "pvc zemin bakımı",
"secondaryKeywords": ["pvc zemin temizliği", "pvc zemin ömrü"],
"metaTitle": "PVC Zemin Bakımı | Marka",
"metaDescription": "PVC zemin bakımı için pratik ve uzman önerileri.",
"coverImageUrl": "https://cdn.seomio.com.tr/blog-images/cover-8f21.png",
"wordCount": 1850,
"readingTimeMinutes": 8,
"seoScore": 87,
"language": "tr",
"publishedDate": "2026-08-19T09:00:00.000Z"
}
}| Alan | Tip | Açıklama |
|---|---|---|
| content | string (HTML) | Tam HTML gövde. Gövde görselleri (CDN mutlak URL), "İlgili İçerikler" bölümü ve JSON-LD yapısal verisi gömülüdür. Şablonunuzda olduğu gibi basmanız yeterlidir. |
| metaTitle / metaDescription | string | Sayfanızın <title> ve meta description değerleri için hazır. |
| coverImageUrl | string (URL) | Kapak görselinin mutlak CDN adresi — öne çıkan görsel olarak kullanın. |
| secondaryKeywords | string[] | İkincil anahtar kelimeler — etiket/ilgili içerik kurgusu için kullanılabilir. |
| readingTimeMinutes / wordCount | number | Okuma süresi ve kelime sayısı. |
| seoScore | number | null | Seomio'nun kendi on-page SEO puanı (0–100). Gösterme zorunluluğu yoktur. |
| language | string | Yazının dili. |
| publishedDate | string (ISO 8601) | Yayın tarihi. |
Yanıtta gördüğünüzden fazla alan olabilir
Hata kodları
Hatalar da aynı JSON zarfıyla döner.
{
"success": false,
"message": "Invalid secret key"
}| Kod | Anlamı | Ne yapmalı |
|---|---|---|
| 401 | Anahtar başlığı hiç gönderilmemiş | x-secret-key başlığını ekleyin. |
| 403 | Anahtar geçersiz veya çalışma alanı aktif değil | Panelden anahtarı yeniden kopyalayın; abonelik durumunu kontrol edin. |
| 404 | Bu slug ile yayınlanmış bir yazı yok | Yazı taslak/arşiv olabilir ya da slug değişmiştir; listeden güncel slug'ı alın. |
| 500 | Sunucu tarafı hata | Kısa bir süre sonra tekrar deneyin; sürerse bize iletin. |
Örnek entegrasyonlar
Anahtarın sunucuda kaldığı, önbellekli ve hataya dayanıklı kullanım kalıpları.
// lib/seomio.ts — anahtar YALNIZCA sunucu tarafında kullanılır
const BASE = "https://api.seomio.com.tr";
async function seomio(path: string) {
const res = await fetch(BASE + path, {
headers: { "x-secret-key": process.env.SEOMIO_SECRET_KEY as string },
// İçerik sık değişmiyor; 1 saatlik önbellek hem hızlı hem ekonomik
next: { revalidate: 3600 }
});
if (!res.ok) throw new Error("Seomio API hatası: " + res.status);
const json = await res.json();
if (!json.success) throw new Error(json.message || "Bilinmeyen hata");
return json;
}
export async function getPosts(page = 1, limit = 12) {
const json = await seomio("/api/public/blog?page=" + page + "&limit=" + limit);
return { posts: json.data, pagination: json.pagination };
}
export async function getPost(slug: string) {
const json = await seomio("/api/public/blog/" + slug);
return json.data;
}// app/blog/[slug]/page.tsx
import { getPost } from "@/lib/seomio";
export default async function BlogDetail({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return (
<article>
<h1>{post.title}</h1>
{post.coverImageUrl && <img src={post.coverImageUrl} alt={post.title} />}
{/* content tam HTML gövdedir: görseller, iç linkler ve JSON-LD gömülü gelir */}
<div dangerouslySetInnerHTML={{ __html: post.content }} />
</article>
);
}
export async function generateMetadata({ params }: { params: { slug: string } }) {
const post = await getPost(params.slug);
return {
title: post.metaTitle || post.title,
description: post.metaDescription || post.excerpt
};
}<?php
// seomio.php — anahtarı .env / config dosyasında tutun, şablona sızdırmayın
function seomio_get($path) {
$ch = curl_init('https://api.seomio.com.tr' . $path);
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['x-secret-key: ' . getenv('SEOMIO_SECRET_KEY')],
CURLOPT_TIMEOUT => 15,
]);
$body = curl_exec($ch);
$status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if ($status !== 200) {
return null;
}
$json = json_decode($body, true);
return isset($json['success']) && $json['success'] ? $json : null;
}
// Liste
$list = seomio_get('/api/public/blog?page=1&limit=12');
$posts = $list ? $list['data'] : [];
// Detay
$detail = seomio_get('/api/public/blog/pvc-zemin-bakimi');
$post = $detail ? $detail['data'] : null;Yayın ipuçları
Çektiğiniz içerikten SEO açısından tam verim almanız için.
- Önbellek kullanın. İçerik dakika dakika değişmez; 30–60 dakikalık bir önbellek (ISR/CDN) hem sayfa hızını hem dayanıklılığı artırır.
- JSON-LD'yi ikinci kez eklemeyin.
contentiçinde Article/FAQ/Breadcrumb yapısal verisi zaten gömülüdür; şablonunuzda aynı türden ikinci bir JSON-LD basmak çakışma yaratır. - slug'ı koruyun. Kendi URL'nizde Seomio'daki slug'ı kullanırsanız iç linkler ve "İlgili İçerikler" bölümündeki bağlantılar doğru sayfalara düşer.
- metaTitle / metaDescription'ı kullanın. Bu alanlar anahtar kelimeye göre üretilir; başlığı kendi şablon ekinizle uzatmak yerine olduğu gibi kullanmak daha iyi sonuç verir.
- Görselleri indirmek zorunda değilsiniz. Kapak ve gövde görselleri CDN üzerinden mutlak URL ile gelir ve kimlik doğrulama gerektirmez. Kendi medya kitaplığınıza almak isterseniz de serbestsiniz.
- Sitemap'inize ekleyin. Liste ucundaki
slugvepublishedDatealanlarıyla sitemap üretmek, indekslenmeyi hızlandırır.
Panelde canlı deneyin