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.
Genel Bilgiler
Section titled “Genel Bilgiler”- Base URL: Uygulama kökü (yerelde
http://localhost:5173veyahttp://localhost:8787; production’dahttps://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
Cookieheader’ı otomatik gönderilir;fetchile çağırırkencredentials: "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.
REST API’ler
Section titled “REST API’ler”1. GraphQL — Sorgu ve Mutation
Section titled “1. GraphQL — Sorgu ve Mutation”| Özellik | Değer |
|---|---|
| Path | POST /api/graphql (GET desteklenir; GraphiQL/playground) |
| Dosya | app/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. |
| Yetkilendirme | Session 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:
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.
2. Better Auth — Kimlik Doğrulama
Section titled “2. Better Auth — Kimlik Doğrulama”| Özellik | Değer |
|---|---|
| Path | /api/auth/* (tüm alt path’ler) |
| Dosya | app/routes/api.auth.ts → auth.handler(request) |
| Amaç | Giriş, kayıt, çıkış, OAuth (Google), e-posta doğrulama, şifre sıfırlama, session yönetimi. |
| Yetkilendirme | Public (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.
3. Stripe Webhook
Section titled “3. Stripe Webhook”| Özellik | Değer |
|---|---|
| Path | POST /api/stripe/webhook |
| Dosya | app/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. |
| Yetkilendirme | Stripe-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.
4. Stripe Connect Onboarding
Section titled “4. Stripe Connect Onboarding”| Özellik | Değer |
|---|---|
| Path | POST /api/stripe/connect-onboarding |
| Dosya | app/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. |
| Yetkilendirme | Session 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>5. Eğitmen Manuel Ödeme Bilgisi (TR)
Section titled “5. Eğitmen Manuel Ödeme Bilgisi (TR)”| Özellik | Değer |
|---|---|
| Path | POST /api/instructor/update-manual-payout |
| Dosya | app/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. |
| Yetkilendirme | Session + user.role === "instructor". |
İstek:
- Method: POST
- Content-Type:
application/x-www-form-urlencodedveyamultipart/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:
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"6. Ders Kaynağı Yükleme
Section titled “6. Ders Kaynağı Yükleme”| Özellik | Değer |
|---|---|
| Path | POST /api/lesson-resource-upload |
| Dosya | app/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. |
| Yetkilendirme | Bu 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.
7. Sohbet Görsel Yükleme
Section titled “7. Sohbet Görsel Yükleme”| Özellik | Değer |
|---|---|
| Path | POST /api/chat-image-upload |
| Dosya | app/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. |
| Yetkilendirme | Bu 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ı).
8. Sertifika PDF İndirme
Section titled “8. Sertifika PDF İndirme”| Özellik | Değer |
|---|---|
| Path | GET /api/certificate/:id/download veya GET /api/certificates/:id/download |
| Dosya | app/routes/api.certificate.$id.download.ts |
| Amaç | Kullanıcının sertifika kaydına ait PDF’i indirmek. Sertifika userId ile eşleşmeli. |
| Yetkilendirme | Session gerekli; sertifika sahibi (certificates.userId === session.user.id) olmalı. |
İstek: GET; path parametresi id — sertifika UUID.
Yanıt (başarı): 200 — Content-Type: application/pdf, Content-Disposition: attachment; filename="certificate-xxx.pdf". Gövde PDF stream.
Hata: 401 (giriş gerekli), 404 (sertifika bulunamadı veya yetkisiz), 500.
9. Fatura PDF İndirme
Section titled “9. Fatura PDF İndirme”| Özellik | Değer |
|---|---|
| Path | GET /api/invoice/:enrollmentId/download |
| Dosya | app/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. |
| Yetkilendirme | Session gerekli; enrollment sahibi (enrollments.userId === session.user.id) olmalı. |
İstek: GET; path parametresi enrollmentId — enrollment UUID.
Yanıt (başarı): 200 — Content-Type: application/pdf, Content-Disposition: attachment. Gövde PDF.
Hata: 400 (enrollmentId eksik), 401 (giriş gerekli), 404 (enrollment bulunamadı veya yetkisiz), 500.
10. Admin Aktivite Listesi
Section titled “10. Admin Aktivite Listesi”| Özellik | Değer |
|---|---|
| Path | GET /api/admin/activities |
| Dosya | app/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). |
| Yetkilendirme | Session + 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:
curl "https://lms.techsider.co/api/admin/activities" \ -H "Cookie: better-auth.session_token=..."11. Video İzleme İlerlemesi
Section titled “11. Video İzleme İlerlemesi”| Özellik | Değer |
|---|---|
| Path | POST /api/update-progress |
| Dosya | app/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. |
| Yetkilendirme | Bu 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:
curl -X POST "https://lms.techsider.co/api/update-progress" \ -H "Content-Type: application/json" \ -d '{"userId":"...","lessonId":"...","courseId":"...","instructorId":"...","secondsWatched":60,"isSubscription":false}'Özet Tablo — REST API’ler
Section titled “Özet Tablo — REST API’ler”| Endpoint | Method | Amaç | Yetki |
|---|---|---|---|
/api/graphql | POST | GraphQL sorgu/mutation | Session (resolver bazlı) |
/api/auth/* | * | Giriş, kayıt, OAuth, session | Public / Better Auth |
/api/stripe/webhook | POST | Stripe olayları (ödeme, abonelik) | Stripe-Signature |
/api/stripe/connect-onboarding | POST | Stripe Connect onboarding redirect | Instructor |
/api/instructor/update-manual-payout | POST | TR manuel ödeme bilgisi (IBAN/Payoneer) | Instructor |
/api/lesson-resource-upload | POST | Ders kaynağı yükleme (Bunny) | FormData: lessonId, file |
/api/chat-image-upload | POST | Sohbet görseli yükleme (Bunny) | FormData: file |
/api/certificate/:id/download | GET | Sertifika PDF indirme | Session, sertifika sahibi |
/api/certificates/:id/download | GET | Aynı (geriye dönük URL) | Aynı |
/api/invoice/:enrollmentId/download | GET | Fatura PDF indirme | Session, enrollment sahibi |
/api/admin/activities | GET | Admin aktivite listesi (JSON) | Admin |
/api/update-progress | POST | Video 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,adminPayoutRequestsvb. - Mutation:
createCourse,updateCourse,toggleLessonCompletion,recordLearningActivity,requestPayout,createStripeCheckoutSession,addToCart,createReview,updatePayoutSettingsvb.
İstemci örneği: app/lib/graphql-client.ts — fetch("/api/graphql", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ query, variables }), credentials: "include" }).
İlgili Sayfalar
Section titled “İlgili Sayfalar”- API Referansı ve GraphQL — Şema, context, Better Auth konfigürasyonu.
- Route Haritası — Tüm URL’lerin listesi.
- Sözlük — Terim tanımları.