v1.0 REST · JSON · HTTPS

Dapur API

Sumber konten streaming untuk Warung kamu. Semua konten — video, album, search, trending — diambil dari sini lewat HTTP request pakai API key.

Belum punya API key? Daftar gratis di panel.dukunseo.com — langsung aktif, tanpa kartu kredit.

🚀 Quickstart #

Dari nol ke response pertama dalam 5 menit.

1

Ambil API Key

Login ke panel.dukunseo.com, masuk ke menu API Keys, klik Generate Key Baru. Salin key-nya — hanya tampil sekali.

2

Panggil Endpoint Pertama

Kirim GET request ke endpoint /api/v1/media dengan dua header wajib.

3

Terima Konten

Response JSON berisi list konten siap pakai. Tampilkan di situs kamu.

cURL — Ambil Konten Terbaru
curl https://dapur.dukunseo.com/api/v1/media \
  -H "X-API-Key: usr123_sk_live_xxxxxxxxxxxx" \
  -H "Origin: https://situslo.com"
JavaScript (fetch)
const res = await fetch('https://dapur.dukunseo.com/api/v1/media', {
  headers: {
    'X-API-Key': 'usr123_sk_live_xxxxxxxxxxxx',
    'Origin':    'https://situslo.com'
  }
});
const data = await res.json();
console.log(data.data); // array of media items
Response (200 OK)
{
  "status": "ok",
  "data": [
    {
      "id":        1842,
      "title":     "Judul Konten",
      "type":      "video",
      "thumbnail": "https://cdn.../thumb.jpg",
      "duration":  482,
      "views":     15280,
      "tags":      ["viral", "terbaru"],
      "created_at":"2026-03-10T14:22:00+07:00"
    }
  ],
  "meta": {
    "total":       1523,
    "page":        1,
    "per_page":    24,
    "total_pages": 64,
    "has_next":    true,
    "has_prev":    false
  }
}

🔑 Autentikasi #

Semua request wajib menyertakan dua header berikut.

HeaderWajibKeterangan
X-API-KeyWAJIBAPI key dari panel. Format: usr{id}_sk_live_{hash}
OriginWAJIBDomain situs yang terdaftar di whitelist panel. Contoh: https://situslo.com
AcceptOPSIONALDefaultnya application/json. Tidak perlu dicantumkan eksplisit.
⚠️
Header Origin harus cocok persis dengan domain yang lo daftarkan di panel. Request dari domain yang tidak diwhitelist akan ditolak dengan 403 Forbidden.
Contoh Header Lengkap
X-API-Key: usr42_sk_live_a3f9c2e1b8d74f5a
Origin:    https://warungku.com
Accept:    application/json

🌐 Base URL #

Semua endpoint diawali dengan base URL berikut.

https://dapur.dukunseo.com/api/v1
ℹ️
Kalau lo pakai Warung Template, set env variable DAPUR_BASE_URL ke https://dapur.dukunseo.com — template otomatis append /api/v1 ke semua request.

📡 Endpoints

Semua endpoint menggunakan HTTPS. Response selalu JSON.

GET /api/v1/media Ambil list konten

Ambil daftar konten (video atau album) dengan pagination. Endpoint utama untuk halaman beranda, halaman kategori, dan halaman tag.

Query Parameters
ParameterTipeDefaultKeterangan
pageinteger1Nomor halaman
per_pageinteger24Jumlah item per halaman. Maks 100.
typestringFilter tipe: video atau album. Kosong = semua.
sortstringnewestnewest · popular · views · longest
Contoh Request
GET /api/v1/media?page=1&per_page=24&type=video&sort=newest
Response
{ "status":"ok", "data":[{...}], "meta":{"total":1440,"page":1,"per_page":24,"total_pages":60,"has_next":true,"has_prev":false}}}
GET /api/v1/media/{id} Detail satu konten

Ambil detail lengkap satu konten berdasarkan ID. Dipakai di halaman tonton/view.

Contoh Request
GET /api/v1/media/1842
Response
{
  "status": "ok",
  "data": {
    "id":          1842,
    "title":       "Judul Konten",
    "type":        "video",
    "description":"Deskripsi konten...",
    "thumbnail":   "https://cdn.../thumb.jpg",
    "duration":    482,   // detik
    "views":       15280,
    "tags":        ["viral", "terbaru"],
    "status":      "published",
    "created_at":  "2026-03-10T14:22:00+07:00",
    "updated_at":  "2026-03-12T09:10:00+07:00"
  }
}
GET /api/v1/most-viewed Konten views terbanyak

