# Admin

管理控制平面：登入、API key 與方案管理

## GET /admin/api/api-keys

> \`GET /admin/api/api-keys\`：列出所有 API key。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/api-keys":{"get":{"tags":["admin"],"summary":"`GET /admin/api/api-keys`：列出所有 API key。","operationId":"list_keys","responses":{"200":{"description":"API key 列表","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","description":"API key 摘要（後台列表用）。","required":["id","key_prefix","name","status","plan_id","credit_balance","created_at"],"properties":{"created_at":{"type":"string","format":"date-time"},"credit_balance":{"type":"integer","format":"int64"},"id":{"type":"string","format":"uuid"},"key_prefix":{"type":"string"},"last_used_at":{"type":["string","null"],"format":"date-time"},"name":{"type":"string"},"plan_id":{"type":"string","format":"uuid"},"status":{"type":"string"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}}}}}}}
```

## POST /admin/api/api-keys

> \`POST /admin/api/api-keys\`：建立 API key（回傳一次性明碼）。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"CreateApiKeyRequest":{"type":"object","description":"建立 API key 請求。","required":["name","plan_id"],"properties":{"initial_credit":{"type":"integer","format":"int64","description":"初始 credit 餘額。"},"name":{"type":"string"},"plan_id":{"type":"string","format":"uuid"}}},"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/api-keys":{"post":{"tags":["admin"],"summary":"`POST /admin/api/api-keys`：建立 API key（回傳一次性明碼）。","operationId":"create_key","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateApiKeyRequest"}}},"required":true},"responses":{"200":{"description":"建立成功（含一次性明碼 key）","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"object","description":"建立成功回應（**含明碼 key，僅此一次**）。","required":["id","key_prefix","raw_key"],"properties":{"id":{"type":"string","format":"uuid"},"key_prefix":{"type":"string"},"raw_key":{"type":"string","description":"明碼 key，請當場保存，無法再取回。"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"輸入不合法（如方案不存在）"}}}}}}
```

## POST /admin/api/api-keys/{id}/credit

> \`POST /admin/api/api-keys/{id}/credit\`：調整 credit 餘額。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"AdjustCreditRequest":{"type":"object","description":"調整 credit 請求。","required":["delta"],"properties":{"delta":{"type":"integer","format":"int64","description":"變動量，可正（增點）可負（扣點）。"}}},"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/api-keys/{id}/credit":{"post":{"tags":["admin"],"summary":"`POST /admin/api/api-keys/{id}/credit`：調整 credit 餘額。","operationId":"adjust_credit","parameters":[{"name":"id","in":"path","description":"API key 內部 ID","required":true,"schema":{"type":"string","format":"uuid"}}],"requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AdjustCreditRequest"}}},"required":true},"responses":{"200":{"description":"調整後餘額","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"object","description":"credit 調整結果。","required":["id","credit_balance"],"properties":{"credit_balance":{"type":"integer","format":"int64"},"id":{"type":"string","format":"uuid"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"404":{"description":"找不到該 key"}}}}}}
```

## POST /admin/api/api-keys/{id}/revoke

> \`POST /admin/api/api-keys/{id}/revoke\`：撤銷一把 key。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}}},"paths":{"/admin/api/api-keys/{id}/revoke":{"post":{"tags":["admin"],"summary":"`POST /admin/api/api-keys/{id}/revoke`：撤銷一把 key。","operationId":"revoke_key","parameters":[{"name":"id","in":"path","description":"API key 內部 ID","required":true,"schema":{"type":"string","format":"uuid"}}],"responses":{"204":{"description":"已撤銷"},"404":{"description":"找不到該 key"}}}}}}
```

## POST /admin/api/login

> \`POST /admin/api/login\`：帳密登入，成功時於 httpOnly cookie 設 session。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"paths":{"/admin/api/login":{"post":{"tags":["admin"],"summary":"`POST /admin/api/login`：帳密登入，成功時於 httpOnly cookie 設 session。","operationId":"login","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/LoginRequest"}}},"required":true},"responses":{"200":{"description":"登入成功，並設定 session cookie","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"object","description":"管理員資訊（登入成功 / `/me` 回傳）。","required":["admin_id","email","role","must_change_password"],"properties":{"admin_id":{"type":"string","format":"uuid"},"email":{"type":"string"},"must_change_password":{"type":"boolean","description":"是否需強制改密碼（前端據此導向改密碼流程）。"},"role":{"type":"string"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"帳號或密碼錯誤"},"403":{"description":"帳號已停用"}}}}},"components":{"schemas":{"LoginRequest":{"type":"object","description":"登入請求。","required":["email","password"],"properties":{"email":{"type":"string"},"password":{"type":"string"}}},"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}}}
```

## POST /admin/api/logout

