关于 venice-api-keys
venice-api-keys 是通过 Venice 管理端点管理 Bearer API 密钥的 Skill,面向账户管理员。它支持创建、配置、查看和撤销密钥,并检查密钥对应的余额与速率限制。
主要功能
- 01列出、创建、更新和撤销密钥
- 02设置有效期和消费限额
- 03按模型隐私级别限制密钥
- 04查看密钥使用情况和详情
- 05检查余额与速率限制
适用场景
- 01为客户应用签发限额密钥
- 02轮换或撤销泄露的密钥
- 03将密钥限制为仅用私有模型
- 04检查密钥是否可以发起请求
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ veniceai/ skills --skill venice-api-keys安装后在 Claude Code 中输入/venice-api-keys确认已加载。
详细介绍
Venice API 密钥
用于管理 Bearer API 密钥的管理端点。管理路由需要 ADMIN 密钥。若仅使用钱包进行身份验证,请改用 venice-auth / venice-x402。
| 端点 | 密钥类型 | 用途 |
|---|---|---|
GET /api_keys | ADMIN | 列出你的有效密钥(已遮蔽)。 |
POST /api_keys | ADMIN | 创建密钥。响应中包含唯一一份密钥。 |
PATCH /api_keys | ADMIN | 更新 description、expiresAt、consumptionLimit、limitPeriod、modelPrivacy。 |
DELETE /api_keys?id=... | ADMIN | 撤销密钥。 |
GET /api_keys/{id} | ADMIN | 查看单个密钥的完整详情(用量、限额、过期时间)。 |
GET /api_keys/rate_limits | 任意 | 查看调用密钥的余额和各模型速率限制。 |
GET /api_keys/rate_limits/log | ADMIN | 查看账户最近 50 次速率限制超限记录。 |
GET /api_keys/generate_web3_key | 无 | 获取用于通过钱包签名的短期令牌。 |
POST /api_keys/generate_web3_key | 无 | 证明钱包持有质押的 VVV 并铸造 API 密钥。 |
限制:创建密钥(POST /api_keys)的速率上限为每位用户每分钟 20 次请求,且每位用户最多持有 500 个有效密钥(过期密钥不计入)。
请求未提供 Authorization 标头时,会收到 402 x402 身份验证质询,而不是 401;密钥无效时则会收到 401。
密钥类型
| 类型 | 可调用的端点 |
|---|---|
INFERENCE | 推理和实用工具路由——/chat/completions、/responses、/decisions、/systemone、/image/*、/images/generations、/audio/*、/video/*、/embeddings、/augment/*、/crypto/rpc/*、/characters*、/models*——以及 GET /api_keys/rate_limits。仅限管理员的路由会返回 401 "Admin API key required"。 |
ADMIN | 上述所有端点,以及 GET/POST/PATCH/DELETE /api_keys、GET /api_keys/{id}、GET /api_keys/rate_limits/log 和所有账单路由(/billing/balance、/billing/usage-history、/billing/usage-analytics)。 |
密钥以 VENICE_INFERENCE_KEY_ 或 VENICE_ADMIN_KEY_ 开头。叶级应用几乎总是应使用 INFERENCE 密钥——按应用、按用户配置,并设置用量上限。
GET /api_keys
curl https://api.venice.ai/api/v1/api_keys \
-H "Authorization: Bearer $VENICE_ADMIN_KEY"
{
"object": "list",
"data": [
{
"id": "e28e82dc-9df2-4b47-b726-d0a222ef2ab5",
"apiKeyType": "INFERENCE",
"description": "backend prod",
"createdAt": "2025-10-01T12:00:00.000Z",
"expiresAt": null,
"lastUsedAt": "2026-04-20T10:05:00.000Z",
"last6Chars": "2V2jNW",
"consumptionLimits": { "usd": 50, "diem": 10, "vcu": null },
"limitPeriod": "MONTH",
"modelPrivacy": "ALL",
"usage": { "trailingSevenDays": { "usd": "4.2000", "vcu": "0.0000", "diem": "0.0000" } },
"currentPeriodUsage": { "usd": "12.5000", "diem": "0.0000" }
}
]
}
- 仅列出未过期的密钥,按创建时间从新到旧排序。绝不会返回完整密钥——只返回
last6Chars。 usage.trailingSevenDays和currentPeriodUsage的值是保留 4 位小数的字符串。usd数值包含捆绑额度支出,但不包含赚取额度支出,即使 USD 限额会同时计算两者。currentPeriodUsage表示当前limitPeriod窗口内的支出,且仅当密钥设置了 USD 或 DIEM 限额时才会出现。consumptionLimits.vcu已弃用,但始终会显示;请忽略它。
POST /api_keys — 创建
curl https://api.venice.ai/api/v1/api_keys \
-H "Authorization: Bearer $VENICE_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{
"apiKeyType": "INFERENCE",
"description": "backend prod",
"expiresAt": "2026-12-31T23:59:59Z",
"consumptionLimit": { "usd": 50, "diem": 10 },
"limitPeriod": "MONTH",
"modelPrivacy": "PRIVATE_ONLY"
}'
{
"success": true,
"data": {
"id": "e28e82dc-9df2-4b47-b726-d0a222ef2ab5",
"apiKey": "VENICE_INFERENCE_KEY_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"apiKeyType": "INFERENCE",
"description": "backend prod",
"expiresAt": "2026-12-31T23:59:59.000Z",
"consumptionLimit": { "usd": 50, "diem": 10, "vcu": null },
"limitPeriod": "MONTH",
"modelPrivacy": "PRIVATE_ONLY"
}
}
立即保存 apiKey——Venice 不会再次显示密钥。若丢失,请删除并重新创建。请求正文采用严格校验:未知字段会导致 400。
必填项
apiKeyType—INFERENCE或ADMIN。description— 字符串,最多 64 个字符。
可选项
expiresAt—""、日期YYYY-MM-DD或 UTC 日期时间YYYY-MM-DDTHH:mm:ss[.sss]Z。若密钥永不过期,请省略此项(或设为"")。consumptionLimit.usd/.diem— 数值0–9999999999,或设为null表示不设上限。USD 限额会限制USD、BUNDLED_CREDITS和EARNED_CREDITS的总支出;DIEM 限额会限制 DIEM 支出。consumptionLimit.vcu— 已弃用(旧版 DIEM)。请使用diem。limitPeriod— 限额的统计周期。默认为EPOCH。modelPrivacy— 此密钥可调用的模型。默认为ALL。
limitPeriod
| 值 | 周期 |
|---|---|
EPOCH | 每个 UTC 日重置(默认,旧版行为)。 |
MONTH | 每个日历月的 1 日 00:00 UTC 重置。 |
LIFETIME | 永不重置 — 对该密钥设置永久上限。 |
当密钥达到限额但账户仍有余额时,推理请求会返回 402,且仅包含一个 error 字符串:"API key USD spend limit exceeded. Your account may still have USD balance, but this API key has reached its configured USD spending limit."(或将 USD 替换为 DIEM)。响应中没有 code 字段。
modelPrivacy
此设置会在每个推理路由上强制执行。若模型不符合要求,则返回 403("This API key is set to '…', but is an Anonymous model. Choose a Private, TEE, or E2EE model, or change the model privacy setting of this API key.")。使用此密钥调用 GET /models、/models/traits 和 /models/compatibility_mapping 时,结果会筛选为该密钥可使用的模型。
| 值 | 效果 |
|---|---|
ALL | 任意模型(默认)。 |
PRIVATE_TEXT | 文本、嵌入和决策模型必须为 Private、TEE 或 E2EE。图像/音频/视频模型可以是 Anonymous。 |
PRIVATE_ONLY | 所有模型都必须为 Private、TEE 或 E2EE。Anonymous 模型会被拒绝。 |
对于受限密钥,GET /models 仅返回该密钥可调用的模型 — 这是选择允许模型的最简单方式(参见 venice-models)。
PATCH /api_keys — 更新
curl -X PATCH https://api.venice.ai/api/v1/api_keys \
-H "Authorization: Bearer $VENICE_ADMIN_KEY" \
-H "Content-Type: application/json" \
-d '{ "id": "e28e82dc-9df2-4b47-b726-d0a222ef2ab5", "description": "renamed", "consumptionLimit": { "usd": 100 }, "limitPeriod": "LIFETIME" }'
- 必须提供
id;其他所有字段均为可选,且只会更改你发送的字段。无法更改apiKeyType。 - 可更改字段:
description(≤ 64 个字符)、expiresAt、consumptionLimit(usd/diem/vcu,每项都可以设为null以移除对应上限)、limitPeriod、modelPrivacy。 - 传入
"expiresAt": ""或null可移除过期时间。 - 返回
{ success: true, data: { id, apiKeyType, description, createdAt, expiresAt, lastUsedAt, last6Chars, consumptionLimits, limitPeriod, modelPrivacy } }。 - 未知或已过期的
id→400"API key not found or expired"。
DELETE /api_keys?id=<uuid> — 撤销
curl -X DELETE "https://api.venice.ai/api/v1/api_keys?id=e28e82dc-9df2-4b47-b726-d0a222ef2ab5" \
-H "Authorization: Bearer $VENICE_ADMIN_KEY"
也可以在 JSON 请求体中传入 ID { "id": "..." }。返回 {"success": true}。未知密钥 → 400 "API key could not be found"。撤销会立即生效。
GET /api_keys/{id} — 详情
返回 { data: <key> },包含与列表项相同的字段(usage.trailingSevenDays、受限时的 currentPeriodUsage、limitPeriod、modelPrivacy 等)。ID 未知或已过期 → 400 "API key not found"。
GET /api_keys/rate_limits
可使用任何类型的密钥调用;返回的是当前调用所用密钥的信息。
curl https://api.venice.ai/api/v1/api_keys/rate_limits \
-H "Authorization: Bearer $VENICE_API_KEY"
{
"data": {
"accessPermitted": true,
"apiTier": { "id": "paid", "isCharged": true },
"balances": { "USD": 50.23, "DIEM": 100.023, "BUNDLED_CREDITS": 25 },
"keyExpiration": null,
"nextEpochBegins": "2026-04-21T00:00:00.000Z",
"rateLimits": [
{
"apiModelId": "zai-org-glm-5-1",
"rateLimits": [
{ "type": "RPM", "amount": 100 },
{ "type": "TPM", "amount": 2000000 }
]
}
]
}
}
accessPermitted是实际的准入检查(余额、单密钥限额、账户状态)— 建议优先使用它,而不是/billing/balance中的canConsume。balances表示此密钥当前可支出的余额:每种账户余额都会限制为不超过该密钥的剩余限额。BUNDLED_CREDITS以 USD 计价;如果套餐不含此额度,其值为0。不包含已赚取的额度。未知时,三项中的任何一项都可能被省略。apiTier.id是账户的 API 等级(例如paid);isCharged始终为true。rateLimits[].rateLimits[].type为RPM(每分钟请求数)、RPD(每日请求数)或TPM(每分钟令牌数);上方显示的数量仅为示例 — 请以响应中的值为准。视频和音乐模型返回空数组(它们不受吞吐量限制)。nextEpochBegins表示 DIEM 分配额和EPOCH周期密钥限额的重置时间。
GET /api_keys/rate_limits/log
需要 ADMIN 密钥。返回账户最近 50 次速率限制超限记录,按时间从新到旧排列:
{
"object": "list",
"data": [
{ "apiKeyId": "e28e82dc-...", "modelId": "zai-org-glm-5-1", "rateLimitType": "RPM",
"rateLimitTier": "paid", "timestamp": "2026-04-20T12:34:56.000Z" }
]
}
rateLimitType 的值包括:
| 值 | 含义 |
|---|---|
RPM / TPM / RPD | 按模型设置的吞吐量上限。 |
FAILED_REQUESTS | 通用错误预算:30 秒内客户端错误响应(除 429 外的 4xx)超过 50 次。 |
UNSUPPORTED_FEATURE_REQUESTS | 在 /chat/completions 或 /responses 上,30 秒内因“模型不支持此功能”而被拒绝超过 200 次。 |
modelId 通常是模型 ID,但端点级限制会记录为 endpoint:api/v1/...(例如 endpoint:api/v1/crypto/rpc),无法解析的模型名称会记录为 model:unknown。
Web3 API 密钥 — 两步钱包流程
允许在 Base 上持有 已质押 VVV 的钱包铸造 Bearer API 密钥。无需 Venice 账户;首次使用时会创建账户并将其与钱包关联。
1. GET /api_keys/generate_web3_key
curl https://api.venice.ai/api/v1/api_keys/generate_web3_key
返回 { "success": true, "data": { "token": "<JWT>" } }。令牌有效期为 15 分钟。
2. 签署令牌,然后调用 POST /api_keys/generate_web3_key
import { Wallet } from 'ethers'
const { data: { token } } = await fetch(`${base}/api_keys/generate_web3_key`).then(r => r.json())
const wallet = new Wallet(process.env.WALLET_KEY!)
const signature = await wallet.signMessage(token) // EIP-191 personal_sign of the exact JWT string
const res = await fetch(`${base}/api_keys/generate_web3_key`, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
apiKeyType: 'INFERENCE',
description: 'Web3 API Key',
address: wallet.address,
signature,
token,
consumptionLimit: { usd: 50 },
}),
})
const { data } = await res.json()
console.log(data.apiKey) // save this once
- 请求体:必须提供
address、signature、token和apiKeyType;description默认为"Web3 API Key";expiresAt、consumptionLimit、limitPeriod、modelPrivacy的用法与POST /api_keys相同。 - 签名会在 Base(链 8453)上验证。验证失败时返回
400,并附带具体消息:地址错误、令牌已过期或被修改、签名不匹配,或"Wallet … has no staked VVV on Base"。 - 响应格式与
POST /api_keys相同。返回的apiKey与普通 Bearer 密钥行为完全一致。已质押 VVV 仅用于限制密钥铸造:该密钥仍会消耗关联账户中的 DIEM、赚取的积分、捆绑积分或 USD。
示例
每位客户使用月度 USD 上限为 $5 的密钥,且仅限私有模型
await fetch(`${base}/api_keys`, {
method: 'POST',
headers: { Authorization: `Bearer ${ADMIN_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({
apiKeyType: 'INFERENCE',
description: `cust:${customerId}`,
consumptionLimit: { usd: 5 },
limitPeriod: 'MONTH',
modelPrivacy: 'PRIVATE_ONLY',
}),
})
客户流失时撤销密钥。
密钥健康检查
const { data } = await fetch(`${base}/api_keys/rate_limits`, {
headers: { Authorization: `Bearer ${key}` },
}).then(r => r.json())
if (!data.accessPermitted) alert('Key blocked — top up or raise its limit')
错误
| 代码 | 含义 |
|---|---|
400 | 请求体错误(缺少 apiKeyType、description 超过 64 个字符、expiresAt 格式错误、包含未知字段)、已达到 500 个有效密钥上限、密钥 ID 未知或已过期,或任何 Web3 验证失败。 |
401 | 密钥无效,或在仅限管理员的路由上使用了非 ADMIN 密钥("Admin API key required")。 |
402 | 缺少 Authorization 标头(x402 身份验证质询)。在推理时,如果密钥额度用尽,会返回 "API key USD spend limit exceeded…" / "API key DIEM spend limit exceeded…"。 |
403 | 推理时:密钥的 modelPrivacy 不允许使用该模型。 |
429 | 每分钟创建密钥次数超过 20 次,或超出通用 API 错误预算。 |
500 | 暂时性错误;请重试。 |
注意事项
- 密钥仅在创建响应中返回 一次。丢失后需删除并重新创建。
consumptionLimit按limitPeriod统计——默认是EPOCH(UTC 日),也可以选择MONTH或LIFETIME。它不是按调用次数计算的。- USD 上限涵盖 USD、捆绑积分和赚取的积分。
GET /api_keys/rate_limits可使用INFERENCE密钥;GET /api_keys/rate_limits/log则不行(仅限 ADMIN)。- 系统会强制执行
modelPrivacy:PRIVATE_ONLY密钥访问 Anonymous 模型时会收到403,且/models不会向该密钥显示这些模型。 vcu已弃用——请使用diem。- 创建时,
expiresAt: ""表示“不设过期时间”;更新时,""或null会移除已有的过期时间。 - 速率限制日志最多保存 50 条记录——调试突发流量时请频繁拉取。
- Web3 流程中的令牌会在 15 分钟后过期,且钱包必须在 Base 上持有已质押的 VVV。使用此流程时,请通过
GET /api_keys/{id}读取限制,而不要信任创建响应中回显的consumptionLimit——其diem根据vcu生成(因此,如果你只发送了diem,读回的值会是null),且usd为0时会回显为null。存储的限制是正确的。