Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Authenticate to the Venice API with a Bearer API key or with an x402 / SIWE wallet. Covers header formats, the SIWE message fields, TTL and nonce rules, the venice-x402-client SDK, and how to choose between the two modes.
.claude/skills/sediman-agent-venice-auth/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-01 | ✗→✓ | ▲ Improved | 57% | 0% |
| case-02 | ✗→✓ | ▲ Improved | 51% | 0% |
| case-03 | ✗→✓ | ▲ Improved | 100% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 127% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 18% | 0% |
Every Venice endpoint accepts one of two auth schemes, declared in the OpenAPI spec as BearerAuth and siwx. Both are first-class — pick whichever fits the deployment.
api.venice.ai.401 Authentication failed and need to check header format.httpAuthorization: Bearer <VENICE_API_KEY>
venice-api-keys.consumptionLimits (USD and/or DIEM caps) and apiKeyType (ADMIN or INFERENCE).ADMIN keys can manage other keys.bashcurl https://api.venice.ai/api/v1/chat/completions \ -H "Authorization: Bearer $VENICE_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "model": "zai-org-glm-5-1", "messages": [{"role":"user","content":"hello"}] }'
Use the Bearer scheme when you have a Venice account, want usage analytics (/billing/usage-analytics), want to issue scoped child keys, or need DIEM / bundled credit priority.
Authenticate with an Ethereum wallet. No account needed. Pay per request in USDC on Base (chain ID 8453). Balance lives under your wallet address and is consumed automatically.
httpX-Sign-In-With-X: <base64(json)>
Where the decoded JSON is:
json{ "address": "0x... (checksummed)", "message": "<SIWE message string from SiweMessage.prepareMessage()>", "signature": "0x... (hex)", "timestamp": 1712659200000, "chainId": 8453 }
| Field | Value | |---|---| | domain | One of the allow-listed Venice domains: venice.ai, api.venice.ai, outerface.venice.ai, preview.venice.ai, staging.venice.ai (plus localhost in dev). The server's own generated challenge uses api.venice.ai. | | uri | Matching https://<domain> URL. | | version | "1" | | address | the wallet's checksummed address | | statement | "Sign in to Venice AI" (what the server's generated challenge uses — any string is accepted, this one keeps consent UX consistent). | | nonce | random 16-char hex, single-use per wallet | | issuedAt / expirationTime | ISO-8601. Server enforces a hard 5-minute window from issuedAt (expirationTime is informational only). | | chainId | 8453 — accepted as number (8453), numeric string ("8453"), or CAIP-2 ("eip155:8453"). |
The header is short-lived — generate a fresh one at most every ~4 minutes (server accepts up to 5 min from issuedAt). The payload timestamp must be within 30 seconds of the SIWE issuedAt, and issuedAt itself must not be more than 30 seconds ahead of server time. Nonces are single-use per wallet — reuse within ~5.5 minutes is rejected with X402_SIGN_IN_NONCE_REUSED.
Domain is validated against the allow-list above — not against the incoming request's Host header. Passing any allow-listed domain (e.g. api.venice.ai) is fine regardless of which Venice host you hit.
tsimport { Wallet } from 'ethers' import { SiweMessage } from 'siwe' const wallet = new Wallet(process.env.WALLET_KEY!) function makeSiwxHeader() { const msg = new SiweMessage({ domain: 'api.venice.ai', address: wallet.address, statement: 'Sign in to Venice AI', uri: 'https://api.venice.ai', version: '1', chainId: 8453, nonce: crypto.randomUUID().replace(/-/g, '').slice(0, 16), issuedAt: new Date().toISOString(), expirationTime: new Date(Date.now() + 4 * 60_000).toISOString(), }) const message = msg.prepareMessage() const signature = wallet.signMessageSync(message) return btoa(JSON.stringify({ address: wallet.address, message, signature, timestamp: Date.now(), chainId: 8453, })) } const res = await fetch('https://api.venice.ai/api/v1/chat/completions', { method: 'POST', headers: { 'Content-Type': 'application/json', 'X-Sign-In-With-X': makeSiwxHeader(), }, body: JSON.stringify({ model: 'zai-org-glm-5-1', messages: [{ role: 'user', content: 'hello' }], }), })
bashnpm install venice-x402-client
tsimport { VeniceClient } from 'venice-x402-client' const venice = new VeniceClient(process.env.WALLET_KEY!) await venice.topUp(10) // $10 USDC on Base (first time only) const res = await venice.chat({ model: 'zai-org-glm-5-1', messages: [{ role: 'user', content: 'Hello!' }], }) console.log(res.choices[0].message.content)
VeniceClient and createAuthFetch handle SIWE signing, header rotation, and 402 top-up prompts automatically.
POST /x402/top-up # WITHOUT X-402-Payment header → returns payment requirements
→ sign a USDC transfer authorization with the x402 SDK (createPaymentHeader)
POST /x402/top-up # WITH X-402-Payment header → credits land on your wallet addressSee venice-x402 for the full flow.
| Need | Pick | |---|---| | Server-side dashboard with usage analytics | Bearer | | Scoped child keys, consumption limits per app | Bearer | | DIEM-staked users / bundled credits | Bearer | | Serverless function that pays per call | x402 | | Agents with an on-chain budget, no account | x402 | | End-user wallets authing directly (browser extension, mobile wallet) | x402 | | Team sharing — one seed, many consumers | Bearer (+ child keys) |
Both schemes can co-exist: a Pro user may generate a Web3 API key via POST /api_keys/generate_web3_key that ties an on-chain wallet to an off-chain key with an EIP-191 signature. See venice-api-keys.
| Status | Likely cause | |---|---| | 401 Authentication failed | bad/expired key, SIWE older than 5 min from issuedAt, payload.timestamp off by >30s, domain not in the Venice allow-list, unsupported chain id, nonce replayed. The server returns a specific code like X402_SIGN_IN_EXPIRED, X402_SIGN_IN_TIMESTAMP_MISMATCH, X402_SIGN_IN_DOMAIN_MISMATCH, X402_SIGN_IN_NONCE_REUSED, or X402_SIGN_IN_INVALID_CHAIN_ID (code always set; message may fall back to generic text for some codes). | | 402 x402 (no header) | X-Sign-In-With-X is missing on an SIWE-gated route (/x402/balance, /x402/transactions). Add the header. | | 401 This model is only available to Pro users | using x402 or an INFERENCE key on a gated model — switch to a Pro Bearer key | | 402 PAYMENT_REQUIRED (x402) | wallet balance too low; read topUpInstructions and top up via /x402/top-up | | 402 INSUFFICIENT_BALANCE (Bearer) | DIEM + USD + bundled credits are all empty; top up at venice.ai |
consumptionLimits.issuedAt; rotate every ~4 minutes. Never reuse a signed X-Sign-In-With-X header across hours or across machines. Nonces are tracked per wallet for ~5.5 min; replaying one is rejected with X402_SIGN_IN_NONCE_REUSED.venice-api-keys and venice-errors.| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-01 | fail→pass | 15,464 | 10,964 | -29% | 1 | 1 | 0% | 3,076 | 4,823 | +57% | 0 | 0 | — |
case-02 | fail→pass | 22,130 | 13,158 | -41% | 1 | 1 | 0% | 3,042 | 4,593 | +51% | 0 | 0 | — |
case-03 | fail→pass | 16,753 | 14,497 | -13% | 1 | 1 | 0% | 2,650 | 5,307 | +100% | 0 | 0 | — |
case-04 | pass→pass | 7,065 | 3,396 | -52% | 1 | 1 | 0% | 1,194 | 3,070 | +157% | 0 | 0 | — |
case-05 | pass→pass | 6,302 | 1,620 | -74% | 1 | 1 | 0% | 811 | 2,679 | +230% | 0 | 0 | — |
case-06 | fail→pass | 8,011 | 2,942 | -63% | 1 | 1 | 0% | 1,285 | 2,923 | +127% | 0 | 0 | — |
case-07 | pass→pass | 12,702 | 2,899 | -77% | 1 | 1 | 0% | 2,012 | 2,938 | +46% | 0 | 0 | — |
case-08 | pass→pass | 10,301 | 3,259 | -68% | 1 | 1 | 0% | 1,517 | 2,967 | +96% | 0 | 0 | — |
case-09 | fail→pass | 15,435 | 2,183 | -86% | 1 | 1 | 0% | 2,350 | 2,783 | +18% | 0 | 0 | — |
case-10 | fail→pass | 13,432 | 1,787 | -87% | 1 | 1 | 0% | 2,169 | 2,731 | +26% | 0 | 0 | — |
case-11 | fail→pass | 11,809 | 2,747 | -77% | 1 | 1 | 0% | 1,996 | 2,914 | +46% | 0 | 0 | — |
case-12 | pass→pass | 10,137 | 2,153 | -79% | 1 | 1 | 0% | 1,554 | 2,832 | +82% | 0 | 0 | — |
case-13 | fail→pass | 13,591 | 2,551 | -81% | 1 | 1 | 0% | 2,171 | 2,839 | +31% | 0 | 0 | — |
case-14 | fail→pass | 8,771 | 1,897 | -78% | 1 | 1 | 0% | 1,215 | 2,724 | +124% | 0 | 0 | — |
case-15 | pass→pass | 12,782 | 8,327 | -35% | 1 | 1 | 0% | 1,986 | 3,884 | +96% | 0 | 0 | — |
case-16 | pass→pass | 10,558 | 1,726 | -84% | 1 | 1 | 0% | 1,729 | 2,693 | +56% | 0 | 0 | — |
case-17 | fail→pass | 12,778 | 2,524 | -80% | 1 | 1 | 0% | 2,012 | 2,892 | +44% | 0 | 0 | — |
case-18 | pass→pass | 9,062 | 1,881 | -79% | 1 | 1 | 0% | 1,437 | 2,741 | +91% | 0 | 0 | — |
case-19 | pass→pass | 15,064 | 1,788 | -88% | 1 | 1 | 0% | 2,355 | 2,736 | +16% | 0 | 0 | — |
case-20 | pass→pass | 6,890 | 4,534 | -34% | 1 | 1 | 0% | 1,168 | 3,329 | +185% | 0 | 0 | — |
case-21 | pass→pass | 12,089 | 10,951 | -9% | 1 | 1 | 0% | 2,008 | 4,390 | +119% | 0 | 0 | — |
case-22 | pass→pass | 20,407 | 14,151 | -31% | 1 | 1 | 0% | 3,689 | 4,969 | +35% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted. The headline lift of +45 percentage points is the difference between those two pass rates over the 22 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.