{
 "openapi": "3.1.0",
 "info": {
  "title": "RegulasiEnergi.com API baca-saja",
  "version": "1.0.0",
  "description": "Data regulasi energi Indonesia sisi pengguna untuk agen AI dan program. Tanpa autentikasi, tanpa penulisan, idempoten. Setiap hasil menyebut pasal dasar. Bukan nasihat hukum maupun nasihat teknik; untuk keperluan hukum rujuk naskah resmi dari lembaga penerbit.",
  "license": {
   "name": "Lihat https://regulasienergi.com/lisensi/",
   "url": "https://regulasienergi.com/lisensi/"
  }
 },
 "servers": [
  {
   "url": "https://regulasienergi.com"
  }
 ],
 "paths": {
  "/api/langganan/daftar": {
   "post": {
    "operationId": "daftarRingkasan",
    "summary": "Minta langganan Ringkasan Regulasi sektor energi dan ketenagalistrikan; surel konfirmasi dikirim ke alamat itu",
    "description": "Langganan aktif hanya setelah pemilik alamat membuka tautan di surel konfirmasi dan menekan tombolnya; agen tidak dapat mengaktifkan langganan untuk alamat orang lain. Jawaban 202 sama untuk alamat yang sudah dan belum terdaftar. Content-Type harus application/json; badan paling besar 4096 karakter. Satu alamat boleh mendaftar beberapa sektor lewat situs sektor masing-masing atau lewat segmen[] di sini. Teks persetujuan umum-v2: https://regulasienergi.com/privasi/.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "surel",
         "segmen",
         "persetujuan_versi"
        ],
        "additionalProperties": false,
        "properties": {
         "surel": {
          "type": "string",
          "maxLength": 254,
          "format": "email"
         },
         "segmen": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
           "type": "string",
           "enum": [
            "air",
            "kerja",
            "energi",
            "sehat",
            "uang",
            "pengadaan",
            "pajak",
            "digital"
           ]
          },
          "example": [
           "energi"
          ]
         },
         "jadwal": {
          "type": "string",
          "enum": [
           "mingguan",
           "bulanan"
          ],
          "default": "bulanan"
         },
         "persetujuan_versi": {
          "type": "string",
          "example": "umum-v2"
         },
         "situs": {
          "type": "string",
          "maxLength": 0,
          "description": "Medan umpan bot; harus kosong."
         }
        }
       }
      }
     }
    },
    "responses": {
     "202": {
      "description": "Diterima; pesan sama untuk alamat baru dan terdaftar"
     },
     "400": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "403": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "429": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "503": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/langganan/masuk-google": {
   "post": {
    "operationId": "masukGoogle",
    "summary": "Aktifkan langganan Ringkasan Regulasi dengan token ID Google sebagai bukti kepemilikan alamat (tanpa surel konfirmasi)",
    "description": "Dipanggil halaman situs sesudah pembaca masuk dengan Google, membaca teks persetujuan umum-v2, dan menekan tombol setuju. Alamat diambil dari token (email_verified), bukan dari badan permintaan; masuk saja tidak mendaftarkan siapa pun. Token ID hanya dikeluarkan Google kepada pemilik akun yang masuk sendiri, jadi agen memakai POST daftar. Content-Type harus application/json; badan paling besar 4096 karakter. Teks persetujuan umum-v2: /privasi/.",
    "requestBody": {
     "required": true,
     "content": {
      "application/json": {
       "schema": {
        "type": "object",
        "required": [
         "token",
         "segmen",
         "persetujuan_versi"
        ],
        "additionalProperties": false,
        "properties": {
         "token": {
          "type": "string",
          "maxLength": 4096,
          "description": "Token ID Google (credential dari Google Identity Services)"
         },
         "segmen": {
          "type": "array",
          "minItems": 1,
          "uniqueItems": true,
          "items": {
           "type": "string",
           "enum": [
            "air",
            "kerja",
            "energi",
            "sehat",
            "uang",
            "pengadaan",
            "pajak",
            "digital"
           ]
          },
          "example": [
           "energi"
          ]
         },
         "jadwal": {
          "type": "string",
          "enum": [
           "mingguan",
           "bulanan"
          ],
          "default": "bulanan"
         },
         "persetujuan_versi": {
          "type": "string",
          "enum": [
           "umum-v2"
          ]
         }
        }
       }
      }
     }
    },
    "responses": {
     "200": {
      "description": "Langganan aktif untuk segmen yang diminta"
     },
     "400": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "401": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "403": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "429": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     },
     "503": {
      "description": "Galat: kode, pesan, dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "type": "object",
         "required": [
          "kode",
          "pesan",
          "perbaikan"
         ],
         "properties": {
          "kode": {
           "type": "string"
          },
          "pesan": {
           "type": "string"
          },
          "perbaikan": {
           "type": "string"
          }
         }
        }
       }
      }
     }
    }
   }
  },
  "/api/langganan/konfirmasi": {
   "get": {
    "operationId": "konfirmasiHalaman",
    "summary": "Halaman tombol konfirmasi (tidak mengubah apa pun)",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "HTML"
     },
     "410": {
      "description": "Token tidak berlaku"
     }
    }
   },
   "post": {
    "operationId": "konfirmasi",
    "summary": "Aktifkan langganan yang ditunjuk token",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Langganan aktif"
     },
     "410": {
      "description": "Token tidak berlaku"
     }
    }
   }
  },
  "/api/langganan/henti": {
   "get": {
    "operationId": "hentiHalaman",
    "summary": "Halaman tombol berhenti (tidak mengubah apa pun)",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "HTML"
     },
     "400": {
      "description": "Tanda tidak sah"
     }
    }
   },
   "post": {
    "operationId": "henti",
    "summary": "Berhenti dari satu sektor atau semua; idempoten; dipakai juga tombol satu klik aplikasi surel (RFC 8058)",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Berhenti"
     },
     "400": {
      "description": "Tanda tidak sah"
     }
    }
   }
  },
  "/api/langganan/jadwal": {
   "get": {
    "operationId": "jadwalHalaman",
    "summary": "Halaman pilihan jadwal",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "HTML"
     },
     "400": {
      "description": "Tanda tidak sah"
     }
    }
   },
   "post": {
    "operationId": "jadwal",
    "summary": "Ganti jadwal satu sektor (formulir jadwal=mingguan|bulanan)",
    "parameters": [
     {
      "name": "t",
      "in": "query",
      "required": true,
      "description": "token dari tautan di surel",
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Jadwal diganti"
     },
     "400": {
      "description": "Tanda atau jadwal tidak sah"
     }
    }
   }
  },
  "/api/berlaku": {
   "get": {
    "operationId": "berlakuPadaTanggal",
    "summary": "Versi tiap pokok aturan pada satu tanggal",
    "parameters": [
     {
      "name": "tanggal",
      "in": "query",
      "required": true,
      "description": "YYYY-MM-DD",
      "schema": {
       "type": "string",
       "example": "2021-06-01"
      }
     },
     {
      "name": "topik",
      "in": "query",
      "required": false,
      "description": "id topik, opsional (daftar di /berubah/index.json, medan topik[].id)",
      "schema": {
       "type": "string",
       "example": "kompensasi-gangguan-listrik"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Versi yang berlaku, dengan kutipan pasal"
     },
     "400": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     },
     "404": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     }
    }
   }
  },
  "/api/cari": {
   "get": {
    "operationId": "cari",
    "summary": "Cari pokok aturan, tanya jawab, dan tenggat dengan kata kunci (mulai dari sini)",
    "description": "Mengembalikan pokok aturan berikut versi terakhirnya (dan alamat /api/berlaku untuk tanggal tertentu), tanya jawab lengkap dengan peraturan sumbernya, dan tenggat. Istilah sehari-hari (misalnya panel surya, token listrik, TDL) dipetakan ke bahasa peraturan.",
    "parameters": [
     {
      "name": "q",
      "in": "query",
      "required": true,
      "description": "kata kunci atau pertanyaan",
      "schema": {
       "type": "string",
       "example": "kompensasi listrik padam"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Hasil pencarian terurut"
     },
     "400": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     }
    }
   }
  },
  "/api/pasal": {
   "get": {
    "operationId": "ambilPasal",
    "summary": "Bunyi satu pasal dari pustaka",
    "parameters": [
     {
      "name": "regulasi",
      "in": "query",
      "required": true,
      "description": "id regulasi, mis. pp-33-2023",
      "schema": {
       "type": "string",
       "example": "pp-33-2023"
      }
     },
     {
      "name": "pasal",
      "in": "query",
      "required": false,
      "description": "label pasal, mis. Pasal 32; kosong = daftar label",
      "schema": {
       "type": "string",
       "example": "Pasal 32"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Bunyi pasal atau daftar label"
     },
     "404": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     }
    }
   }
  },
  "/api/hitung": {
   "get": {
    "operationId": "hitung",
    "summary": "Alat hitung menurut pasal: kompensasi gangguan listrik, biaya SLO, tagihan menurut tarif, tagihan PLTS atap",
    "description": "Mesin yang sama dengan halaman /kalkulator/, diuji terhadap 136 kasus kunci. Tiap hasil menyebut pasal dasar dan tanggal berlaku. Parameter menurut alat. kompensasi: tanggal (YYYY-MM-DD, gangguan mulai 2020-01-01), dasar_rupiah, jam_padam (total lama padam sebulan, jam) atau indikator=indikator_lain dengan golongan_ta=ya|tidak, standar_jam (opsional, bawaan 1). biaya-slo: daya_va (bilangan bulat), tanggal (mulai 2025-01-21). tarif-listrik: golongan (r1-450, r1-900, r1-900rtm, r1-1300, r1-2200, r2, r3, b1-450, b1-900, b1-1300, b1-2200-5500, b2), pembayaran (reguler atau prabayar), kwh, daya_va, tanggal (mulai 2024-06-06). ekspor-impor: tanggal_persetujuan, bulan_tagihan (YYYY-MM), impor_kwh, ekspor_kwh, akumulasi_awal_kwh (opsional). Masukan di luar cakupan pasal ditolak dengan 422 dan alasannya.",
    "parameters": [
     {
      "name": "alat",
      "in": "query",
      "required": true,
      "description": "kompensasi, biaya-slo, tarif-listrik, atau ekspor-impor",
      "schema": {
       "type": "string",
       "example": "biaya-slo"
      }
     },
     {
      "name": "tanggal",
      "in": "query",
      "required": false,
      "description": "YYYY-MM-DD",
      "schema": {
       "type": "string",
       "example": "2025-06-01"
      }
     },
     {
      "name": "tanggal_persetujuan",
      "in": "query",
      "required": false,
      "description": "YYYY-MM-DD (ekspor-impor)",
      "schema": {
       "type": "string",
       "example": "2023-03-15"
      }
     },
     {
      "name": "bulan_tagihan",
      "in": "query",
      "required": false,
      "description": "YYYY-MM (ekspor-impor)",
      "schema": {
       "type": "string",
       "example": "2026-07"
      }
     },
     {
      "name": "daya_va",
      "in": "query",
      "required": false,
      "description": "daya tersambung dalam VA",
      "schema": {
       "type": "number",
       "example": 2200
      }
     },
     {
      "name": "kwh",
      "in": "query",
      "required": false,
      "description": "pemakaian sebulan, kWh",
      "schema": {
       "type": "number",
       "example": 200
      }
     },
     {
      "name": "jam_padam",
      "in": "query",
      "required": false,
      "description": "total lama padam sebulan, jam",
      "schema": {
       "type": "number",
       "example": 6
      }
     },
     {
      "name": "dasar_rupiah",
      "in": "query",
      "required": false,
      "description": "biaya beban atau rekening minimum, rupiah",
      "schema": {
       "type": "number",
       "example": 200000
      }
     },
     {
      "name": "golongan",
      "in": "query",
      "required": false,
      "description": "id golongan tarif",
      "schema": {
       "type": "string",
       "example": "r1-1300"
      }
     },
     {
      "name": "pembayaran",
      "in": "query",
      "required": false,
      "description": "reguler atau prabayar",
      "schema": {
       "type": "string",
       "example": "reguler"
      }
     },
     {
      "name": "indikator",
      "in": "query",
      "required": false,
      "description": "lama_gangguan atau indikator_lain",
      "schema": {
       "type": "string",
       "example": "lama_gangguan"
      }
     },
     {
      "name": "golongan_ta",
      "in": "query",
      "required": false,
      "description": "ya atau tidak (indikator_lain)",
      "schema": {
       "type": "string",
       "example": "ya"
      }
     },
     {
      "name": "standar_jam",
      "in": "query",
      "required": false,
      "description": "standar lama gangguan bila ditetapkan lain, jam per bulan",
      "schema": {
       "type": "number",
       "example": 1
      }
     },
     {
      "name": "impor_kwh",
      "in": "query",
      "required": false,
      "description": "kWh impor (ekspor-impor)",
      "schema": {
       "type": "number",
       "example": 300
      }
     },
     {
      "name": "ekspor_kwh",
      "in": "query",
      "required": false,
      "description": "kWh ekspor (ekspor-impor)",
      "schema": {
       "type": "number",
       "example": 200
      }
     },
     {
      "name": "akumulasi_awal_kwh",
      "in": "query",
      "required": false,
      "description": "selisih lebih terbawa, kWh (ekspor-impor)",
      "schema": {
       "type": "number",
       "example": 0
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Hasil hitung dengan pasal dasar dan catatan berkutipan"
     },
     "400": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     },
     "422": {
      "description": "Galat: penyebab dan perbaikan",
      "content": {
       "application/json": {
        "schema": {
         "$ref": "#/components/schemas/Galat"
        }
       }
      }
     }
    }
   }
  },
  "/api/teks/{id}.json": {
   "get": {
    "operationId": "teksLengkap",
    "summary": "Seluruh pasal satu regulasi",
    "parameters": [
     {
      "name": "id",
      "in": "path",
      "required": true,
      "schema": {
       "type": "string"
      }
     }
    ],
    "responses": {
     "200": {
      "description": "Peta label pasal ke bunyi"
     }
    }
   }
  },
  "/berubah/index.json": {
   "get": {
    "operationId": "rantaiVersi",
    "summary": "Rantai versi semua pokok aturan",
    "responses": {
     "200": {
      "description": "Topik dengan versi, kutipan, dasar tanggal berlaku"
     }
    }
   }
  },
  "/api/kunci-kalkulator.json": {
   "get": {
    "operationId": "kunciKalkulator",
    "summary": "Kunci lengkap alat hitung: data, dasar pasal, masukan, dan harapan setiap kasus",
    "responses": {
     "200": {
      "description": "Kunci yang dipakai uji mesin hitung"
     }
    }
   }
  },
  "/api/kunci-cek.json": {
   "get": {
    "operationId": "kunciCek",
    "summary": "Kunci lengkap alat cek: syarat dan kasus kedua alat",
    "responses": {
     "200": {
      "description": "Syarat utuh, jawaban, butir yang harus dan tidak boleh tampil"
     }
    }
   }
  },
  "/api/jalur.json": {
   "get": {
    "operationId": "jalurPenyelesaian",
    "summary": "Langkah penyelesaian pengaduan dan sengketa dengan tenggat",
    "responses": {
     "200": {
      "description": "Langkah dengan kutipan dasar"
     }
    }
   }
  },
  "/api/kewenangan.json": {
   "get": {
    "operationId": "kewenangan",
    "summary": "Siapa berwenang: lembaga dan kutipan pasal dasarnya",
    "responses": {
     "200": {
      "description": "Lembaga dengan kutipan dasar"
     }
    }
   }
  },
  "/api/tenggat.json": {
   "get": {
    "operationId": "tenggat",
    "summary": "Batas waktu di bidang energi dengan kutipan pasal",
    "responses": {
     "200": {
      "description": "Butir tenggat per kelompok dengan kutipan dasar"
     }
    }
   }
  },
  "/api/surat.json": {
   "get": {
    "operationId": "contohSurat",
    "summary": "Contoh surat",
    "responses": {
     "200": {
      "description": "Contoh surat dengan kutipan dasar"
     }
    }
   }
  },
  "/mcp": {
   "post": {
    "operationId": "mcp",
    "summary": "Server MCP baca-saja (JSON-RPC 2.0): initialize, tools/list, tools/call",
    "responses": {
     "200": {
      "description": "Balasan JSON-RPC"
     }
    }
   }
  },
  "/api/regulasi.json": {
   "get": {
    "operationId": "daftarRegulasi",
    "summary": "Seluruh peraturan di situs dengan status, hubungan, dan alamat teks",
    "responses": {
     "200": {
      "description": "Daftar (121 peraturan)"
     }
    }
   }
  },
  "/api/peta-dasar.json": {
   "get": {
    "operationId": "petaDasarHukum",
    "summary": "Peta dasar hukum sebagai graf: peraturan (simpul, dengan lapis hierarki) dan pencantuman di bagian Mengingat (sisi)",
    "responses": {
     "200": {
      "description": "Simpul dan sisi"
     }
    }
   }
  },
  "/api/membantu": {
   "get": {
    "operationId": "membantuCacah",
    "summary": "Cacah suara anonim ya/tidak tombol \"Apakah halaman ini membantu?\" untuk satu halaman (petunjuk kasar, bukan bukti kepuasan)",
    "parameters": [
     {
      "name": "halaman",
      "in": "query",
      "required": true,
      "description": "alamat halaman, mis. /tanya/",
      "schema": {
       "type": "string"
      },
      "example": "/tanya/"
     }
    ],
    "responses": {
     "200": {
      "description": "ya, tidak, suara terbanyak dalam satu jam, dan batas per jam"
     },
     "400": {
      "$ref": "#/components/schemas/Galat"
     },
     "503": {
      "$ref": "#/components/schemas/Galat"
     }
    }
   }
  }
 },
 "components": {
  "schemas": {
   "Galat": {
    "type": "object",
    "required": [
     "galat",
     "status",
     "penyebab",
     "perbaikan"
    ],
    "properties": {
     "galat": {
      "type": "boolean"
     },
     "status": {
      "type": "integer"
     },
     "penyebab": {
      "type": "string"
     },
     "perbaikan": {
      "type": "string"
     },
     "contoh": {}
    }
   }
  }
 }
}
