{"openapi":"3.1.0","info":{"title":"SIPAKASIDI Public API","version":"1.0.0","summary":"Data agregat pelayanan kelurahan untuk mitra eksternal.","description":"API REST read-only untuk mitra (instansi, akademisi, swasta, LSM). Semua data bersifat agregat — tidak ada NIK, nama, atau data pribadi warga. Jangkauan wilayah dan scope ditentukan oleh akun mitra.\n\n**Autentikasi:** kirim `Authorization: Bearer <API_KEY>` (atau header `X-API-Key`). Buat API key di portal mitra. Key hanya ditampilkan sekali saat dibuat.","contact":{"name":"Admin SIPAKASIDI"}},"servers":[{"url":"https://sipakasidi.ssyubix.com/api/public/v1","description":"Produksi"}],"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"tags":[{"name":"Akun","description":"Informasi API key"},{"name":"Wilayah","description":"Kelurahan & kecamatan dalam jangkauan"},{"name":"Statistik","description":"Rekap warga & pengajuan layanan"},{"name":"Penduduk","description":"Demografi agregat"},{"name":"Layanan","description":"Katalog jenis layanan"}],"paths":{"/me":{"get":{"operationId":"getApiKeyInfo","tags":["Akun"],"summary":"Info API key","description":"Detail API key yang sedang dipakai: scope efektif, jangkauan wilayah, dan rate limit. Tidak butuh scope khusus — cocok untuk tes koneksi.","x-scope":null,"responses":{"200":{"description":"Info key","headers":{"X-Request-Id":{"description":"ID unik request — sertakan saat melapor masalah","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Kuota request per menit","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Sisa kuota pada jendela 60 detik saat ini","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ApiKeyInfoResponse"},"example":{"object":"api_key","data":{"id":"0c9b1f2e-3a4d-4e5f-8a9b-0c1d2e3f4a5b","nama":"Server Produksi","prefix":"sipk_3f9a1c2","organisasi":"Dinas Sosial Kota","scopes":["wilayah:read","stats:read"],"wilayah":{"level":"kecamatan","kelurahan_id":null,"kecamatan_id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10"},"rate_limit_per_menit":60,"expires_at":null}}}}},"401":{"description":"API key tidak ada / tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"API key tidak valid, sudah dicabut, kedaluwarsa, atau akun mitra ditangguhkan.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"Rate limit terlampaui","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Batas 60 request/menit terlampaui. Coba lagi dalam 60 detik.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"500":{"description":"Kesalahan server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"api_error","code":"internal_error","message":"Terjadi kesalahan di server. Coba lagi nanti.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/wilayah":{"get":{"operationId":"listWilayah","tags":["Wilayah"],"summary":"Daftar kelurahan","description":"Kelurahan aktif dalam jangkauan API key, beserta kecamatannya. Gunakan `id` kelurahan sebagai filter `kelurahan_id` di endpoint lain.","x-scope":"wilayah:read","parameters":[{"name":"kelurahan_id","in":"query","required":false,"description":"Persempit hasil ke satu kelurahan (harus di dalam jangkauan API key). Kosongkan untuk semua kelurahan dalam jangkauan.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Daftar kelurahan","headers":{"X-Request-Id":{"description":"ID unik request — sertakan saat melapor masalah","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Kuota request per menit","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Sisa kuota pada jendela 60 detik saat ini","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/WilayahListResponse"},"example":{"object":"list","scope":{"level":"kecamatan","kelurahan_id":null,"kecamatan_id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10"},"data":[{"id":"a1b2c3d4-0000-4000-8000-000000000001","kode":"7371011001","nama":"Kelurahan Contoh","kecamatan":{"id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10","kode":"737101","nama":"Kecamatan Contoh"}}]}}}},"401":{"description":"API key tidak ada / tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"API key tidak valid, sudah dicabut, kedaluwarsa, atau akun mitra ditangguhkan.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"Scope tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"permission_error","code":"insufficient_scope","message":"API key ini tidak memiliki scope `stats:read`.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"Rate limit terlampaui","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Batas 60 request/menit terlampaui. Coba lagi dalam 60 detik.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"500":{"description":"Kesalahan server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"api_error","code":"internal_error","message":"Terjadi kesalahan di server. Coba lagi nanti.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/stats":{"get":{"operationId":"getStats","tags":["Statistik"],"summary":"Statistik pelayanan","description":"Jumlah warga terdaftar dan rekap pengajuan layanan per kelurahan, termasuk jumlah selesai & rata-rata durasi penyelesaian bulan berjalan.","x-scope":"stats:read","parameters":[{"name":"kelurahan_id","in":"query","required":false,"description":"Persempit hasil ke satu kelurahan (harus di dalam jangkauan API key). Kosongkan untuk semua kelurahan dalam jangkauan.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Statistik per kelurahan","headers":{"X-Request-Id":{"description":"ID unik request — sertakan saat melapor masalah","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Kuota request per menit","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Sisa kuota pada jendela 60 detik saat ini","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StatsResponse"},"example":{"object":"list","scope":{"level":"kecamatan","kelurahan_id":null,"kecamatan_id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10"},"ringkasan":{"jumlah_kelurahan":1,"total_warga":1284,"total_pengajuan":342},"data":[{"kelurahan":{"id":"a1b2c3d4-0000-4000-8000-000000000001","kode":"7371011001","nama":"Kelurahan Contoh"},"kecamatan":{"id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10","nama":"Kecamatan Contoh"},"total_warga":1284,"pengajuan":{"total":342,"per_status":{"SELESAI":301,"MENUNGGU_RT_RW":12,"MENUNGGU_LURAH":4,"DITOLAK":25},"selesai_bulan_ini":38,"rata_rata_hari_penyelesaian_bulan_ini":1.7}}]}}}},"401":{"description":"API key tidak ada / tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"API key tidak valid, sudah dicabut, kedaluwarsa, atau akun mitra ditangguhkan.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"Scope tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"permission_error","code":"insufficient_scope","message":"API key ini tidak memiliki scope `stats:read`.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"Rate limit terlampaui","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Batas 60 request/menit terlampaui. Coba lagi dalam 60 detik.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"500":{"description":"Kesalahan server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"api_error","code":"internal_error","message":"Terjadi kesalahan di server. Coba lagi nanti.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/penduduk":{"get":{"operationId":"getPendudukAgregat","tags":["Penduduk"],"summary":"Demografi agregat","description":"Distribusi warga terdaftar per jenis kelamin, kelompok umur, agama, pendidikan, pekerjaan, dan status perkawinan. Kategori dengan jumlah di bawah `ambang_penyamaran` digabung menjadi `LAINNYA_DISAMARKAN` untuk mencegah identifikasi individu.","x-scope":"penduduk:read","parameters":[{"name":"kelurahan_id","in":"query","required":false,"description":"Persempit hasil ke satu kelurahan (harus di dalam jangkauan API key). Kosongkan untuk semua kelurahan dalam jangkauan.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Demografi agregat","headers":{"X-Request-Id":{"description":"ID unik request — sertakan saat melapor masalah","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Kuota request per menit","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Sisa kuota pada jendela 60 detik saat ini","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PendudukResponse"},"example":{"object":"penduduk.agregat","scope":{"level":"kecamatan","kelurahan_id":null,"kecamatan_id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10"},"kelurahan":[{"id":"a1b2c3d4-0000-4000-8000-000000000001","nama":"Kelurahan Contoh"}],"ambang_penyamaran":5,"data":{"total_warga":1284,"distribusi":{"jenis_kelamin":[{"nilai":"PEREMPUAN","jumlah":655},{"nilai":"LAKI-LAKI","jumlah":629}],"kelompok_umur":[{"nilai":"25-44","jumlah":441},{"nilai":"45-59","jumlah":290},{"nilai":"LAINNYA_DISAMARKAN","jumlah":3}]}}}}}},"401":{"description":"API key tidak ada / tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"API key tidak valid, sudah dicabut, kedaluwarsa, atau akun mitra ditangguhkan.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"Scope tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"permission_error","code":"insufficient_scope","message":"API key ini tidak memiliki scope `stats:read`.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"Rate limit terlampaui","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Batas 60 request/menit terlampaui. Coba lagi dalam 60 detik.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"500":{"description":"Kesalahan server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"api_error","code":"internal_error","message":"Terjadi kesalahan di server. Coba lagi nanti.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}},"/layanan":{"get":{"operationId":"listLayanan","tags":["Layanan"],"summary":"Katalog jenis layanan","description":"Jenis layanan aktif beserta persyaratannya di setiap kelurahan dalam jangkauan.","x-scope":"layanan:read","parameters":[{"name":"kelurahan_id","in":"query","required":false,"description":"Persempit hasil ke satu kelurahan (harus di dalam jangkauan API key). Kosongkan untuk semua kelurahan dalam jangkauan.","schema":{"type":"string","format":"uuid"}}],"responses":{"200":{"description":"Daftar layanan","headers":{"X-Request-Id":{"description":"ID unik request — sertakan saat melapor masalah","schema":{"type":"string"}},"X-RateLimit-Limit":{"description":"Kuota request per menit","schema":{"type":"integer"}},"X-RateLimit-Remaining":{"description":"Sisa kuota pada jendela 60 detik saat ini","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LayananListResponse"},"example":{"object":"list","scope":{"level":"kecamatan","kelurahan_id":null,"kecamatan_id":"5b0c1a52-6e1f-4d59-9d4a-0d2b8c1e7f10"},"data":[{"id":"f0e1d2c3-0000-4000-8000-000000000009","nama":"Surat Keterangan Domisili","slug":"sk-domisili","deskripsi":"Keterangan tempat tinggal warga.","persyaratan":["Fotokopi KTP","Fotokopi KK","Surat pengantar RT/RW"],"kelurahan":{"id":"a1b2c3d4-0000-4000-8000-000000000001","nama":"Kelurahan Contoh"}}]}}}},"401":{"description":"API key tidak ada / tidak valid","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"authentication_error","code":"invalid_api_key","message":"API key tidak valid, sudah dicabut, kedaluwarsa, atau akun mitra ditangguhkan.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"403":{"description":"Scope tidak mencukupi","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"permission_error","code":"insufficient_scope","message":"API key ini tidak memiliki scope `stats:read`.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"429":{"description":"Rate limit terlampaui","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"rate_limit_error","code":"rate_limit_exceeded","message":"Batas 60 request/menit terlampaui. Coba lagi dalam 60 detik.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}},"500":{"description":"Kesalahan server","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"},"example":{"error":{"type":"api_error","code":"internal_error","message":"Terjadi kesalahan di server. Coba lagi nanti.","request_id":"req_8f14e45fceea167a5a36dedd4bea2543"}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"sipk_<48 hex>","description":"Header `Authorization: Bearer <API_KEY>` (disarankan)."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternatif untuk klien yang tidak bisa mengirim header Authorization."}},"schemas":{"Error":{"type":"object","required":["error"],"properties":{"error":{"type":"object","required":["type","code","message","request_id"],"properties":{"type":{"type":"string","enum":["authentication_error","permission_error","invalid_request_error","rate_limit_error","api_error"]},"code":{"type":"string","examples":["invalid_api_key","insufficient_scope","kelurahan_not_found"]},"message":{"type":"string"},"request_id":{"type":"string"}}}}},"Scope":{"type":"object","description":"Jangkauan wilayah API key. `semua` = seluruh kelurahan.","properties":{"level":{"type":"string","enum":["kelurahan","kecamatan","semua"]},"kelurahan_id":{"type":["string","null"],"format":"uuid"},"kecamatan_id":{"type":["string","null"],"format":"uuid"}}},"Ref":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"kode":{"type":"string"},"nama":{"type":"string"}}},"ApiKeyInfoResponse":{"type":"object","properties":{"object":{"const":"api_key"},"data":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nama":{"type":"string"},"prefix":{"type":"string"},"organisasi":{"type":["string","null"]},"scopes":{"type":"array","items":{"type":"string","enum":["wilayah:read","stats:read","penduduk:read","layanan:read"]}},"wilayah":{"$ref":"#/components/schemas/Scope"},"rate_limit_per_menit":{"type":"integer"},"expires_at":{"type":["string","null"],"format":"date-time"}}}}},"WilayahListResponse":{"type":"object","properties":{"object":{"const":"list"},"scope":{"$ref":"#/components/schemas/Scope"},"data":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Ref"},{"type":"object","properties":{"kecamatan":{"$ref":"#/components/schemas/Ref"}}}]}}}},"StatsResponse":{"type":"object","properties":{"object":{"const":"list"},"scope":{"$ref":"#/components/schemas/Scope"},"ringkasan":{"type":"object","properties":{"jumlah_kelurahan":{"type":"integer"},"total_warga":{"type":"integer"},"total_pengajuan":{"type":"integer"}}},"data":{"type":"array","items":{"type":"object","properties":{"kelurahan":{"$ref":"#/components/schemas/Ref"},"kecamatan":{"$ref":"#/components/schemas/Ref"},"total_warga":{"type":"integer"},"pengajuan":{"type":"object","properties":{"total":{"type":"integer"},"per_status":{"type":"object","additionalProperties":{"type":"integer"}},"selesai_bulan_ini":{"type":"integer"},"rata_rata_hari_penyelesaian_bulan_ini":{"type":["number","null"]}}}}}}}},"Sel":{"type":"object","properties":{"nilai":{"type":"string"},"jumlah":{"type":"integer"}}},"PendudukResponse":{"type":"object","properties":{"object":{"const":"penduduk.agregat"},"scope":{"$ref":"#/components/schemas/Scope"},"kelurahan":{"type":"array","items":{"$ref":"#/components/schemas/Ref"}},"ambang_penyamaran":{"type":"integer"},"data":{"type":"object","properties":{"total_warga":{"type":"integer"},"distribusi":{"type":"object","properties":{"jenis_kelamin":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}},"kelompok_umur":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}},"agama":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}},"pendidikan":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}},"jenis_pekerjaan":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}},"status_perkawinan":{"type":"array","items":{"$ref":"#/components/schemas/Sel"}}}}}}}},"LayananListResponse":{"type":"object","properties":{"object":{"const":"list"},"scope":{"$ref":"#/components/schemas/Scope"},"data":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string","format":"uuid"},"nama":{"type":"string"},"slug":{"type":"string"},"deskripsi":{"type":["string","null"]},"persyaratan":{"type":"array","items":{"type":"string"}},"kelurahan":{"$ref":"#/components/schemas/Ref"}}}}}}}}}