> \`POST /admin/api/logout\`：刪除 session 並清除 cookie。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}}},"paths":{"/admin/api/logout":{"post":{"tags":["admin"],"summary":"`POST /admin/api/logout`：刪除 session 並清除 cookie。","operationId":"logout","responses":{"204":{"description":"已登出"}}}}}}
```

## GET /admin/api/me

> \`GET /admin/api/me\`：回傳目前登入的管理員資訊。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/me":{"get":{"tags":["admin"],"summary":"`GET /admin/api/me`：回傳目前登入的管理員資訊。","operationId":"me","responses":{"200":{"description":"目前管理員","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"object","description":"管理員資訊（登入成功 / `/me` 回傳）。","required":["admin_id","email","role","must_change_password"],"properties":{"admin_id":{"type":"string","format":"uuid"},"email":{"type":"string"},"must_change_password":{"type":"boolean","description":"是否需強制改密碼（前端據此導向改密碼流程）。"},"role":{"type":"string"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"401":{"description":"未登入 / session 失效"}}}}}}
```

## GET /admin/api/plans

> \`GET /admin/api/plans\`：列出方案。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/plans":{"get":{"tags":["admin"],"summary":"`GET /admin/api/plans`：列出方案。","operationId":"list_plans","responses":{"200":{"description":"方案列表","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"array","items":{"type":"object","description":"方案視圖。","required":["id","name","monthly_credit_quota"],"properties":{"id":{"type":"string","format":"uuid"},"monthly_credit_quota":{"type":"integer","format":"int64"},"name":{"type":"string"},"rate_limit_burst":{"type":["integer","null"],"format":"int32"},"rate_limit_rps":{"type":["integer","null"],"format":"int32"}}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}}}}}}}
```

## POST /admin/api/plans

> \`POST /admin/api/plans\`：建立方案。

```json
{"openapi":"3.1.0","info":{"title":"Blockchain Atlantis API Gateway","version":"0.1.0"},"tags":[{"name":"admin","description":"管理控制平面：登入、API key 與方案管理"}],"security":[{"admin_session":[]}],"components":{"securitySchemes":{"admin_session":{"type":"http","scheme":"bearer"}},"schemas":{"CreatePlanRequest":{"type":"object","description":"建立方案請求。","required":["name"],"properties":{"monthly_credit_quota":{"type":"integer","format":"int64"},"name":{"type":"string"},"rate_limit_burst":{"type":["integer","null"],"format":"int32"},"rate_limit_rps":{"type":["integer","null"],"format":"int32"}}},"Meta":{"type":"object","description":"回應的中繼資訊。所有欄位都是 `Option`，沒有的就不會出現在 JSON 裡\n（搭配 `skip_serializing_if`），維持輸出乾淨。","properties":{"credit_cost":{"type":["integer","null"],"format":"int64","description":"本次請求扣掉的 credit 數量（計費後填入）。"},"credit_remaining":{"type":["integer","null"],"format":"int64","description":"本次請求後剩餘的 credit 餘額。"},"pagination":{"oneOf":[{"type":"null"},{"$ref":"#/components/schemas/PaginationMeta","description":"分頁資訊（僅列表型 endpoint 會帶）。"}]},"request_id":{"type":["string","null"],"description":"本次請求的唯一識別碼，與 log / 追蹤系統對應，方便客訴時定位。"}}},"PaginationMeta":{"type":"object","description":"對外的分頁中繼資訊。","required":["limit","offset"],"properties":{"limit":{"type":"integer","format":"int32","minimum":0},"offset":{"type":"integer","format":"int32","minimum":0},"total":{"type":["integer","null"],"format":"int64","description":"符合條件的總筆數（若下游能提供）。","minimum":0}}}}},"paths":{"/admin/api/plans":{"post":{"tags":["admin"],"summary":"`POST /admin/api/plans`：建立方案。","operationId":"create_plan","requestBody":{"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreatePlanRequest"}}},"required":true},"responses":{"200":{"description":"建立的方案","content":{"application/json":{"schema":{"type":"object","description":"統一成功回應信封。\n\n- `data`：實際的業務資料（泛型 `T`，必須可序列化）。\n- `meta`：與這次請求有關的中繼資訊（request id、分頁、credit 用量等）。","required":["data","meta"],"properties":{"data":{"type":"object","description":"方案視圖。","required":["id","name","monthly_credit_quota"],"properties":{"id":{"type":"string","format":"uuid"},"monthly_credit_quota":{"type":"integer","format":"int64"},"name":{"type":"string"},"rate_limit_burst":{"type":["integer","null"],"format":"int32"},"rate_limit_rps":{"type":["integer","null"],"format":"int32"}}},"meta":{"$ref":"#/components/schemas/Meta"}}}}}},"400":{"description":"輸入不合法"}}}}}}
```


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.blockchainsecurity.asia/api-reference/readme/admin.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
