概述
API Key 通過/api/token 下的介面管理。這些介面使用認證與額度中介紹的系統存取權杖。
PUT /api/token/ 是完整的可變設定更新,不是 JSON Merge Patch。請求中必須包含所有需要保留的設定。可變欄位
| 欄位 | 型別 | 說明 |
|---|---|---|
id | integer | 更新時必填 |
name | string | 顯示名稱,最多 50 個字元 |
expired_time | integer | Unix 秒級時間戳;-1 表示永不過期 |
remain_quota | integer | 以內部單位表示的剩餘額度 |
unlimited_quota | boolean | 為 true 時取消 Key 級額度上限 |
model_limits_enabled | boolean | 是否啟用模型白名單 |
model_limits | string | 以逗號分隔的模型 ID |
allow_ips | string or null | 以換行分隔的 IP 或 CIDR;空字串或 null 表示不限制 |
group | string | 路由與計費分組 |
cross_group_retry | boolean | 跨分組重試,僅對受支援的自動分組有效 |
smart_routing | boolean | 是否為智慧路由 Key |
smart_route_tiers | string | JSON 字串形式的智慧路由層級設定 |
建立一般 API Key
curl -fsS -X POST "$BASE_URL/api/token/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
-H "Content-Type: application/json" \
-d '{
"name": "ci-deployment",
"expired_time": -1,
"remain_quota": 0,
"unlimited_quota": true,
"model_limits_enabled": false,
"model_limits": "",
"allow_ips": "",
"group": "default",
"cross_group_retry": false,
"smart_routing": false,
"smart_route_tiers": ""
}' | jq
列表與搜尋
一般 Key 列表預設排除智慧路由 Key:curl -fsS "$BASE_URL/api/token/?p=1&size=20" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" | jq
exclude_smart_routing=false 可包含所有 Key:
curl -fsS "$BASE_URL/api/token/?p=1&size=20&exclude_smart_routing=false" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" | jq
size、page_size 和 ps,每頁最多 100 條。
按名稱或已儲存的 Key 值搜尋:
curl -fsS --get "$BASE_URL/api/token/search" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
--data-urlencode "keyword=ci-deployment" \
--data-urlencode "p=1" \
--data-urlencode "size=20" | jq
token 查詢參數支援帶或不帶 sk- 字首的 Key。列表、搜尋和單條讀取回應中的 Key 始終經過掩碼處理。
讀取與顯示完整 Key
讀取掩碼記錄:curl -fsS "$BASE_URL/api/token/42" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" | jq
stored_key=$(curl -fsS -X POST "$BASE_URL/api/token/42/key" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
| jq -er '.data.key')
api_key="sk-${stored_key#sk-}"
sk-。請把回應直接寫入金鑰管理系統,不要列印到日誌。
一次最多顯示 100 個 Key:
curl -fsS -X POST "$BASE_URL/api/token/batch/keys" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
-H "Content-Type: application/json" \
-d '{"ids":[42,43]}'
安全更新 Key
先讀取目前記錄,構造完整的可變欄位請求內容,然後只修改目標欄位:current=$(curl -fsS "$BASE_URL/api/token/42" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID")
payload=$(jq '.data | {
id,
name,
expired_time,
remain_quota,
unlimited_quota,
model_limits_enabled,
model_limits,
allow_ips,
group,
cross_group_retry,
smart_routing,
smart_route_tiers
} | .name = "ci-deployment-v2"' <<< "$current")
curl -fsS -X PUT "$BASE_URL/api/token/" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
-H "Content-Type: application/json" \
-d "$payload" | jq
啟用或停用
僅更新狀態不會替換其他設定:curl -fsS -X PUT "$BASE_URL/api/token/?status_only=true" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
-H "Content-Type: application/json" \
-d '{"id":42,"status":2}' | jq
| 狀態 | 含義 |
|---|---|
1 | 已啟用 |
2 | 手動停用 |
3 | 已過期 |
4 | 額度已耗盡 |
刪除 Key
刪除一個 Key:curl -fsS -X DELETE "$BASE_URL/api/token/42" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" | jq
curl -fsS -X POST "$BASE_URL/api/token/batch" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "New-Api-User: $USER_ID" \
-H "Content-Type: application/json" \
-d '{"ids":[42,43]}' | jq
data 是實際刪除的記錄數量。
完整生命週期腳本
以下指令碼建立一個有效期為一小時、使用美元金額換算額度的 Key,然後完成定位、讀取完整 Key、更新、停用和刪除。指令碼不會把完整 Key 列印到標準輸出。#!/usr/bin/env bash
set -euo pipefail
: "${BASE_URL:=https://api.mixroute.ai}"
: "${ACCESS_TOKEN:?Set ACCESS_TOKEN}"
: "${USER_ID:?Set USER_ID}"
auth=(
-H "Authorization: Bearer $ACCESS_TOKEN"
-H "New-Api-User: $USER_ID"
)
name="automation-$(date +%s)-$RANDOM"
token_id=""
delete_token() {
local response
response=$(curl -fsS -X DELETE "$BASE_URL/api/token/$token_id" \
"${auth[@]}")
jq -e '.success == true' <<< "$response" >/dev/null
}
cleanup() {
if [[ -n "$token_id" ]]; then
delete_token >/dev/null 2>&1 || true
fi
}
trap cleanup EXIT
quota_per_unit=$(curl -fsS "$BASE_URL/api/status" | jq -er '.data.quota_per_unit')
expires_at=$(( $(date +%s) + 3600 ))
quota=$(( 5 * quota_per_unit ))
create_payload=$(jq -n \
--arg name "$name" \
--argjson expires "$expires_at" \
--argjson quota "$quota" '{
name: $name,
expired_time: $expires,
remain_quota: $quota,
unlimited_quota: false,
model_limits_enabled: false,
model_limits: "",
allow_ips: "",
group: "default",
cross_group_retry: false,
smart_routing: false,
smart_route_tiers: ""
}')
created=$(curl -fsS -X POST "$BASE_URL/api/token/" \
"${auth[@]}" -H "Content-Type: application/json" \
-d "$create_payload")
jq -e '.success == true' <<< "$created" >/dev/null
found=$(curl -fsS --get "$BASE_URL/api/token/search" \
"${auth[@]}" --data-urlencode "keyword=$name" \
--data-urlencode "p=1" --data-urlencode "size=10")
token_id=$(jq -er --arg name "$name" '
[.data.items[] | select(.name == $name)]
| if length == 1 then .[0].id
else error("expected exactly one matching API key")
end
' <<< "$found")
stored_key=$(curl -fsS -X POST "$BASE_URL/api/token/$token_id/key" \
"${auth[@]}" | jq -er '.data.key')
api_key="sk-${stored_key#sk-}"
# 將下一行空操作替換為金鑰管理系統命令。
: "$api_key"
unset stored_key api_key
current=$(curl -fsS "$BASE_URL/api/token/$token_id" "${auth[@]}")
update_payload=$(jq --argjson quota "$((10 * quota_per_unit))" '.data | {
id, name, expired_time, remain_quota, unlimited_quota,
model_limits_enabled, model_limits, allow_ips, group,
cross_group_retry, smart_routing, smart_route_tiers
} | .remain_quota = $quota' <<< "$current")
curl -fsS -X PUT "$BASE_URL/api/token/" \
"${auth[@]}" -H "Content-Type: application/json" \
-d "$update_payload" | jq -e '.success == true' >/dev/null
curl -fsS -X PUT "$BASE_URL/api/token/?status_only=true" \
"${auth[@]}" -H "Content-Type: application/json" \
-d "{\"id\":$token_id,\"status\":2}" \
| jq -e '.success == true' >/dev/null
delete_token
token_id=""
trap - EXIT
echo "API key lifecycle completed"