SDK
İçeriğinizi okumak ve yönetmek için gereken her şey — fazlası değil. 23 modül, 227 metot; bir öğleden sonrada öğrenilir.
npm i submitcmsHızlı başlangıç
Site token'ınızı Konsol → Entegrasyon sekmesinde bulursunuz. Ziyaretçiye içerik göstermek için tek gereken budur; oturum gerekmez.
import { SubmitCms } from 'submitcms'
const sdk = new SubmitCms({
mode: 'production',
token: process.env.SUBMIT_TOKEN!,
locale: 'tr',
})
// Ziyaretçiye içerik — oturum gerekmez
const { data, meta } = await sdk.delivery.records('blog', { per_page: 10 })
// Panel işlemleri — önce giriş
await sdk.auth.console({ email, password })
await sdk.records.create('blog', {
data: { baslik: 'Merhaba' },
status: 'published',
})Tarifler
Bir site önyüzünde en çok yapılan dört iş — her biri kopyala-çalıştır.
Arama ve filtreleme
q ile başlık/içerik/slug üzerinde tam metin arama; filter ile alan bazlı koşul; category ile kategori daraltma. Hepsi aynı listede birleşir.
const { data, meta } = await sdk.delivery.records('blog', {
q: 'kahve', // başlık, içerik ve slug'da arar
category: 'tarifler', // kategori slug'ı — 'a,b' herhangi biri
filter: { yazar: { eq: 'ayse' } },
sort: 'published_at',
dir: 'desc',
per_page: 20,
})Kategori sayfası: içerikler + ürünler
Bir kategorinin yayımlanmış her şeyi tek çağrıda gelir; yanıt içerik tipine göre gruplanmıştır. Yazılar ve ürünler aynı kategoriye bağlanabildiği için "kategorinin içerikleri" ile "kategorinin ürünleri" aynı yanıtın iki grubudur.
// Menü için kategori ağacı (kayıt sayılarıyla)
const { data: tree } = await sdk.delivery.categories()
// Kategorinin tamamı — tipe göre gruplu
const { data: page } = await sdk.delivery.category('kahve')
// page.records.blog → kategorideki yazılar
// page.records.urun → kategorideki ürünler
// page.types → bu kategoride hangi tipler var
// Yalnızca ürünlerini sayfalamak isterseniz:
const { data: urunler } = await sdk.delivery.records('urun', {
category: 'kahve',
in_stock: true,
})İçerik / ürün detayı
Slug ile tek kayıt. Ürün de bir kayıttır — tip kodu farklıdır, çağrı aynıdır. alsoRead ilgili kayıtları önerir, ping okuma süresini bildirir.
const { data: yazi } = await sdk.delivery.record('blog', 'v60-demleme')
const { data: urun } = await sdk.delivery.record('urun', 'v60-kagit-filtre')
// "Bunlar da ilginizi çekebilir"
const { data: benzer } = await sdk.delivery.alsoRead('blog', 'v60-demleme')
// Sayfadan ayrılırken okuma süresi (saniye)
await sdk.delivery.ping('blog', 'v60-demleme', 42)Site bilgisi (environment)
Sitenin adı, logosu, tasarım değerleri, dilleri ve iletişim bilgileri. Önyüz açılışında bir kez çekip layout genelinde kullanın.
const { data: site } = await sdk.delivery.environment(process.env.SUBMIT_TOKEN!)
console.log(site.title, site.locales)Kurulum
Dört paket de aynı API'yi konuşur ve birlikte sürümlenir: tek bir sürüm etiketi dördünü birden yayınlar. Paketler arasında davranış farkı yoktur, yalnızca dilin doğal biçimini izlerler.
Kimlik doğrulama
İki ayrı şey vardır ve karıştırılmamalıdır:
- Site token'ı — hangi siteye bağlandığınızı söyler, gizli bir sır değildir; her istekte kiracı kimliği olarak gider. SDK'yı kurarken verirsiniz,
SubmitTokenbaşlığıyla otomatik gönderilir.sdk.deliveryiçin tek gereken budur. - Oturum (JWT) — kullanıcının kim olduğunu söyler. İçerik yazacaksanız gerekir;
auth.login()ya daauth.console()sonrası SDK bunu kendisi yazar, sizsetAuthTokençağırmak zorunda değilsiniz.
Kullanıcının birden çok siteye eriştiği panellerde setEnvironment(token) çağırın; EnvToken yapılandırmadaki token'ı ezer.
Listeleme, arama, sayfalama
Liste uçları sayfalama bilgisini yanıtın meta alanında döner: current_page, last_page, per_page, total. per_page 1–100 arasıdır; üstü sessizce 100'e kırpılır.
Arama için q yeter — başlık, içerik ve slug'da arar. Alan filtreleri iç içe nesnedir ve sorgu dizesine filter[alan][işleç]=değer olarak açılır. İşleçler: eq, ne, gt, gte, lt, lte, like, in. Kategoriye daraltmak için category (slug, virgülle çoklu), yalnızca stoktakiler için in_stock kullanın.
const { data, meta } = await sdk.records.list('urun', {
status: 'published',
locale: 'tr',
q: 'filtre',
category: 'kahve',
filter: { price: { gte: 100 }, marka: { in: 'hario,chemex' } },
sort: 'price',
dir: 'asc',
per_page: 50,
})
console.log(`${data.length} kayıt / toplam ${meta?.total}`)İçerik modeli
Önce bir içerik tipi tanımlarsınız (alanları olan bir şema), sonra o tipte kayıt açarsınız. Kaydın özel alanları data nesnesine yazılır; şemada olmayan anahtarlar sessizce atılır, tip uymazsa 422 döner. Ürün de bir kayıttır — tipini ürün türünde açarsınız, fiyat ve stok alanları oradan gelir.
Yazma tarafı sdk.records, ziyaretçiye gösterme tarafı sdk.delivery'dir. İkincisi oturum istemez, sunucuda önbelleklenir ve yalnızca yayımlanmış kayıtları döner — site önyüzünüzde bunu kullanın.
Bir dile kayıt yazabilmek için o dilin sitenin dil listesinde olması gerekir (sdk.locales). Aksi halde panelde hiç görünmeyen "hayalet" çeviriler oluşurdu.
await sdk.contentTypes.create({
code: 'blog',
label: 'Blog Yazısı',
kind: 'content',
fields: [
{ code: 'baslik', label: 'Başlık', type: 'text', required: true },
{ code: 'icerik', label: 'İçerik', type: 'richtext' },
],
})
await sdk.records.create('blog', {
data: { baslik: 'Merhaba', icerik: '<p>…</p>' },
status: 'published',
locale: 'tr',
seo: { meta_title: 'Merhaba — Blog' },
})Hatalar
Hata yanıtları error.code alanında makine-okunur bir kod taşır. Mesaj değişebilir, kod değişmez — dallanırken kodu kullanın.
401 / 403— oturum yok, süresi dolmuş ya da yetki yetersiz.403 MODULE_DISABLED— ücretli modül kapalı (örn. ürün kataloğu). Hangi modüller açık:schema.modules(). Satın alma panelden yapılır.422— doğrulama. Alan bazlı ayrıntıerrorsiçindedir.429— istek sınırı. SDKRetry-Aftersüresine saygı duyar ve en çok üç kez yeniden dener.
Ağ hataları ve 408/500/502/503/504 üstel bekleyerek otomatik yeniden denenir. 429 bunun dışındadır: pencereyi sunucu bilir, tahmin edilmez.
Framework örnekleri
Aynı iş her framework'te: blog listesini çek, bas. Kendi projenize en yakın olandan başlayın.
import { SubmitCms } from 'submitcms'
const sdk = new SubmitCms({
mode: 'production',
token: process.env.SUBMIT_TOKEN!,
locale: 'tr',
})
export default async function BlogPage() {
const { data: posts } = await sdk.delivery.records('blog', { per_page: 10 })
return (
<ul>
{posts.map((post) => (
<li key={post.id}>
<a href={`/blog/${post.slug}`}>{post.data.baslik}</a>
</li>
))}
</ul>
)
}Referans
SDK'nın tamamı budur — 23 modül, 227 metot. submit.api rota tablosundan üretildi (test@502a041); her metodun karşılığı kaynakta doğrulanır.
sdk.addresses
4 metotKullanıcı adresleri.
/api/user/addresses ve /api/shopping/addresses aynı işi görür; SDK
ilkini kullanır.
sdk.ai
6 metotYapay zekâ kredileri.
Her AI çağrısı (metin iyileştirme, çeviri, SEO, görsel üretimi) kredi harcar. Bakiye yetmezse ilgili uç 402 döner.
sdk.auth
26 metotKimlik doğrulama, hesap ve oturum işlemleri.
Başarılı login/register sonrası JWT istemciye otomatik yazılır — ayrıca
setAuthToken çağırmanız gerekmez. logout da temizler.
sdk.billing
6 metotAbonelik ve fatura profilleri (SaaS tarafı).
sdk.cart
6 metotZiyaretçi sepeti — mağaza önyüzü.
Oturum gerekmez; misafir sepeti X-Guest-Id ile taşınır
(client.setGuestId(...)). ecommerce modülü kapalıysa uçlar 403 döner.
sdk.categories
4 metotKayıt kategorileri — ağaç yapısını parent_id kurar.
sdk.contentTypes
9 metotİçerik tipleri — sitenin veri şeması.
Bir tip tanımlarsınız (örn. blog, alanları: başlık, görsel, içerik), sonra
sdk.records ile o tipte kayıt açarsınız. Şema değişiklikleri sürümlenir;
eski kayıtlar hangi sürümle yazıldıysa onu taşır.
sdk.delivery
32 metotGenel teslimat — sitenizin ziyaretçilere gösterdiği her şey.
Bu modülün tamamı yalnızca site token'ı ister; oturum gerekmez. Sunucuda önbelleklenir ve yalnızca yayımlanmış içeriği döndürür. Bir sitenin önyüzünü kuruyorsanız neredeyse tek ihtiyacınız budur.
sdk.locales
3 metotSitenin dilleri.
Bir dil burada tanımlı değilse o dilde kayıt yazılamaz (422) — bu, panelde hiç görünmeyen "hayalet" çevirileri engeller.
sdk.myOrders
4 metotMüşterinin kendi siparişleri — son kullanıcı hesabı için.
sdk.orders
10 metotSipariş yönetimi (satıcı tarafı).
orders modülü açık olmalıdır — kapalıysa 403. Oturum ve site üyeliği ister.
sdk.partner
25 metotPartner paneli — bayi/ajans tarafı.
Partner kendi müşterilerini, paketlerini ve tahsilatını yönetir. Bu uçlar partner rolündeki oturum ister.
sdk.payments
4 metotÖdemeler. Stripe/Tami webhook uçları sunucu-sunucu olduğu için SDK'da yoktur.
sdk.platform
25 metotMüşterinin kendi sitesini yönettiği self-servis uçlar (platform/my).
Site üyeliği zorunludur — başka bir sitenin verisine erişilemez.
sdk.records
19 metotsdk.reservations
15 metotRezervasyon yönetimi (panel tarafı).
Oturum ister ve reservations modülü açık olmalıdır. Ziyaretçi tarafı
(müsaitlik sorgusu ve talep gönderme) oturumsuzdur ve
sdk.delivery.reservations altındadır.
Rezerve edilen şey bir KAYITTIR: otel odası, doktor, masa, tur — hepsi kendi
içerik tipinde birer kayıt. Bir kaydı rezervasyona AÇAN şey settings.save()
çağrısıdır; ayarı olmayan kayıtta müsaitlik not_reservable döner.
sdk.schema
4 metotŞema sistemine dair yardımcı uçlar.
sdk.shopping
9 metotEski sepet/checkout uçları (/api/shopping/*).
Yeni entegrasyonlarda sdk.cart kullanın. Bunlar hâlen canlıdır ve eski
mağazalar için ayaktadır; kupon ve kargo seçenekleri şu an yalnızca burada.
sdk.storage
2 metotDosya yükleme.
File/Blob verirseniz SDK multipart/form-data kurar. Node tarafında
Buffer yerine Blob ya da bir stream sarmalayıcı kullanın.
sdk.system
1 metotServis durumu. İzleme (uptime) kontrolleri için.
sdk.tickets
3 metotDestek talepleri gelen kutusu — sitenizin iletişim/destek formlarına düşenler.
OKUMA tarafıdır ve oturum ister (panel yetkisi): site token'ı tek başına
yetmez, kullanıcı o sitenin üyesi olmalı ve tickets modülü açık olmalıdır.
Talebi OLUŞTURAN taraf ziyaretçidir ve oturumsuzdur — bunun için
sdk.delivery.submitTicket() / sdk.delivery.ticketForm() kullanılır.
sdk.tracking
2 metotZiyaretçi takibi ve hata bildirimi.
Site token'ı yeter, oturum gerekmez. Yolculuk kayıtları panelde Admin → Site Hareketleri ekranında görünür.