Ambil konten yang paling banyak ditonton. Diurutkan murni berdasarkan jumlah views.

ParameterTipeDefaultKeterangan
limitinteger20Jumlah item. Maks 100.
typestringvideo atau album. Kosong = semua.
Contoh Request
GET /api/v1/most-viewed?limit=10
GET /api/v1/most-liked Konten like terbanyak

Ambil konten yang paling banyak dilike. Diurutkan murni berdasarkan jumlah likes.

ParameterTipeDefaultKeterangan
limitinteger20Jumlah item. Maks 100.
typestringvideo atau album. Kosong = semua.
Contoh Request
GET /api/v1/most-liked?limit=10
GET /api/v1/longest Video durasi terpanjang

Ambil video dengan durasi terpanjang. Hanya mengembalikan tipe video — album tidak punya durasi.

ParameterTipeDefaultKeterangan
limitinteger20Jumlah item. Maks 100.
Contoh Request
GET /api/v1/longest?limit=10
GET /api/v1/album/{id} Detail album + foto

Ambil detail album beserta seluruh list foto di dalamnya. Dipakai di halaman galeri album.

Contoh Request
GET /api/v1/album/321
Response
{
  "status": "ok",
  "data": {
    "id":          321,
    "title":       "Judul Album",
    "type":        "album",
    "photo_count": 24,
    "photos": [
      { "url": "https://cdn.../foto-1.jpg" },
      { "url": "https://cdn.../foto-2.jpg" }
    ]
  }
}
GET /api/v1/tags Daftar tag populer

Ambil daftar tag yang paling banyak dipakai. Dipakai di tag cloud dan navigasi.

ParameterTipeDefaultKeterangan
limitinteger100Jumlah tag yang dikembalikan.
Contoh Request
GET /api/v1/tags?limit=50
Response
{ "status":"ok", "data":["viral","terbaru","hot","hd"] }
GET /api/v1/tags-media/{tag} Media berdasarkan tag

Ambil semua konten yang memiliki tag tertentu. Dipakai di halaman /tag/{tag}.

ParameterTipeDefaultKeterangan
pageinteger1Nomor halaman
per_pageinteger24Jumlah item per halaman. Maks 100.
Contoh Request
GET /api/v1/tags-media/viral?page=1&per_page=24
GET /api/v1/categories Daftar kategori

Ambil semua kategori konten yang tersedia. Dipakai di menu navigasi dan filter.

Contoh Request
GET /api/v1/categories
Response
{
  "status": "ok",
  "data": [
    { "type": "video", "label": "Video", "count": 1200 },
    { "type": "album", "label": "Album", "count": 323  }
  ]
}
GET /api/v1/player-url/{id} URL embed player

Ambil URL embed player untuk satu konten video. URL ini yang dimasukkan ke dalam <iframe> di halaman tonton.

⚠️
Endpoint ini tidak di-cache — selalu fresh. Panggil satu kali saat halaman tonton dibuka, jangan simpan di cache browser lebih dari 1 jam.
Contoh Request
GET /api/v1/player-url/1842
Response
{ "status":"ok", "data":{ "player_url":"https://player.example.com/embed/abc123" } }
GET /api/v1/download-url/{id} URL download konten

Ambil URL download langsung untuk konten video atau foto album. Dipakai di halaman /download/{id}.

Contoh Request
GET /api/v1/download-url/1842
Response
{ "status":"ok", "data":{ "download_url":"https://cdn.../file.mp4?dl=1" } }
GET /api/v1/config Konfigurasi warung

Ambil konfigurasi warung dari Dapur — tipe konten aktif, nav items, dan fitur yang tersedia. Template otomatis memanggil ini saat boot, lo tidak perlu panggil manual.

Response
{
  "status": "ok",
  "data": {
    "warung_type":    "C",  // A=video, B=album, C=keduanya
    "content_types": ["video","album"],
    "nav_items":     [{"label":"Video","type":"video"}],
    "features":     {"has_album_route":true}
  }
}
POST /api/v1/record-view/{id} Tambah jumlah tayang

Tambahkan satu view ke konten. Dipanggil di background saat pengunjung membuka halaman tonton. Kalau lo pakai Warung Template, sudah otomatis dipanggil — tidak perlu manual.

💡
Panggil via waitUntil() atau background task agar tidak memperlambat respons halaman ke pengunjung.
Contoh Request
POST /api/v1/record-view/1842
# Tidak perlu body — ID cukup dari URL
POST /api/v1/record-like/{id} Tambah jumlah like

Tambahkan satu like ke konten. Dipanggil saat pengunjung menekan tombol like. Anti-duplicate per IP — like dari IP yang sama dalam satu sesi diabaikan.

