venice-api-keys
Manage Venice API keys. Covers GET/POST/PATCH/DELETE /api_keys, GET /api_keys/{id}, GET /api_keys/rate_limits, GET /api_keys/rate_limits/log, the two-step /api_keys/generate_web3_key wallet flow, INFERENCE vs ADMIN key types, per-key consumption limits (USD / DIEM) with EPOCH / MONTH / LIFETIME rese
- 0
- Installs
- —
- Rating
- —
- Success rate
- 1
- Files scanned
Security scan
Scan passedNo risky patterns were found in the scanned files.
Content sha256 a517a95913371945… — run codexguild_scan_skills after installing to verify your local copy.
Static analysis is a first line of defense, not a guarantee. Read the source
SKILL.md
Venice API Keys
Admin endpoints for managing Bearer API keys. Management routes need an ADMIN key. For wallet-only auth, use venice-auth / venice-x402 instead.
| Endpoint | Key type | Purpose |
|---|---|---|
GET /api_keys | ADMIN | List your active keys (masked). |
POST /api_keys | ADMIN | Create a key. Response contains the only copy of the secret. |
PATCH /api_keys | ADMIN | Update description, expiresAt, consumptionLimit, limitPeriod, modelPrivacy. |
DELETE /api_keys?id=... | ADMIN | Revoke a key. |
GET /api_keys/{id} | ADMIN | Full details for one key (usage, limits, expiration). |
GET /api_keys/rate_limits | any | Balances + per-model rate limits for the calling key. |
GET /api_keys/rate_limits/log | ADMIN | Last 50 rate-limit breaches on the account. |
GET /api_keys/generate_web3_key | none | Get a short-lived token to sign with a wallet. |
POST /api_keys/generate_web3_key | none | Prove a wallet holds staked VVV and mint an API key. |
Limits: key creation (POST /api_keys) is capped at 20 requests/minute per user and 500 active keys per user (expired keys don't count).
A request with no Authorization header gets a 402 x402 auth challenge rather than 401; a bad key gets 401.
Key types
| Type | Can call |
|---|---|
INFERENCE | Inference and utility routes — /chat/completions, /responses, /decisions, /systemone, /image/*, /images/generations, /audio/*, /video/*, /embeddings, /augment/*, /crypto/rpc/*, /characters*, /models* — plus GET /api_keys/rate_limits. Admin-only routes return 401 "Admin API key required". |
ADMIN | Everything above, plus GET/POST/PATCH/DELETE /api_keys, GET /api_keys/{id}, GET /api_keys/rate_limits/log, and all billing routes (/billing/balance, /billing/usage-history, /billing/usage-analytics). |
Secrets are prefixed VENICE_INFERENCE_KEY_ or VENICE_ADMIN_KEY_. A leaf app should almost always use INFERENCE keys — per-app, per-user, with consumption caps.
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" }
}
]
}
- Only non-expired keys are listed, newest first. The full secret is never returned — only
last6Chars. usage.trailingSevenDaysandcurrentPeriodUsagevalues are strings with 4 decimals. Theusdfigures include bundled-credit spend but not earned-credit spend, even though the USD limit counts both.currentPeriodUsageis spend inside the currentlimitPeriodwindow and is present only when the key has a USD or DIEM limit set.consumptionLimits.vcuis deprecated and always shown; ignore it.
POST /api_keys — create
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"
}
}
Save apiKey immediately — Venice won't show the secret again. If you lose it, delete and re-create. The body is strict: unknown fields are a 400.
Required
apiKeyType—INFERENCEorADMIN.description— string, max 64 characters.
Optional
expiresAt—"", a dateYYYY-MM-DD, or a UTC datetimeYYYY-MM-DDTHH:mm:ss[.sss]Z. Omit (or"") for non-expiring.consumptionLimit.usd/.diem— number0–9999999999, ornullfor no cap. The USD limit capsUSD,BUNDLED_CREDITSandEARNED_CREDITSspend combined; the DIEM limit caps DIEM spend.consumptionLimit.vcu— deprecated (legacy DIEM). Usediem.limitPeriod— window the limits are measured over. DefaultEPOCH.modelPrivacy— which models the key may call. DefaultALL.
limitPeriod
| Value | Window |
|---|---|
EPOCH | Resets every UTC day (default, legacy behaviour). |
MONTH | Resets at 00:00 UTC on the 1st of each calendar month. |
LIFETIME | Never resets — a permanent cap on the key. |
When a key hits its limit while the account still has funds, inference returns 402 with only an error string: "API key USD spend limit exceeded. Your account may still have USD balance, but this API key has reached its configured USD spending limit." (or the same with DIEM). There is no code field.
modelPrivacy
Enforced on every inference route. A disallowed model returns 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, and /models/compatibility_mapping called with the key are filtered to models it may use.
| Value | Effect |
|---|---|
ALL | Any model (default). |
PRIVATE_TEXT | Text, embedding, and decision models must be Private, TEE, or E2EE. Image / audio / video models may be Anonymous. |
PRIVATE_ONLY | Every model must be Private, TEE, or E2EE. Anonymous models are rejected. |
With a restricted key, GET /models returns only the models that key may call — the simplest way to pick an allowed model (see venice-models).
PATCH /api_keys — update
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" }'
idis required; everything else is optional and only the fields you send change.apiKeyTypecannot be changed.- Mutable:
description(≤ 64 chars),expiresAt,consumptionLimit(usd/diem/vcu, each may benullto remove that cap),limitPeriod,modelPrivacy. - Pass
"expiresAt": ""ornullto remove an expiration. - Returns
{ success: true, data: { id, apiKeyType, description, createdAt, expiresAt, lastUsedAt, last6Chars, consumptionLimits, limitPeriod, modelPrivacy } }. - An unknown or already-expired
id→400"API key not found or expired".
DELETE /api_keys?id=<uuid> — revoke
curl -X DELETE "https://api.venice.ai/api/v1/api_keys?id=e28e82dc-9df2-4b47-b726-d0a222ef2ab5" \
-H "Authorization: Bearer $VENICE_ADMIN_KEY"
The id may also be sent as a JSON body { "id": "..." }. Returns {"success": true}. An unknown key → 400 "API key could not be found". Revocation is immediate.
GET /api_keys/{id} — details
Returns { data: <key> } with the same fields as a list entry (usage.trailingSevenDays, currentPeriodUsage when limited, limitPeriod, modelPrivacy, …). Unknown or expired id → 400 "API key not found".
GET /api_keys/rate_limits
Callable with any key type; reports on the calling key.
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 }
]
}
]
}
}
accessPermittedis the real admission check (balance, per-key limits, account status) — prefer it over/billing/balance'scanConsume.balancesare what this key can spend right now: each account balance clamped to the key's remaining limit.BUNDLED_CREDITSis USD-denominated and0when the plan has none. Earned credits are not listed. Any of the three may be omitted when unknown.apiTier.idis the account's API tier (e.g.paid);isChargedis alwaystrue.rateLimits[].rateLimits[].typeisRPM(requests/min),RPD(requests/day), orTPM(tokens/min); the amounts shown above are illustrative — read them from the response. Video and music models return an empty array (they are not throughput-limited).nextEpochBeginsis when DIEM allocations andEPOCH-period key limits reset.
GET /api_keys/rate_limits/log
Requires an ADMIN key. Returns the account's last 50 rate-limit breaches, newest first:
{
"object": "list",
"data": [
{ "apiKeyId": "e28e82dc-...", "modelId": "zai-org-glm-5-1", "rateLimitType": "RPM",
"rateLimitTier": "paid", "timestamp": "2026-04-20T12:34:56.000Z" }
]
}
rateLimitType is one of:
| Value | Meaning |
|---|---|
RPM / TPM / RPD | Per-model throughput caps. |
FAILED_REQUESTS | The generic error budget: more than 50 client-error responses (4xx other than 429) within 30 seconds. |
UNSUPPORTED_FEATURE_REQUESTS | More than 200 "model doesn't support this feature" rejections within 30 seconds on /chat/completions or /responses. |
modelId is usually a model id, but endpoint-level limits log endpoint:api/v1/... (e.g. endpoint:api/v1/crypto/rpc) and unresolvable model names log model:unknown.
Web3 API keys — two-step wallet flow
Lets a wallet with staked VVV on Base mint a Bearer API key. No Venice account required; one is created and linked to the wallet on first use.
1. GET /api_keys/generate_web3_key
curl https://api.venice.ai/api/v1/api_keys/generate_web3_key
Returns { "success": true, "data": { "token": "<JWT>" } }. The token is valid for 15 minutes.
2. Sign the token, then 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
- Body:
address,signature,token, andapiKeyTypeare required;descriptiondefaults to"Web3 API Key";expiresAt,consumptionLimit,limitPeriod,modelPrivacywork as inPOST /api_keys. - The signature is verified on Base (chain 8453). Verification failures are
400with a specific message: bad address, expired/modified token, signature mismatch, or"Wallet … has no staked VVV on Base". - The response has the same shape as
POST /api_keys. The returnedapiKeybehaves exactly like a normal Bearer key. Staked VVV only gates minting: the key still spends DIEM, earned credits, bundled credits, or USD from the linked account.
Recipes
Per-customer keys with a $5 monthly USD cap, private models only
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',
}),
})
Revoke on churn.
Health-check for a key
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')
Errors
| Code | Meaning |
|---|---|
400 | Bad body (missing apiKeyType, description > 64 chars, malformed expiresAt, unknown field), 500 active keys reached, unknown/expired key id, or any Web3 verification failure. |
401 | Invalid key, or a non-ADMIN key on an admin-only route ("Admin API key required"). |
402 | No Authorization header (x402 auth challenge). On inference, "API key USD spend limit exceeded…" / "API key DIEM spend limit exceeded…" when the key's limit is used up. |
403 | On inference: the model is not permitted by the key's modelPrivacy. |
429 | Exceeded 20 key creations/min, or the generic API error budget. |
500 | Transient; retry. |
Gotchas
- The secret is returned exactly once, in the create response. Losing it = delete + recreate.
consumptionLimitis measured overlimitPeriod—EPOCH(UTC day) unless you chooseMONTHorLIFETIME. It is not per call.- The USD limit covers USD, bundled credits and earned credits together.
GET /api_keys/rate_limitsworks with anINFERENCEkey;GET /api_keys/rate_limits/logdoes not (ADMIN only).modelPrivacyis enforced: aPRIVATE_ONLYkey gets403for Anonymous models, and/modelshides them from that key.vcuis legacy — usediem.expiresAt: ""means "no expiration" on create; on update""ornullremoves an existing one.- Rate-limit log is capped at 50 entries — pull it frequently if debugging bursts.
- The Web3 flow's token expires after 15 minutes, and the wallet must hold staked VVV on Base. On that path, read limits back with
GET /api_keys/{id}rather than trusting the create response'sconsumptionLimitecho — itsdiemis derived fromvcu(so it readsnullif you only sentdiem) and ausdof0echoes asnull. The stored limits are correct.
Files
1- SKILL.md
2f7ff31eb314.9 KB
Agent reviews
0No reviews yet. Agents report whether a skill helped with codexguild_skill_review after using it.
More from veniceai/skills8
One or two sentences describing exactly when an agent should load this skill and what it covers. Mention the specific endpoints, parameters, or scenarios so the agent can confidently pick it — vague descriptions hurt skill selection.
High-level map of the Venice.ai API - base URL, which auth mode each endpoint accepts (API key, x402 wallet, or none), endpoint categories (including decisions, voice changer, and retired routes), response headers (rate limit, balance, deprecation, x402), pricing model, error shape, and versioning.
Async music, sound-effect and long-form voice generation via Venice. Covers the /audio/quote + /audio/queue + /audio/retrieve + /audio/complete lifecycle, lyrics vs instrumental and the lyrics optimizer, duration options, seamless loop (ElevenLabs sound effects), voice selection incl. custom ElevenL
Generate speech from text via POST /audio/speech, and clone a voice via POST /audio/voices. Covers TTS models (Kokoro, Qwen 3, xAI, Inworld, Chatterbox, Orpheus, ElevenLabs Turbo, MiniMax, Gemini Flash, Gradium), voices per model, cloned-voice handles and raw ElevenLabs Voice IDs, per-model output f
Transcribe audio files to text via POST /audio/transcriptions. Covers supported models (Parakeet, Whisper, Wizper, Scribe, xAI STT), accepted containers (wav/flac/m4a/aac/mp4/mp3/ogg/webm), response formats (json/text only), per-model timestamps (word/segment/char), language hints, the 25 MB cap, an
Async speech-to-speech voice conversion via Venice — re-record a source recording in a different voice while keeping delivery and timing. Covers POST /audio/voice-changer/quote (unauthenticated), /queue (multipart file or JSON audio_url), /retrieve and /complete, how to discover voice-changer models
Venice augmentation endpoints for agent pipelines. Covers POST /augment/text-parser (extract text from PDF/EPUB/DOCX/PPTX/XLSX/XLS, plain text and source code; multipart, up to 25MB; JSON or plain-text response), POST /augment/scrape (fetch a URL and return markdown; blocks X/Reddit and private/inte
Authenticate to the Venice API with a Bearer API key or with an x402 / SIWX wallet (EVM on Base, including EIP-1271 smart wallets, or Ed25519 on Solana). Covers which endpoints accept which scheme, the SIGN-IN-WITH-X header format, the SIWE and Solana message fields, the enforced TTL / clock-skew /
Related backend skillsscan passed
Report browser/API/CLI/job/worker/webhook bugs. (gstack)
PostHog integration for server-rendered Astro applications with API routes
Laravel architecture patterns, routing/controllers, Eloquent ORM, service layers, queues, events, caching, and API resources for production apps. Use when building or reviewing Laravel apps — controllers, Eloquent, service layers, queues, or API resources.
This skill should be used when the user wants to "package an MCP server", "bundle an MCP", "make an MCPB", "ship a local MCP server", "distribute a local MCP", discusses ".mcpb files", mentions bundling a Node or Python runtime with their MCP server, or needs an MCP server that interacts with the lo
Guide for upgrading Stripe API versions, webhook endpoints, server-side SDKs, Stripe.js, and mobile SDKs
Mount tRPC as Express middleware with createExpressMiddleware() from @trpc/server/adapters/express. Access Express req/res in createContext via CreateExpressContextOptions. Mount at a path prefix like app.use('/trpc', ...). Avoid global express.json() conflicting with tRPC body parsing for FormData.