{"openapi":"3.0.3","info":{"title":"WilayahID API","version":"1.0.0","description":"Public API untuk data wilayah Indonesia + Admin API untuk token management dan usage reporting."},"servers":[{"url":"https://wilayahid-api.1dev.my.id"}],"tags":[{"name":"Public","description":"Endpoint publik (butuh API token)"},{"name":"Admin Auth","description":"Login admin (JWT)"},{"name":"Admin Tokens","description":"Manajemen API token"},{"name":"Admin Usage","description":"Usage analytics / report"},{"name":"Admin Upgrade Requests","description":"Review dan approve/reject permintaan upgrade plan developer"},{"name":"Admin Developers","description":"List developer terdaftar beserta plan aktif"},{"name":"Admin Plans","description":"List plan/tier yang tersedia"},{"name":"Auth","description":"Self-serve developer registration, verifikasi email, login, reset password (publik)"},{"name":"Developer","description":"Profil, token, usage, dan upgrade request milik developer (butuh Developer JWT)"}],"components":{"securitySchemes":{"ApiTokenBearer":{"type":"http","scheme":"bearer","bearerFormat":"wil.xxxxxxxx","description":"API token via Authorization: Bearer <token>"},"ApiTokenHeader":{"type":"apiKey","in":"header","name":"X-Api-Token","description":"API token via header X-Api-Token: <token>"},"AdminBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Admin JWT via Authorization: Bearer <jwt>"},"DeveloperBearer":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"Developer JWT via Authorization: Bearer <jwt>"}},"schemas":{"ErrorResponse":{"type":"object","properties":{"message":{"type":"string"},"meta":{"type":"object","additionalProperties":true}},"required":["message"]},"WilayahItem":{"type":"object","properties":{"kode":{"type":"string","example":"31.74"},"nama":{"type":"string","example":"Kota Administrasi Jakarta Selatan"}},"required":["kode","nama"]},"PaginatedMeta":{"type":"object","properties":{"page":{"type":"integer","example":1},"limit":{"type":"integer","example":25},"total":{"type":"integer","example":91599}},"required":["page","limit","total"]},"WilayahListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WilayahItem"}},"meta":{"$ref":"#/components/schemas/PaginatedMeta"}},"required":["data","meta"]},"ProvincesListResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/WilayahItem"}},"meta":{"type":"object","properties":{"total":{"type":"integer"}},"required":["total"]}},"required":["data","meta"]},"AdminLoginRequest":{"type":"object","properties":{"usernameOrEmail":{"type":"string"},"username":{"type":"string"},"email":{"type":"string"},"password":{"type":"string"}},"required":["password"]},"AdminLoginResponse":{"type":"object","properties":{"token":{"type":"string"},"admin":{"type":"object","properties":{"id":{"type":"string"},"username":{"type":"string"},"email":{"type":"string","nullable":true},"role":{"type":"string","nullable":true}},"required":["id","username","email","role"]}},"required":["token","admin"]},"MessageResponse":{"type":"object","properties":{"message":{"type":"string"}},"required":["message"]},"RegisterRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string","minLength":8,"example":"password123"}},"required":["email","password"]},"VerifyEmailRequest":{"type":"object","properties":{"token":{"type":"string"}},"required":["token"]},"VerifyEmailResponse":{"type":"object","properties":{"message":{"type":"string"},"apiToken":{"type":"string","example":"wil.xxxxxxxx"}},"required":["message","apiToken"]},"LoginRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"},"password":{"type":"string"}},"required":["email","password"]},"LoginResponse":{"type":"object","properties":{"token":{"type":"string"},"developer":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"}},"required":["id","email"]}},"required":["token","developer"]},"ForgotPasswordRequest":{"type":"object","properties":{"email":{"type":"string","format":"email"}},"required":["email"]},"ResetPasswordRequest":{"type":"object","properties":{"token":{"type":"string"},"newPassword":{"type":"string","minLength":8}},"required":["token","newPassword"]},"DeveloperProfile":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"email_verified":{"type":"integer","enum":[0,1]},"is_active":{"type":"integer","enum":[0,1]},"created_at":{"type":"string"},"last_login_at":{"type":"string","nullable":true}}},"PlanSummary":{"type":"object","properties":{"plan_id":{"type":"string","nullable":true},"plan_key":{"type":"string","example":"free"},"plan_name":{"type":"string","example":"Free"},"max_tokens":{"type":"integer","example":1},"limit_window":{"type":"string","enum":["DAILY","MONTHLY"]},"limit_max_requests":{"type":"integer","nullable":true},"price_idr":{"type":"integer","example":0}}},"DeveloperMeResponse":{"type":"object","properties":{"developer":{"$ref":"#/components/schemas/DeveloperProfile"},"subscription":{"type":"object","nullable":true},"plan":{"type":"object","nullable":true}},"required":["developer"]},"ApiTokenItem":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token_prefix":{"type":"string","example":"wil.1a2b"},"status":{"type":"string","enum":["ACTIVE","REVOKED"]},"limit_window":{"type":"string","enum":["DAILY","MONTHLY"]},"limit_max_requests":{"type":"integer","nullable":true},"expires_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"revoked_at":{"type":"string","nullable":true},"last_used_at":{"type":"string","nullable":true}}},"DeveloperTokensResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/ApiTokenItem"}}},"required":["data"]},"CreateDeveloperTokenRequest":{"type":"object","properties":{"name":{"type":"string","example":"my-token"}}},"CreateDeveloperTokenResponse":{"type":"object","properties":{"token":{"type":"string","example":"wil.xxxxxxxx"},"data":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"},"token_prefix":{"type":"string"},"status":{"type":"string"},"limit_window":{"type":"string"},"limit_max_requests":{"type":"integer","nullable":true}}}},"required":["token","data"]},"OkResponse":{"type":"object","properties":{"ok":{"type":"boolean"}},"required":["ok"]},"DeveloperUsageResponse":{"type":"object","properties":{"data":{"type":"array","items":{"type":"object"}},"meta":{"type":"object","properties":{"from":{"type":"string"},"to":{"type":"string"}},"required":["from","to"]}},"required":["data","meta"]},"UpgradeRequestItem":{"type":"object","properties":{"id":{"type":"string"},"plan_key":{"type":"string"},"plan_name":{"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"payment_note":{"type":"string","nullable":true},"rejection_reason":{"type":"string","nullable":true},"reviewed_at":{"type":"string","nullable":true},"created_at":{"type":"string"}}},"CreateUpgradeRequestRequest":{"type":"object","properties":{"planKey":{"type":"string","example":"pro"},"paymentNote":{"type":"string","nullable":true}},"required":["planKey"]},"CreateUpgradeRequestResponse":{"type":"object","properties":{"data":{"type":"object","properties":{"id":{"type":"string"},"plan_key":{"type":"string"},"plan_name":{"type":"string"},"status":{"type":"string"}}}},"required":["data"]},"DeveloperUpgradeRequestsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/UpgradeRequestItem"}}},"required":["data"]},"AdminUpgradeRequestItem":{"type":"object","properties":{"id":{"type":"string"},"status":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]},"payment_note":{"type":"string","nullable":true},"rejection_reason":{"type":"string","nullable":true},"reviewed_at":{"type":"string","nullable":true},"created_at":{"type":"string"},"developer_id":{"type":"string"},"developer_email":{"type":"string"},"plan_key":{"type":"string"},"plan_name":{"type":"string"}}},"AdminUpgradeRequestsResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminUpgradeRequestItem"}}},"required":["data"]},"RejectUpgradeRequestRequest":{"type":"object","properties":{"reason":{"type":"string","nullable":true}}},"AdminDeveloperItem":{"type":"object","properties":{"id":{"type":"string"},"email":{"type":"string"},"email_verified":{"type":"integer","enum":[0,1]},"is_active":{"type":"integer","enum":[0,1]},"created_at":{"type":"string"},"last_login_at":{"type":"string","nullable":true},"plan_key":{"type":"string","nullable":true},"plan_name":{"type":"string","nullable":true}}},"AdminDevelopersResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/AdminDeveloperItem"}}},"required":["data"]},"PlanItem":{"type":"object","properties":{"id":{"type":"string"},"key":{"type":"string"},"name":{"type":"string"},"max_tokens":{"type":"integer"},"limit_window":{"type":"string","enum":["DAILY","MONTHLY"]},"limit_max_requests":{"type":"integer","nullable":true},"price_idr":{"type":"integer"},"sort_order":{"type":"integer"},"is_active":{"type":"integer","enum":[0,1]}}},"AdminPlansResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/PlanItem"}}},"required":["data"]}}},"paths":{"/":{"get":{"tags":["Public"],"summary":"Health check","responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean"},"service":{"type":"string"}},"required":["ok","service"]}}}}}}},"/v1/wilayah":{"get":{"tags":["Public"],"summary":"List/filter wilayah (single table)","description":"Token bisa dikirim via Authorization Bearer / X-Api-Token / query param token. Default sort: kode.","security":[{"ApiTokenBearer":[]},{"ApiTokenHeader":[]}],"parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string"}},{"name":"kode","in":"query","required":false,"schema":{"type":"string"}},{"name":"parent_kode","in":"query","required":false,"schema":{"type":"string"}},{"name":"level","in":"query","required":false,"schema":{"type":"integer","minimum":0,"maximum":3}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}},{"name":"sort","in":"query","required":false,"schema":{"type":"string","enum":["kode","nama"]}},{"name":"order","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WilayahListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"429":{"description":"Rate limit exceeded","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/provinces":{"get":{"tags":["Public"],"summary":"List provinces","security":[{"ApiTokenBearer":[]},{"ApiTokenHeader":[]}],"parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string"}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ProvincesListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/regencies":{"get":{"tags":["Public"],"summary":"List regencies/cities","security":[{"ApiTokenBearer":[]},{"ApiTokenHeader":[]}],"parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string"}},{"name":"province_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"type","in":"query","required":false,"schema":{"type":"string","enum":["KOTA","KABUPATEN"]}},{"name":"q","in":"query","required":false,"schema":{"type":"string"}},{"name":"page","in":"query","required":false,"schema":{"type":"integer","minimum":1}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":100}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/WilayahListResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/v1/regencies/{kode}":{"get":{"tags":["Public"],"summary":"Get regency detail by kode","security":[{"ApiTokenBearer":[]},{"ApiTokenHeader":[]}],"parameters":[{"name":"token","in":"query","required":false,"schema":{"type":"string"}},{"name":"kode","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/WilayahItem"}},"required":["data"]}}}},"400":{"description":"Invalid kode","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/auth/login":{"post":{"tags":["Admin Auth"],"summary":"Admin login (JWT)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLoginRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminLoginResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/tokens":{"get":{"tags":["Admin Tokens"],"summary":"List API tokens","security":[{"AdminBearer":[]}],"parameters":[{"name":"service","in":"query","required":false,"schema":{"type":"string"}},{"name":"service_key","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Admin Tokens"],"summary":"Create API token (plaintext returned once)","security":[{"AdminBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"serviceKey":{"type":"string","example":"wilayah"},"limitWindow":{"type":"string","enum":["DAILY","MONTHLY"]},"limitMaxRequests":{"type":"integer","nullable":true},"expiresAt":{"type":"string","format":"date-time","nullable":true}}}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/tokens/{id}/revoke":{"post":{"tags":["Admin Tokens"],"summary":"Revoke API token","security":[{"AdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/usage/daily":{"get":{"tags":["Admin Usage"],"summary":"Daily usage rows","security":[{"AdminBearer":[]}],"parameters":[{"name":"day","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"from","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"token_id","in":"query","required":false,"schema":{"type":"string"}},{"name":"service","in":"query","required":false,"schema":{"type":"string"}},{"name":"endpoint","in":"query","required":false,"schema":{"type":"string"}},{"name":"method","in":"query","required":false,"schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"schema":{"type":"integer"}},{"name":"offset","in":"query","required":false,"schema":{"type":"integer"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/usage/summary/tokens":{"get":{"tags":["Admin Usage"],"summary":"Usage summary by token","security":[{"AdminBearer":[]}],"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"service","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/usage/summary/endpoints":{"get":{"tags":["Admin Usage"],"summary":"Usage summary by endpoint","security":[{"AdminBearer":[]}],"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"token_id","in":"query","required":false,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"type":"object"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/upgrade-requests":{"get":{"tags":["Admin Upgrade Requests"],"summary":"List all upgrade requests","security":[{"AdminBearer":[]}],"parameters":[{"name":"status","in":"query","required":false,"schema":{"type":"string","enum":["PENDING","APPROVED","REJECTED"]}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminUpgradeRequestsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/upgrade-requests/{id}/approve":{"post":{"tags":["Admin Upgrade Requests"],"summary":"Approve upgrade request","description":"Mengubah status request jadi APPROVED, membuat subscription baru, update limit token aktif developer.","security":[{"AdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Request not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Request not in PENDING status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/upgrade-requests/{id}/reject":{"post":{"tags":["Admin Upgrade Requests"],"summary":"Reject upgrade request","security":[{"AdminBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RejectUpgradeRequestRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Request not found","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Request not in PENDING status","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/developers":{"get":{"tags":["Admin Developers"],"summary":"List all developers with active plan","security":[{"AdminBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminDevelopersResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/admin/plans":{"get":{"tags":["Admin Plans"],"summary":"List all plans","security":[{"AdminBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdminPlansResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/auth/register":{"post":{"tags":["Auth"],"summary":"Register developer (self-serve)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/RegisterRequest"}}}},"responses":{"201":{"description":"Registrasi berhasil","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Email already registered","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/auth/verify-email":{"post":{"tags":["Auth"],"summary":"Verify email and get free-tier API token","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailRequest"}}}},"responses":{"200":{"description":"Email terverifikasi, API token diberikan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/VerifyEmailResponse"}}}},"400":{"description":"Invalid/expired token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server misconfigured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/auth/login":{"post":{"tags":["Auth"],"summary":"Developer login (JWT)","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}}},"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginResponse"}}}},"401":{"description":"Invalid credentials","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Email not verified","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/auth/forgot-password":{"post":{"tags":["Auth"],"summary":"Request password reset link (always 200)","description":"Selalu return 200 untuk mencegah email enumeration.","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ForgotPasswordRequest"}}}},"responses":{"200":{"description":"Reset link akan dikirim jika email terdaftar","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}}}}},"/auth/reset-password":{"post":{"tags":["Auth"],"summary":"Reset password with token","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResetPasswordRequest"}}}},"responses":{"200":{"description":"Password berhasil diubah","content":{"application/json":{"schema":{"$ref":"#/components/schemas/MessageResponse"}}}},"400":{"description":"Invalid/expired token","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/developer/me":{"get":{"tags":["Developer"],"summary":"Get developer profile + active plan","security":[{"DeveloperBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperMeResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/developer/tokens":{"get":{"tags":["Developer"],"summary":"List own API tokens","security":[{"DeveloperBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperTokensResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Developer"],"summary":"Create new API token (enforce plan max_tokens)","security":[{"DeveloperBearer":[]}],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeveloperTokenRequest"}}}},"responses":{"201":{"description":"Token created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateDeveloperTokenResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"403":{"description":"Max tokens reached for plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"500":{"description":"Server misconfigured","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/developer/tokens/{id}/revoke":{"post":{"tags":["Developer"],"summary":"Revoke own API token","security":[{"DeveloperBearer":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/OkResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"404":{"description":"Token not found or already revoked","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/developer/usage":{"get":{"tags":["Developer"],"summary":"Usage summary for own tokens","security":[{"DeveloperBearer":[]}],"parameters":[{"name":"from","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}},{"name":"to","in":"query","required":false,"schema":{"type":"string","example":"2026-01-15"}}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperUsageResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}},"/developer/upgrade-requests":{"get":{"tags":["Developer"],"summary":"List own upgrade requests","security":[{"DeveloperBearer":[]}],"responses":{"200":{"description":"OK","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeveloperUpgradeRequestsResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}},"post":{"tags":["Developer"],"summary":"Submit upgrade request","security":[{"DeveloperBearer":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUpgradeRequestRequest"}}}},"responses":{"201":{"description":"Upgrade request created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateUpgradeRequestResponse"}}}},"400":{"description":"Invalid request","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"401":{"description":"Unauthorized","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}},"409":{"description":"Pending request already exists for this plan","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ErrorResponse"}}}}}}}}}