Skip to content

Platform API Referansı

Coursio platformundaki tüm API'lerin ne için ve nasıl kullanıldığı — REST endpoint'leri, istek/yanıt formatları, yetkilendirme ve örnekler.

Bu sayfa Coursio platformunun kendi API dokümantasyonudur. Backend ve full-stack geliştiricilerin tüm API’leri ne için kullanacaklarını, hangi parametreleri göndereceklerini ve ne tür yanıt alacaklarını tek yerden görmesini sağlar. Her endpoint için amaç, yetkilendirme, istek formatı, yanıt ve örnek çağrı verilir.


  • Base URL: Uygulama kökü (yerelde http://localhost:5173 veya http://localhost:8787; production’da https://lms.techsider.co). API path’leri dil prefix’i içermez (/api/...).
  • Kimlik doğrulama: Çoğu endpoint session cookie (Better Auth) ile korunur. İstekte Cookie header’ı otomatik gönderilir; fetch ile çağırırken credentials: "include" kullanın.
  • Hata yanıtları: 400 (geçersiz istek), 401 (giriş gerekli), 403 (yetkisiz), 404 (bulunamadı), 500 (sunucu hatası). Gövde genelde { "error": "mesaj" } veya düz metin.

ÖzellikDeğer
PathPOST /api/graphql (GET desteklenir; GraphiQL/playground)
Dosyaapp/routes/api.graphql.ts
AmaçTüm veri okuma (courses, me, enrollments, certificates vb.) ve mutation’lar (createCourse, addToCart, toggleLessonCompletion vb.) GraphQL üzerinden yapılır.
YetkilendirmeSession cookie; resolver içinde context.user ile rol ve yetki kontrolü.

İstek (POST):

  • Header: Content-Type: application/json
  • Body: { "query": "string", "variables": { ... } }
  • Cookie: Session cookie (credentials: “include”)

Yanıt: 200{ "data": { ... } } veya { "errors": [ { "message": "..." } ] }

Örnek:

Terminal window
curl -X POST "https://lms.techsider.co/api/graphql" \
-H "Content-Type: application/json" \
-d '{"query":"query { me { id email name role } }"}' \
--cookie "better-auth.session_token=..."

Şema ve tipler: app/graphql/schema.ts — typeDefs + resolvers. Detay için API Referansı ve GraphQL sayfasına bakın.


ÖzellikDeğer
Path/api/auth/* (tüm alt path’ler)
Dosyaapp/routes/api.auth.tsauth.handler(request)
AmaçGiriş, kayıt, çıkış, OAuth (Google), e-posta doğrulama, şifre sıfırlama, session yönetimi.
YetkilendirmePublic (giriş/kayıt); session gerektiren path’ler Better Auth tarafından yönetilir.

Kullanım: Better Auth client (app/lib/auth-client.ts) ile signIn.email, signUp.email, signOut vb. çağrılır. Doğrudan REST çağrısı yerine SDK kullanılır. Path örnekleri: /api/auth/sign-in/email, /api/auth/sign-up/email, /api/auth/sign-out, /api/auth/callback/google. Detay: API Referansı ve GraphQL — Better Auth.


ÖzellikDeğer
PathPOST /api/stripe/webhook
Dosyaapp/routes/api.stripe.webhook.ts
AmaçStripe’dan gelen olayları işlemek: ödeme tamamlandı (checkout.session.completed), abonelik, payment_intent vb. Enrollment oluşturma, earnings kaydı, e-posta bildirimi burada yapılır.
YetkilendirmeStripe-Signature header ile imza doğrulama; cookie/session yok. Sadece Stripe bu endpoint’e istek atar.

İstek:

  • Header: Stripe-Signature: ... (Stripe tarafından eklenir)
  • Body: Raw (text); Stripe event JSON. Doğrulama için body olduğu gibi kullanılır.

Yanıt: 200 — başarı; 400 — imza hatası veya geçersiz body.

Not: Bu endpoint’i uygulama içinden çağırmazsınız; Stripe Dashboard’da webhook URL olarak tanımlanır. Yerelde test için stripe listen --forward-to localhost:8787/api/stripe/webhook kullanılır.


ÖzellikDeğer
PathPOST /api/stripe/connect-onboarding
Dosyaapp/routes/api.stripe.connect-onboarding.ts
AmaçEğitmeni Stripe Connect Express hesabına yönlendirmek. Hesap yoksa oluşturulur; Account Link ile Stripe onboarding sayfasına redirect döner.
YetkilendirmeSession gerekli; user.role === "instructor". Değilse 401/403.

İstek: POST; body boş veya form. Session cookie gerekli.

Yanıt: 302 Redirect — Stripe Account Link URL’ine yönlendirme. Hata: 401 (giriş gerekli), 403 (sadece eğitmen), 500 (STRIPE_SECRET_KEY veya BASE_URL eksik).

Örnek (form submit):

<form action="/api/stripe/connect-onboarding" method="POST">
<button type="submit">Stripe Hesabını Bağla</button>
</form>

ÖzellikDeğer
PathPOST /api/instructor/update-manual-payout
Dosyaapp/routes/api.instructor.update-manual-payout.ts
AmaçTürkiye’deki eğitmenin IBAN veya Payoneer bilgisini güncellemek. users.manualPayoutDetails ve users.payoutMethod = 'bank_transfer' yazılır.
YetkilendirmeSession + user.role === "instructor".

İstek:

  • Method: POST
  • Content-Type: application/x-www-form-urlencoded veya multipart/form-data
  • Body (FormData): details (string) — IBAN veya Payoneer e-posta adresi.

Yanıt: 302 Redirect — Referer veya /tr/instructor/payouts. Hata: 401, 403 (sadece eğitmen), 404 (kullanıcı bulunamadı), 500.

Örnek:

Terminal window
curl -X POST "https://lms.techsider.co/api/instructor/update-manual-payout" \
-H "Cookie: better-auth.session_token=..." \
-F "details=TR00 0000 0000 0000 0000 0000 00"

ÖzellikDeğer
PathPOST /api/lesson-resource-upload
Dosyaapp/routes/api.lesson-resource-upload.ts
AmaçDerse PDF vb. kaynak dosyası yüklemek; Bunny Storage’a yazılır. Yükleme sonrası dönen fileUrl ile lesson_resources tablosuna kayıt uygulama tarafında yapılabilir.
YetkilendirmeBu endpoint’te session kontrolü yok; çağıran sayfa (eğitmen müfredat sayfası) session ile korunur. İsteğe bağlı olarak action içinde eğitmen ve ders sahipliği kontrolü eklenebilir.

İstek:

  • Method: POST
  • Content-Type: multipart/form-data
  • Body (FormData):
    • lessonId (string) — Ders UUID.
    • file (File) — Yüklenecek dosya.

Yanıt (başarı): 200{ "title": "dosya.pdf", "fileUrl": "https://...", "fileSize": 12345, "fileType": "application/pdf" }
Hata: 400 (lessonId veya file eksik), 500 (Bunny ayarları eksik), 502 (Bunny yükleme hatası).

Ortam değişkenleri: BUNNY_STORAGE_ZONE, BUNNY_STORAGE_KEY, BUNNY_PULL_ZONE_URL.


ÖzellikDeğer
PathPOST /api/chat-image-upload
Dosyaapp/routes/api.chat-image-upload.ts
AmaçMesajda gönderilecek görseli yüklemek; Bunny Storage chat-media/ altına yazılır. Dönen URL mesaj içinde kullanılır.
YetkilendirmeBu endpoint’te session kontrolü yok; mesaj sayfası session ile korunur. İsteğe bağlı action içinde session kontrolü eklenebilir.

İstek:

  • Method: POST
  • Content-Type: multipart/form-data
  • Body (FormData): file (File) — Görsel; tipler: image/jpeg, image/png, image/gif, image/webp.

Yanıt (başarı): 200{ "url": "https://pullzone.../chat-media/xxx.jpg" }
Hata: 400 (dosya yok veya tip uygun değil), 500 (Bunny ayarları eksik), 502 (yükleme hatası).


ÖzellikDeğer
PathGET /api/certificate/:id/download veya GET /api/certificates/:id/download
Dosyaapp/routes/api.certificate.$id.download.ts
AmaçKullanıcının sertifika kaydına ait PDF’i indirmek. Sertifika userId ile eşleşmeli.
YetkilendirmeSession gerekli; sertifika sahibi (certificates.userId === session.user.id) olmalı.

İstek: GET; path parametresi id — sertifika UUID.

Yanıt (başarı): 200Content-Type: application/pdf, Content-Disposition: attachment; filename="certificate-xxx.pdf". Gövde PDF stream.
Hata: 401 (giriş gerekli), 404 (sertifika bulunamadı veya yetkisiz), 500.


ÖzellikDeğer
PathGET /api/invoice/:enrollmentId/download
Dosyaapp/routes/api.invoice.$enrollmentId.download.ts
AmaçKullanıcının bir enrollment’ına ait fatura PDF’ini indirmek. Aynı checkout session’daki tüm kalemler tek faturada gösterilir.
YetkilendirmeSession gerekli; enrollment sahibi (enrollments.userId === session.user.id) olmalı.

İstek: GET; path parametresi enrollmentId — enrollment UUID.

Yanıt (başarı): 200Content-Type: application/pdf, Content-Disposition: attachment. Gövde PDF.
Hata: 400 (enrollmentId eksik), 401 (giriş gerekli), 404 (enrollment bulunamadı veya yetkisiz), 500.


ÖzellikDeğer
PathGET /api/admin/activities
Dosyaapp/routes/api.admin.activities.ts
AmaçAdmin “Tüm bildirimler” modalı için ödeme talepleri ve kurs onayları gibi aktiviteleri JSON olarak döndürmek (en fazla 500 kayıt).
YetkilendirmeSession + user.role === "admin".

İstek: GET; session cookie gerekli.

Yanıt (başarı): 200{ "activities": [ { "id", "type", "title", "createdAt", ... } ] }
Hata: 401 (giriş gerekli), 403 (sadece admin), 500.

Örnek:

Terminal window
curl "https://lms.techsider.co/api/admin/activities" \
-H "Cookie: better-auth.session_token=..."

ÖzellikDeğer
PathPOST /api/update-progress
Dosyaapp/routes/api.update-progress.ts
Amaçİzlenen video süresini (saniye) kaydetmek. user_lessons_progress.watchedSeconds artar; daily_activities (streak); abonelik ise subscription_watch_logs güncellenir.
YetkilendirmeBu endpoint’te session kontrolü yok; body’de userId gönderilir. Çağıran taraf (learn sayfası) session ile korunur; güvenlik için ileride session’dan userId alınması önerilir.

İstek:

  • Method: POST
  • Content-Type: application/json
  • Body: { "userId": "uuid", "lessonId": "uuid", "courseId": "uuid", "instructorId": "uuid", "secondsWatched": number, "isSubscription": boolean }
    • secondsWatched > 0 olmalı.

Yanıt (başarı): 200{ "success": true }
Hata: 400 (Invalid payload — eksik/geçersiz alan), 500.

Örnek:

Terminal window
curl -X POST "https://lms.techsider.co/api/update-progress" \
-H "Content-Type: application/json" \
-d '{"userId":"...","lessonId":"...","courseId":"...","instructorId":"...","secondsWatched":60,"isSubscription":false}'

EndpointMethodAmaçYetki
/api/graphqlPOSTGraphQL sorgu/mutationSession (resolver bazlı)
/api/auth/**Giriş, kayıt, OAuth, sessionPublic / Better Auth
/api/stripe/webhookPOSTStripe olayları (ödeme, abonelik)Stripe-Signature
/api/stripe/connect-onboardingPOSTStripe Connect onboarding redirectInstructor
/api/instructor/update-manual-payoutPOSTTR manuel ödeme bilgisi (IBAN/Payoneer)Instructor
/api/lesson-resource-uploadPOSTDers kaynağı yükleme (Bunny)FormData: lessonId, file
/api/chat-image-uploadPOSTSohbet görseli yükleme (Bunny)FormData: file
/api/certificate/:id/downloadGETSertifika PDF indirmeSession, sertifika sahibi
/api/certificates/:id/downloadGETAynı (geriye dönük URL)Aynı
/api/invoice/:enrollmentId/downloadGETFatura PDF indirmeSession, enrollment sahibi
/api/admin/activitiesGETAdmin aktivite listesi (JSON)Admin
/api/update-progressPOSTVideo izleme süresi kaydıBody: userId, lessonId, …

GraphQL — Önemli Sorgular ve Mutation’lar

Section titled “GraphQL — Önemli Sorgular ve Mutation’lar”

Şema tam listesi app/graphql/schema.ts içindedir. Sık kullanılanlar:

  • Query: me, courses, courseBySlug, myCertificates, conversationMessages, unreadMessagesCount, adminCourses, adminPayoutRequests vb.
  • Mutation: createCourse, updateCourse, toggleLessonCompletion, recordLearningActivity, requestPayout, createStripeCheckoutSession, addToCart, createReview, updatePayoutSettings vb.

İstemci örneği: app/lib/graphql-client.tsfetch("/api/graphql", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, variables }), credentials: "include" }).