Contoh Request
POST /api/v1/record-like/1842
# Tidak perlu body — ID cukup dari URL
Response
{ "status":"ok", "data":{"likes":284,"liked":true} }
POST /api/v1/record-watch-time/{id} Catat durasi tonton

Kirim berapa detik pengunjung menonton video. Dipakai untuk statistik watch time. Anti-cheat: nilai tidak boleh melebihi 2× durasi video.

Parameter (Body JSON)TipeKeterangan
secondsintegerWAJIB Durasi tonton dalam detik.
Contoh Request
POST /api/v1/record-watch-time/1842
Content-Type: application/json

{ "seconds": 240 }
GET /api/v1/quota Sisa kuota bulanan

Cek sisa kuota request bulan berjalan untuk API key yang sedang dipakai.

Response
{
  "status": "ok",
  "data": {
    "plan":        "pro",
    "monthly_quota": 600000,
    "monthly_used":  12480,
    "monthly_left":  587520,
    "reset_at":     "2026-04-01T00:00:00+07:00"
  }
}
GET /api/v1/stats Statistik global warung

Ambil statistik agregat warung: total views, likes, watch time, dan jumlah konten aktif.

Response
{
  "status": "ok",
  "data": {
    "total_media":      1523,
    "total_views":      4820910,
    "total_likes":      182340,
    "total_watch_time": 98432100  // total detik
  }
}
GET /api/v1/ads Konfigurasi iklan aktif

Ambil konfigurasi slot iklan yang aktif untuk warung ini. Template otomatis memanggil ini saat boot — lo tidak perlu panggil manual.

Contoh Request
GET /api/v1/ads
Response
{
  "status": "ok",
  "data": {
    "enabled":   true,
    "slots": {
      "top_d":     "<!-- kode iklan desktop top -->",
      "top_m":     "<!-- kode iklan mobile top -->",
      "content_d": "<!-- kode iklan desktop tengah -->",
      "content_m": "<!-- kode iklan mobile tengah -->",
      "sidebar_d": "<!-- kode iklan desktop sidebar -->",
      "sidebar_m": "<!-- kode iklan mobile sidebar -->",
      "popunder":  "<!-- kode popunder -->"
    }
  }
}
ℹ️
Slot iklan dikonfigurasi via env variable ADS_CODE_* di Cloudflare. Lihat bagian Environment Variables untuk daftar lengkapnya.

⚙️ Environment Variables #

Konfigurasi Warung Template melalui environment variable di Cloudflare. Tidak ada yang perlu diedit di kode.

🔐 Wajib Diisi
VariableStatusKeterangan
DAPUR_API_KEYWAJIBAPI key dari panel. Format: usr{id}_sk_live_{hash}
DAPUR_BASE_URLWAJIBBase URL Dapur: https://dapur.dukunseo.com
WARUNG_DOMAINWAJIBDomain situs lo. Contoh: warungku.com
WARUNG_NAMEWAJIBNama situs. Tampil di judul halaman dan footer.
WARUNG_TYPEWAJIBTipe konten: A = video only · B = album only · C = keduanya
🎨 Tampilan & Tema
THEME_ACCENTOPSIONALWarna aksen utama. Default: #ff4d4d
THEME_BGOPSIONALWarna background. Default: #0f0f0f
THEME_FONTOPSIONALNama Google Font. Contoh: Inter
WARUNG_TAGLINEOPSIONALTagline situs. Tampil di hero dan meta description.
SEO_DEFAULT_DESCOPSIONALMeta description default halaman beranda.
SEO_KEYWORDSOPSIONALMeta keywords default. Pisah dengan koma.
THEME_BADGE_HOTOPSIONALTeks badge "HOT" di thumbnail. Default: 🔥 TRENDING
🔀 URL Path
PATH_CONTENTOPSIONALPath halaman video. Default: tonton
PATH_ALBUMOPSIONALPath halaman album. Default: galeri
PATH_SEARCHOPSIONALPath halaman pencarian. Default: cari
PATH_CATEGORYOPSIONALPath halaman kategori. Default: kategori
PATH_TAGOPSIONALPath halaman tag. Default: tag
🛡️ Keamanan & Perlindungan
HONEYPOT_PREFIXOPSIONALPrefix URL jebakan bot. Default: admin-cp. Ganti kalau mau lebih eksotis.
INDEXNOW_SECRETOPSIONALSecret untuk IndexNow webhook. Pisah dari API key utama.
CANNIBALIZE_PATHOPSIONALPrefix URL landing page keyword. Default: viral
CANNIBALIZE_KEYWORDSOPSIONALDaftar keyword landing page, pisah koma. Kosong = pakai default bawaan.
Contoh .env / Cloudflare Variables
# Wajib
DAPUR_API_KEY    = usr42_sk_live_a3f9c2e1b8d74f5a
DAPUR_BASE_URL   = https://dapur.dukunseo.com
WARUNG_DOMAIN    = warungku.com
WARUNG_NAME      = WarungKu
WARUNG_TYPE      = C

