Posts API
Bu sayfa yazılarla ilgili her şeyi kapsıyor: liste çekmek, tek bir yazıyı okumak, yeni yazı oluşturmak, güncellemek, silmek. n8n'den taslak fırlatıyorsanız, mobil uygulamanız akışı çekiyorsa ya da dışarıdan içerik gönderiyorsanız — işiniz burada.
Tüm uç noktalar /api/v1/posts altında. Her istekte Authorization: Bearer ... header'ı gönderiyorsunuz ve token'ınızın ilgili posts:* kapsamına sahip olması gerekiyor.
Yazıları listele
GET /api/v1/posts
Kapsam: posts:read.
Elinize aldığınızda filtreleyebileceğiniz şeyler:
status—draft,scheduled,published(varsayılan),archivedcategory— slug veya IDauthor— kullanıcı ID'sisearch— başlık ve içerikte kelime aramasıpage— sayfa numarası (1'den başlar)per_page— sayfa başına öğe, en fazla 100 (varsayılan 20)order_by—published_at,updated_at,titleorder—ascveyadesc
Denemek için:
curl -H "Authorization: Bearer YOUR_TOKEN" \
"https://yoursite.com/api/v1/posts?status=published&category=nutrition&per_page=50"
Cevap iki anahtarlı bir JSON döner — data (yazı dizisi) ve pagination (sayfa bilgisi). Her yazı bu alanları içerir: id, title, slug, status, excerpt, content_html, content_markdown, author nesnesi, categories dizisi, tags, featured_image nesnesi (url + genişlik + yükseklik), published_at, updated_at ve son izleyicinin paylaşacağı hazır url.
{
"data": [
{
"id": 123,
"title": "10 high-protein breakfasts",
"slug": "high-protein-breakfasts",
"status": "published",
"excerpt": "Start your day with...",
"content_html": "<p>...</p>",
"author": { "id": 1, "name": "Ada Lovelace" },
"categories": [ { "id": 3, "slug": "nutrition", "name": "Nutrition" } ],
"tags": [ "protein", "breakfast" ],
"featured_image": { "id": 45, "url": "https://.../cover.jpg", "width": 1600, "height": 900 },
"published_at": "2026-04-10T09:00:00Z",
"url": "https://yoursite.com/blog/high-protein-breakfasts"
}
],
"pagination": { "page": 1, "per_page": 50, "total": 237, "total_pages": 5 }
}
Tek bir yazıyı getir
GET /api/v1/posts/{id}
Hem sayısal ID hem de slug kabul eder, ne elinizdeyse yollayın:
curl -H "Authorization: Bearer YOUR_TOKEN" \
https://yoursite.com/api/v1/posts/high-protein-breakfasts
Liste öğesiyle aynı şekli dönen tek farkı content_html ve content_markdown alanlarının burada tam içerikle dolu gelmesi.
Yazı oluştur
POST /api/v1/posts
Content-Type: application/json
Kapsam: posts:write. En azından title ve içerik (content_markdown veya content_html) göndermeniz gerekir; geri kalan her şey opsiyonel:
{
"title": "My new post",
"content_markdown": "# Hello\n\nThis is the body...",
"status": "draft",
"categories": [ "nutrition" ],
"tags": [ "protein", "breakfast" ],
"featured_image_id": 45,
"seo": {
"title": "Optional SEO title",
"description": "Optional SEO description"
}
}
status üç değerden biri olabilir: draft, scheduled, published. scheduled seçerseniz ileri tarihli bir published_at de göndermeniz lazım — yoksa sunucu hangi zamanda yayınlanacağını bilemez.
Başarılı olursa 201 Created ve GET ile aynı şekle sahip tam yazı nesnesi döner. id, slug, render edilmiş content_html ve url sunucu tarafında doldurulur.
Yazı güncelle
PUT /api/v1/posts/{id}
Kısmi güncelleme çalışıyor — yalnızca değiştirmek istediğiniz alanları gönderin, diğerleri olduğu gibi kalır. Bir taslağı yayına almak bu kadar basit:
{ "status": "published" }
Başarıda 200 OK ve güncel yazı gelir.
Yazı sil
DELETE /api/v1/posts/{id}
Varsayılanda soft delete yapar — yazının status'u archived olur, herkese açık görünümden kaybolur ama DB'de durur. Gerçekten kalıcı silmek istiyorsanız URL'ye ?hard=true ekleyin (bu DB satırını siler; medya ve yorumlar dokunulmaz).
Başarıda 204 No Content — gövde yoktur.
Hata kodları
| Kod | Ne demek | |------|---------| | 400 | İstek gövdesi geçersiz (eksik alan, yanlış tip) | | 401 | Token yok, geçersiz veya süresi dolmuş | | 403 | Token'ın bu kapsamı yok ya da IP kısıtlı | | 404 | Böyle bir yazı yok | | 409 | Slug çakışması (sunucu genelde kendi çözer) | | 422 | Doğrulama hatası — fields içinde tek tek hangi alanın sorunlu olduğunu görürsünüz | | 429 | Hız sınırını aştınız — Retry-After header'ına bakıp o kadar bekleyin | | 500 | Bizde bir şey koptu — X-Request-Id header'ını destek birimine iletin |
Hata gövdesi şöyle görünür:
{
"error": "validation_failed",
"message": "one or more fields are invalid",
"fields": {
"title": "required",
"status": "must be one of: draft, scheduled, published"
}
}
Pratik örnek: n8n'den taslak oluştur
Tipik bir senaryo — bir yerden (Google Form, Airtable, Slack komutu) { title, content } geliyor, bunu taslak olarak jekcms'e atmak istiyorsunuz:
- Webhook node — POST, path
/new-draft - HTTP Request node — Method POST, URL
https://yoursite.com/api/v1/posts, Header Auth ileAuthorization: Bearer {{$credentials.jekcmsToken}}, gövde:
{
"title": "={{ $json.title }}",
"content_markdown": "={{ $json.content }}",
"status": "draft",
"categories": ["auto-import"],
"tags": ["from-webhook"]
}
- Respond to Webhook — çağıran kişi taslak URL'sini hemen görsün diye
{{ $node["HTTP Request"].json.url }}döndürün.
HTTP Request node'unda Retry on fail seçeneğini açmayı unutmayın (3 deneme, üstel geri çekilme). Geçici ağ hıçkırıkları gönderileri düşürmesin.