{"openapi":"3.0.3","info":{"title":"EventMedia REST API","version":"1.0.0","description":"REST API lengkap untuk EventMedia Indonesia. Akses katalog event, pencarian berfilter, kategori, kota, tags, artikel kurasi, pengajuan event publik, dan integrasi upload CDN.","contact":{"name":"EventMedia Developer Support","email":"dev@eventmedia.id","url":"https://eventmedia.my.id/apidocs"}},"servers":[{"url":"https://eventmedia.my.id","description":"Current Environment Server"}],"pagination_standard":{"description":"Format pagination standar pada semua endpoint bertipe list/koleksi data.","schema":{"page":"Nomor halaman aktif (integer >= 1)","limit":"Batas jumlah item per halaman (integer, default bervariasi per endpoint, max: 100)","total":"Total keseluruhan record yang sesuai dengan kriteria filter (integer)","total_pages":"Total jumlah halaman yang tersedia (integer)","has_next":"Boolean (true jika ada halaman berikutnya)","has_prev":"Boolean (true jika ada halaman sebelumnya)","next_page":"Nomor halaman selanjutnya atau null","prev_page":"Nomor halaman sebelumnya atau null"},"example":{"page":1,"limit":12,"total":48,"total_pages":4,"has_next":true,"has_prev":false,"next_page":2,"prev_page":null}},"endpoints":[{"id":"events-list","group":"Events","method":"GET","path":"/api/events","summary":"Daftar Event (dengan Pagination & Filter)","description":"Mengambil daftar event aktif dan terverifikasi dengan dukungan pagination, pencarian teks lengkap, filter kategori, kota, tags, format (offline/online), harga (gratis/berbayar), dan pengurutan.","parameters":[{"name":"page","in":"query","type":"integer","default":1,"description":"Nomor halaman (mulai dari 1)."},{"name":"limit","in":"query","type":"integer","default":12,"description":"Jumlah event per halaman (max: 100)."},{"name":"q","in":"query","type":"string","description":"Kata kunci pencarian judul, deskripsi, atau organizer."},{"name":"kategori","in":"query","type":"string","description":"Slug kategori event (contoh: \"musik\", \"teknologi\")."},{"name":"kota","in":"query","type":"string","description":"Slug kota pelaksanaan event (contoh: \"jakarta\", \"surabaya\")."},{"name":"tag","in":"query","type":"string","description":"Slug tag spesifik (contoh: \"workshop\", \"festival\")."},{"name":"format","in":"query","type":"string","enum":["offline","online","hybrid"],"description":"Format pelaksanaan event."},{"name":"gratis","in":"query","type":"integer","enum":[0,1],"description":"Filter event gratis (1 = gratis, 0 = berbayar)."},{"name":"sort","in":"query","type":"string","enum":["created_at_desc","start_date_asc","start_date_desc","price_asc","title_asc"],"default":"created_at_desc","description":"Urutan hasil."}],"responses":{"200":{"description":"Daftar event berhasil diambil beserta metadata pagination.","sample":{"success":true,"data":[{"id":"evt-a1b2c3d4","title":"Tech In Motion Summit 2026","slug":"tech-in-motion-summit-2026","short_description":"Konferensi teknologi tahunan terbesar.","poster_url":"https://young-unit-7407.wakeawakewik.workers.dev/example.png","start_date":"2026-11-20","end_date":"2026-11-21","start_time":"09:00","event_type":"offline","venue_name":"Grand City Hall","city_name":"Surabaya","city_slug":"surabaya","category_name":"Teknologi","category_slug":"teknologi","ticket_price_min":75000,"ticket_price_max":250000,"is_free":0,"organizer_name":"DevHub Indonesia"}],"pagination":{"page":1,"limit":12,"total":42,"total_pages":4,"has_next":true,"has_prev":false,"next_page":2,"prev_page":null}}}}},{"id":"events-detail","group":"Events","method":"GET","path":"/api/events/{slug}","summary":"Detail Event Spesifik","description":"Mengambil data lengkap sebuah event berdasarkan slug unik atau ID event, termasuk deskripsi kaya, jadwal, tiket, organizer, koordinat peta, dan relasi tags.","parameters":[{"name":"slug","in":"path","required":true,"type":"string","description":"Slug unik atau ID event."}],"responses":{"200":{"description":"Detail lengkap event ditemukan.","sample":{"success":true,"event":{"id":"evt-a1b2c3d4","title":"Tech In Motion Summit 2026","slug":"tech-in-motion-summit-2026","description":"<p>Detail lengkap mengenai sesi dan pembicara...</p>","poster_url":"https://young-unit-7407.wakeawakewik.workers.dev/example.png","gallery":[],"start_date":"2026-11-20","end_date":"2026-11-21","start_time":"09:00","end_time":"17:00","event_type":"offline","venue_name":"Grand City Hall","venue_address":"Jl. Pemuda No. 1","city_name":"Surabaya","category_name":"Teknologi","organizer_name":"DevHub Indonesia","contact_phone":"081234567890","ticket_url":"https://tiket.example.com","is_free":0,"ticket_price_min":75000,"tags":[{"id":"tag-1","name":"AI","slug":"ai"}]}}},"404":{"description":"Event tidak ditemukan.","sample":{"success":false,"error":"Event tidak ditemukan."}}}},{"id":"events-submit","group":"Events","method":"POST","path":"/api/events/submit","summary":"Kirim Event Publik (Submission Form)","description":"Memungkinkan komunitas dan organizer mengajukan event baru untuk dikurasi dan disetujui oleh tim EventMedia sebelum tayang secara publik.","requestBody":{"type":"application/json","required":true,"schema":{"title":"string (wajib, judul event)","category_id":"string (wajib, ID kategori)","city_id":"string (opsional, ID kota)","start_date":"string YYYY-MM-DD (wajib, tanggal mulai)","end_date":"string YYYY-MM-DD (opsional, tanggal selesai)","start_time":"string HH:mm (opsional, jam mulai)","event_type":"offline | online | hybrid (default: offline)","venue_name":"string (opsional, nama lokasi venue)","venue_address":"string (opsional, alamat lengkap)","organizer_name":"string (wajib, nama penyelenggara)","contact_name":"string (opsional, nama PIC)","contact_phone":"string (wajib jika email kosong)","contact_email":"string (wajib jika nomor telepon kosong)","ticket_price_min":"number (opsional, nominal harga tiket termurah)","is_free":"boolean / 0 / 1 (apakah event gratis)","ticket_url":"string (opsional, tautan pembelian tiket atau registrasi)","poster_url":"string (opsional, URL gambar poster hasil upload CDN)","tags":"string (opsional, koma terpisah, contoh: \"workshop, tech\")"}},"responses":{"201":{"description":"Pengajuan event berhasil disimpan dalam status antrean pending.","sample":{"success":true,"message":"Event Anda berhasil diajukan! Tim kurator EventMedia akan memeriksa dan mengonfirmasi event Anda sebelum dipublikasikan.","event":{"id":"evt-x9y8z7","title":"Workshop Flutter Modern","slug":"workshop-flutter-modern"}}},"400":{"description":"Validasi gagal.","sample":{"success":false,"error":"Judul event wajib diisi."}}}},{"id":"categories-list","group":"Categories","method":"GET","path":"/api/categories","summary":"Daftar Kategori Event (dengan Pagination & Search)","description":"Mengambil daftar kategori event aktif dengan informasi jumlah event dan metadata pagination.","parameters":[{"name":"page","in":"query","type":"integer","default":1,"description":"Nomor halaman."},{"name":"limit","in":"query","type":"integer","default":20,"description":"Jumlah kategori per halaman."},{"name":"q","in":"query","type":"string","description":"Filter pencarian nama atau slug kategori."},{"name":"active_only","in":"query","type":"integer","default":1,"description":"Hanya tampilkan kategori aktif (1/0)."}],"responses":{"200":{"description":"Daftar kategori berhasil diambil.","sample":{"success":true,"data":[{"id":"cat-musik","name":"Musik & Konser","slug":"musik","description":"Konser musik, festival, dan gig lokal.","icon":"Music","image_url":"https://young-unit-7407.wakeawakewik.workers.dev/music.jpg","is_active":1,"sort_order":1}],"pagination":{"page":1,"limit":20,"total":10,"total_pages":1,"has_next":false,"has_prev":false}}}}},{"id":"categories-detail","group":"Categories","method":"GET","path":"/api/categories/{slug}","summary":"Detail Kategori Spesifik","description":"Mengambil informasi kategori berdasarkan slug uniknya.","parameters":[{"name":"slug","in":"path","required":true,"type":"string","description":"Slug unik kategori (contoh: \"musik\")."}],"responses":{"200":{"description":"Detail kategori ditemukan.","sample":{"success":true,"category":{"id":"cat-musik","name":"Musik & Konser","slug":"musik","description":"Konser musik, festival, dan gig lokal.","icon":"Music","is_active":1}}}}},{"id":"cities-list","group":"Cities","method":"GET","path":"/api/cities","summary":"Daftar Kota Pelaksanaan (dengan Pagination & Search)","description":"Mengambil daftar kota tempat penyelenggaraan event lengkap dengan provinsi dan thumbnail.","parameters":[{"name":"page","in":"query","type":"integer","default":1,"description":"Nomor halaman."},{"name":"limit","in":"query","type":"integer","default":20,"description":"Jumlah kota per halaman."},{"name":"q","in":"query","type":"string","description":"Pencarian nama kota atau provinsi."}],"responses":{"200":{"description":"Daftar kota berhasil diambil.","sample":{"success":true,"data":[{"id":"city-jkt","name":"Jakarta","slug":"jakarta","province":"DKI Jakarta","image_url":"https://young-unit-7407.wakeawakewik.workers.dev/jkt.jpg"}],"pagination":{"page":1,"limit":20,"total":8,"total_pages":1,"has_next":false,"has_prev":false}}}}},{"id":"cities-detail","group":"Cities","method":"GET","path":"/api/cities/{slug}","summary":"Detail Kota Spesifik","description":"Mengambil informasi kota berdasarkan slug unik.","parameters":[{"name":"slug","in":"path","required":true,"type":"string","description":"Slug unik kota (contoh: \"surabaya\")."}],"responses":{"200":{"description":"Detail kota ditemukan.","sample":{"success":true,"city":{"id":"city-sby","name":"Surabaya","slug":"surabaya","province":"Jawa Timur","country":"Indonesia"}}}}},{"id":"tags-list","group":"Tags","method":"GET","path":"/api/tags","summary":"Daftar Tags / Topik (dengan Pagination & Search)","description":"Mengambil daftar tag dan topik populer beserta jumlah kemunculan event yang terkait.","parameters":[{"name":"page","in":"query","type":"integer","default":1,"description":"Nomor halaman."},{"name":"limit","in":"query","type":"integer","default":30,"description":"Jumlah tag per halaman."},{"name":"q","in":"query","type":"string","description":"Pencarian nama tag."}],"responses":{"200":{"description":"Daftar tag berhasil diambil.","sample":{"success":true,"data":[{"id":"tag-1","name":"Festival","slug":"festival","event_count":14},{"id":"tag-2","name":"Workshop","slug":"workshop","event_count":9}],"pagination":{"page":1,"limit":30,"total":24,"total_pages":1,"has_next":false,"has_prev":false}}}}},{"id":"news-list","group":"Articles & News","method":"GET","path":"/api/news","summary":"Daftar Artikel & Berita (dengan Pagination)","description":"Mengambil artikel berita, tips event, liputan dan ulasan dari kurator EventMedia dengan pagination.","parameters":[{"name":"page","in":"query","type":"integer","default":1,"description":"Nomor halaman aktif."},{"name":"limit","in":"query","type":"integer","default":9,"description":"Batas jumlah artikel per halaman (max: 50)."},{"name":"q","in":"query","type":"string","description":"Pencarian teks judul atau isi berita."},{"name":"kategori","in":"query","type":"string","description":"Kategori artikel (contoh: \"Tips Event\", \"Liputan\")."},{"name":"featured","in":"query","type":"integer","enum":[0,1],"description":"Hanya artikel pilihan editor."}],"responses":{"200":{"description":"Daftar artikel berita berhasil diambil.","sample":{"success":true,"data":[{"id":"news-01","title":"Panduan Lengkap Mengatur Budget Festival Musik","slug":"panduan-lengkap-budget-festival-musik","excerpt":"Kiat hemat dan nyaman menikmati rangkaian festival musik di Indonesia...","cover_url":"https://young-unit-7407.wakeawakewik.workers.dev/news1.jpg","category":"Tips Event","author_name":"Redaksi EventMedia","published_at":"2026-08-10T10:00:00Z"}],"pagination":{"page":1,"limit":9,"total":18,"total_pages":2,"has_next":true,"has_prev":false,"next_page":2,"prev_page":null}}}}},{"id":"news-detail","group":"Articles & News","method":"GET","path":"/api/news/{slug}","summary":"Detail Artikel Berita","description":"Mengambil konten lengkap artikel, format teks HTML, info penulis, dan tanggal publikasi.","parameters":[{"name":"slug","in":"path","required":true,"type":"string","description":"Slug unik artikel berita."}],"responses":{"200":{"description":"Detail artikel berita ditemukan.","sample":{"success":true,"article":{"id":"news-01","title":"Panduan Lengkap Mengatur Budget Festival Musik","slug":"panduan-lengkap-budget-festival-musik","content":"<p>Isi lengkap konten artikel di sini...</p>","cover_url":"https://young-unit-7407.wakeawakewik.workers.dev/news1.jpg","author_name":"Redaksi EventMedia","published_at":"2026-08-10T10:00:00Z"}}}}},{"id":"cdn-upload","group":"CDN File Upload","method":"POST","path":"/api/upload","summary":"Upload Gambar / Poster ke Cloudflare CDN","description":"Endpoint upload file multipart/form-data. File diunggah langsung atau diproksikan ke layanan CDN aksisoft (cfcdn.aksisoft.my.id) dan mengembalikan URL publik langsung (data.url). Batas ukuran file 24 MB.","requestBody":{"type":"multipart/form-data","required":true,"schema":{"file":"binary / file (wajib, file gambar format PNG, JPG, JPEG, WEBP, maks 24 MB)"}},"responses":{"200":{"description":"File berhasil diunggah ke CDN.","sample":{"success":true,"url":"https://young-unit-7407.wakeawakewik.workers.dev/1402bb895e-poster.png","data":{"url":"https://young-unit-7407.wakeawakewik.workers.dev/1402bb895e-poster.png"}}},"400":{"description":"Gagal mengunggah file.","sample":{"success":false,"error":"File tidak ditemukan atau format tidak didukung."}}}},{"id":"cdn-check-file","group":"CDN File Upload","method":"GET","path":"/api/check-file","summary":"Verifikasi Ketersediaan File di CDN (Pengecekan Resolusi)","description":"Mengecek ketersediaan dan status resolusi HTTP (HEAD/GET) dari URL file CDN. Direkomendasikan dipanggil setelah upload berhasil dan menunggu 5-10 detik masa propagasi CDN.","queryParams":[{"name":"url","type":"string","required":true,"description":"URL file CDN lengkap yang didapat dari data.url"}],"responses":{"200":{"description":"Status ketersediaan file berhasil dicek.","sample":{"url":"https://cfcdn.aksisoft.my.id/uploads/sample-poster.jpg","exists":true,"status":200,"timestamp":"2026-09-16T16:50:00.000Z"}}}},{"id":"stats-get","group":"Platform Stats & Settings","method":"GET","path":"/api/stats","summary":"Statistik Publik Platform","description":"Mengambil metrik ringkasan jumlah event aktif terverifikasi, jumlah kota, kategori, dan artikel berita di EventMedia.","responses":{"200":{"description":"Statistik publik berhasil diambil.","sample":{"success":true,"stats":{"total_events":58,"published_events":52,"total_categories":12,"total_cities":10,"total_news":15}}}}},{"id":"settings-get","group":"Platform Stats & Settings","method":"GET","path":"/api/settings","summary":"Pengaturan Publik Situs","description":"Mengambil konfigurasi publik situs seperti judul, meta description, kontak, logo URL, dan tautan sosial media.","responses":{"200":{"description":"Pengaturan publik berhasil diambil.","sample":{"success":true,"settings":{"site_title":"EventMedia.id","site_tagline":"Katalog & Portal Event Terlengkap Indonesia","site_logo":"/logo.svg","instagram_url":"https://instagram.com/eventmedia"}}}}},{"id":"admin-auth-login","group":"Admin Auth & Management","method":"POST","path":"/api/admin/login","summary":"Autentikasi Admin (Login)","description":"Melakukan login admin menggunakan username dan password. Jika berhasil, server akan menetapkan HttpOnly session cookie.","requestBody":{"type":"application/json","required":true,"schema":{"username":"string (wajib)","password":"string (wajib)"}},"responses":{"200":{"description":"Login berhasil.","sample":{"success":true,"user":{"id":"usr-admin","username":"admin","name":"Administrator","role":"superadmin"}}},"401":{"description":"Kredensial tidak valid.","sample":{"success":false,"error":"Username atau password salah."}}}},{"id":"admin-events-list","group":"Admin Auth & Management","method":"GET","path":"/api/admin/events","summary":"Daftar Event Admin (Semua Status & Pending Moderasi)","description":"Membutuhkan cookie sesi admin terautentikasi. Mengambil seluruh event termasuk draft, pending, rejected, dan published.","parameters":[{"name":"page","in":"query","type":"integer","default":1},{"name":"limit","in":"query","type":"integer","default":50},{"name":"status","in":"query","type":"string","enum":["all","published","pending","draft","rejected"]},{"name":"q","in":"query","type":"string"}],"responses":{"200":{"description":"Daftar event admin.","sample":{"success":true,"events":[],"total":58,"page":1,"limit":50}},"401":{"description":"Sesi tidak sah.","sample":{"success":false,"error":"Sesi kedaluwarsa atau akses ditolak."}}}},{"id":"admin-events-approve","group":"Admin Auth & Management","method":"POST","path":"/api/admin/events/{id}/approve","summary":"Konfirmasi / Publikasikan Event Submission","description":"Menyetujui event kiriman publik menjadi status published.","parameters":[{"name":"id","in":"path","required":true,"type":"string"}],"responses":{"200":{"description":"Event berhasil disetujui.","sample":{"success":true,"message":"Event berhasil dikonfirmasi dan diterbitkan."}}}}]}