# Opsional — tema
THEME_ACCENT     = #ff4d4d
WARUNG_TAGLINE   = Streaming Gratis Tanpa Batas
SEO_KEYWORDS     = streaming gratis, nonton online, video terbaru

⚡ Rate Limits #

Setiap plan punya batas request per jam dan per bulan. Kalau batas tercapai, API mengembalikan 429 Too Many Requests.

PlanRequest / JamRequest / BulanMaks SitusMaks Key
🌱 Basic
Gratis
200100.00011
⚡ Pro
$7/bln
1.500600.000103
👑 Master
$12/bln
5.0001.000.000155
🔮 Hybrid
$20/bln
15.000Unlimited2010
ℹ️
Batas per jam mereset setiap awal jam (00:00, 01:00, dst). Batas per bulan mereset di tanggal yang sama setiap bulan sesuai tanggal daftar.
Response Headers Saat Rate Limit
HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 1500      // batas per jam sesuai plan
X-RateLimit-Remaining: 0     // sisa request jam ini
X-RateLimit-Window: 3600     // window dalam detik (selalu 1 jam)
Content-Type: application/json

{
  "status":  "error",
  "code":    429,
  "message":"Rate limit exceeded (1500 req/hour). Try again later."
}
⚠️
Satu API key bisa dipakai di banyak domain sekaligus — limit dihitung total lintas semua domain, bukan per domain. Kalau punya 3 situs dengan 1 key Pro, 1.500 req/jam dibagi rata di ketiga situs itu.
ℹ️
Header X-RateLimit-Fallback: true akan muncul jika Redis tidak tersedia — rate limiting dalam kondisi ini bersifat per-process dan tidak akurat lintas server. Hubungi admin jika header ini muncul terus-menerus.

🚨 Error Codes #

Format error selalu JSON. Field message berisi penjelasan singkat.

Format Error
{
  "status":  "error",
  "code":    401,
  "message":"API key tidak valid atau sudah dicabut."
}
HTTP CodeArtinyaPenyebab UmumSolusi
400 Bad Request Parameter tidak valid, query kosong Cek format parameter yang dikirim
401 Unauthorized API key salah, dicabut, atau format key tidak valid Cek API key di panel, generate ulang jika perlu
403 Forbidden Domain tidak diwhitelist, key model lama, atau plan tidak mencukupi Pastikan domain terdaftar di panel, atau upgrade plan
404 Not Found Konten dengan ID tersebut tidak ada Pastikan ID valid dan konten masih aktif
429 Too Many Requests Melebihi batas request per jam atau per bulan Tunggu hingga awal jam berikutnya, atau upgrade plan
500 Internal Server Error Error di sisi Dapur Coba lagi dalam beberapa saat. Laporkan ke admin kalau persisten.
503 Service Unavailable Dapur sedang maintenance Tunggu dan coba lagi dalam beberapa saat.

📦 Format Response #

Semua response menggunakan struktur yang konsisten.

Struktur Root
statusstringok atau error
dataarray | objectPayload utama. Array untuk list, object untuk detail.
metaobjectMetadata tambahan — pagination, total, dsb. Hanya ada di endpoint list.
messagestringHanya ada saat status: error. Berisi pesan error.
Objek Media Item
idintegerID unik konten
titlestringJudul konten
typestringvideo atau album
descriptionstring | nullDeskripsi konten. Bisa null.
thumbnailstringURL gambar thumbnail
durationintegerDurasi dalam detik. 0 untuk album.
viewsintegerJumlah penayangan
tagsstring[]Array tag konten
statusstringpublished · hidden · draft
created_atstringTimestamp ISO 8601 dengan timezone
updated_atstringTimestamp terakhir diperbarui
Objek Pagination
totalintegerTotal item keseluruhan
pageintegerHalaman saat ini
per_pageintegerJumlah item per halaman
total_pagesintegerTotal halaman
has_nextbooleanAda halaman berikutnya?
has_prevbooleanAda halaman sebelumnya?

Masih ada yang bikin bingung?

Admin Telegram siap bantu — dari pasang sampai jalan.

💬 Tanya Admin 🔑 Ke Panel