Venice AI runs an OpenAI-compatible inference API in front of open-weight and third-party models, with privacy handled at the proxy layer instead of bolted on afterward. This lab gets you a working API key, a first chat completion in curl and Python, the Venice-only venice_parameters options, image generation, and two ways to call it from n8n.

Get an API key

Sign in at venice.ai, open Settings → API (venice.ai/settings/api), then Generate New API Key. Pick Inference Only for normal model calls; Admin is only for keys that manage other keys. Venice shows the full key once — copy it with the dialog’s copy button, then store it as an environment variable:

export VENICE_API_KEY=your-api-key-here

GET /models works with or without a key, so it proves nothing. Verify with GET /api_keys/rate_limits instead:

curl --request GET \
  --url https://api.venice.ai/api/v1/api_keys/rate_limits \
  --header "Authorization: Bearer $VENICE_API_KEY"

A working key returns your tier, balances, and data.accessPermitted. A 401 with AUTHENTICATION_FAILED usually means a partial copy, a stray Bearer prefix baked into the stored value, or a trailing space.

Your first request

The base URL is the detail that trips up first attempts: https://api.venice.ai/api/v1, not the bare venice.ai domain.

curl https://api.venice.ai/api/v1/chat/completions \
  -H "Authorization: Bearer $VENICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "venice-uncensored-1-2",
    "messages": [{"role": "user", "content": "Hello!"}]
  }'

Because the endpoint implements the OpenAI chat completions spec, the standard OpenAI SDK works unchanged once it points at Venice:

import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ.get("VENICE_API_KEY"),
    base_url="https://api.venice.ai/api/v1",
)

completion = client.chat.completions.create(
    model="zai-org-glm-5",
    messages=[{"role": "user", "content": "Why is privacy important?"}],
)
print(completion.choices[0].message.content)

Venice’s migration guide frames existing OpenAI code as a two-variable change: keep OPENAI_API_KEY and OPENAI_BASE_URL (some libraries still read OPENAI_API_BASE) and point them at your Venice key and https://api.venice.ai/api/v1. Any tool that already reads those two variables picks up Venice with no code change.

Pick a model without hardcoding an ID

GET /models?type=text lists text models with context length and a model_spec object; omit type for text only, or pass type=all for every modality. Entries scheduled for retirement carry a deprecation object.

Instead of a raw model ID, you can send a trait name as model. GET /models/traits?type=text returns the current mapping, for example default → zai-org-glm-5-2, default_reasoning → kimi-k3, default_code → deepseek-v4-pro-0813. Sending "model": "default" resolves to whichever model currently holds that trait — a smaller blast radius than a pinned ID when Venice deprecates it.

Venice-specific parameters

The chat completions endpoint accepts a standard OpenAI body plus one extra object, venice_parameters, for behavior outside the OpenAI spec. With the official SDKs it travels through extra_body:

response = client.chat.completions.create(
    model="zai-org-glm-5",
    messages=[{"role": "user", "content": "Latest developments in AI?"}],
    extra_body={
        "venice_parameters": {
            "enable_web_search": "auto",
            "enable_web_citations": True,
        }
    },
)

Documented keys worth knowing:

Parameter Type Default What it does
enable_web_search string off off, on, or auto. Adds usage-based cost per the pricing page.
enable_web_citations boolean false Asks the model to cite sources with caret superscripts (^1^).
enable_web_scraping boolean false Scrapes up to 5 URLs in the user message; replaces search for that request.
enable_x_search boolean false Uses xAI’s native web + X search for supported Grok models.
character_slug string — Loads a public Venice character persona by its “Public ID”.
include_venice_system_prompt boolean true Whether Venice’s default system prompt is appended alongside yours.
disable_thinking boolean false On supported reasoning models, skips thinking and strips <think> blocks.
strip_thinking_response boolean false Removes legacy <think> blocks from the response text only.

Unknown keys inside venice_parameters are ignored, not rejected — a misspelled key returns a normal 200 with the feature simply not applied. Writing the system prompt that goes alongside Venice’s own uses the same general technique as the ChatGPT prompting cheat sheet.

By default your system message is appended to Venice’s default prompts, documented as tuned for uncensored responses. Set "venice_parameters": {"include_venice_system_prompt": false} in the same request body to use only your own system message, nothing from Venice.

Model feature suffix. When a client only lets you choose a model string, append parameters to the model ID instead: "model": "default:enable_web_search=auto&include_venice_system_prompt=false". Same feature, string form, chained with &.

Streaming

Set stream: true for server-sent events, ending in data: [DONE]. stream_options.include_usage adds a final usage chunk:

curl 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",
    "messages": [{"role": "user", "content": "One sentence about Venice."}],
    "stream": true,
    "stream_options": {"include_usage": true}
  }'

If you also set venice_parameters.include_search_results_in_stream, documented as experimental, search results arrive as the first emitted chunk instead of inline with normal content.

Image generation

Image generation is synchronous: one request, one response with the image inline. POST /image/generate is the native API with full parameters; POST /images/generations is an OpenAI-compatible alias for migrating existing OpenAI image code. List image models first with GET /models?type=image to find a valid model id.

curl -X POST https://api.venice.ai/api/v1/image/generate \
  -H "Authorization: Bearer $VENICE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "venice-sd35",
    "prompt": "A cinematic photo of a gondola on a canal at blue hour",
    "negative_prompt": "blurry, low quality, watermark",
    "width": 1024,
    "height": 1024,
    "format": "webp"
  }'

Documented fields include prompt (required), width/height for pixel-based models, aspect_ratio/resolution for ratio-based models (qwen-image-2, gpt-image-2, nano-banana-2), format (jpeg/png/webp), variants (1–4), return_binary, safe_mode, seed, and style_preset. Model families disagree on sizing: the Qwen Image family rejects width/height with a 400 telling you to use aspect_ratio instead. Check model_spec.constraints from the models list first.

Rate limits

Default per-tier numbers are documented as a reference, but Venice says to treat your own key’s endpoint as authoritative:

curl https://api.venice.ai/api/v1/api_keys/rate_limits \
  -H "Authorization: Bearer $VENICE_API_KEY"

Text and embedding models sit in four published size tiers with different requests/tokens-per-minute caps; image, upscale, inpaint, speech, and transcription models have their own separate caps. On a 429, x-ratelimit-reset-requests gives a Unix timestamp (milliseconds) for when the window clears. Two further budgets apply regardless of tier: more than 50 failed requests, or more than 200 requests for an unsupported model feature, in any 30-second window.

Data handling and deprecation, as documented

Venice’s privacy page describes the proxy relaying requests over TLS without storing prompt or response content for normal inference. Each model then adds one of four privacy modes: Anonymous (identity withheld from the provider, content still visible to it), Private (contract-enforced zero retention), TEE (hardware-isolated with remote attestation), or E2EE (encrypted to a verified enclave before it leaves your client). Venice also documents that it may process operational metadata separately — timestamps, token counts, billing, IP address — for auth, billing, and abuse prevention. “We don’t retain prompt text” and “we log nothing at all” are different claims; check the privacy mode of the model you call.

On deprecation, Venice documents 7–15 days’ notice, a deprecation warning in API responses during that window, and automatic routing to a comparable replacement after sunset, or 410 Gone when routing isn’t possible. A model reached through a trait like default_code gets its trait reassigned automatically.

Wire it into n8n

n8n’s built-in OpenAI credential has a Base URL field (default https://api.openai.com/v1) alongside API Key. That one credential type backs the OpenAI node, the OpenAI Chat Model sub-node used by AI Agent, Embeddings OpenAI, and LM OpenAI.

  1. Credentials → Add Credential → OpenAI.
  2. API Key: your Venice key. Organization ID: leave blank.
  3. Base URL: https://api.venice.ai/api/v1.
  4. Save — n8n tests the credential against /models on that base URL.

Add an OpenAI Chat Model node and attach that credential. Its model picker calls GET /models against the configured base URL, so Venice model IDs load once the credential points at Venice. A per-node Options → Base URL override exists too, taking priority over the credential, if one workflow needs a different endpoint. Pair the Chat Model node with an AI Agent node and a tool as covered in the first n8n workflow lab; tool-calling concepts in general are in what is agentic AI, and wiring an MCP server as a tool is in MCP servers explained.

For anything the chat-model node doesn’t cover — image generation, a raw streaming call — use the HTTP Request node. Set Authentication → Generic Credential Type, then Generic Auth Type → Bearer Auth, and paste only the token (no Bearer prefix); n8n builds the Authorization: Bearer <token> header. Point URL at https://api.venice.ai/api/v1/image/generate, method POST:

{
  "model": "venice-sd35",
  "prompt": "A dark server room with a single glowing rack",
  "width": 1024,
  "height": 1024,
  "format": "webp"
}

For curl import, retries, and general HTTP Request node behavior, see the first n8n workflow lab; for choosing n8n over a SaaS automation tool in the first place, see n8n vs Make vs Zapier.

Pitfalls

Keys in exported workflow JSON. n8n stores credential names and IDs in exported JSON, not the secret value. But an HTTP Request node built from a pasted curl command can embed an Authorization: Bearer sk-... header directly in node parameters. Read exported JSON before sharing it, and prefer Generic Credential Type / Bearer Auth so the secret lives in a credential, not in parameters.

Hardcoding a model ID that gets deprecated. A pinned ID can return 410 Gone after the notice window if Venice can’t auto-route it. Watch the deprecation field on GET /models, or call a trait like default so Venice’s alias resolution absorbs the change.

venice.ai instead of api.venice.ai. The bare domain returns the web app’s HTML or a 404 for API calls, not a JSON error — easy to mistake for a bad key when it’s actually the wrong host.

Assuming “private” means no logging of anything. Venice separates prompt/response content (not retained for normal inference) from operational metadata it says it may still process. The privacy mode is the lever for content; it isn’t a claim of zero metadata.

Silent typos in venice_parameters. Unknown keys are ignored, not rejected. A misspelled enabled_web_search returns 200 with search simply not applied — verify the behavior changed, not just the status code.

FAQ

What base URL do I use for the Venice AI API?

https://api.venice.ai/api/v1, not venice.ai. The venice.ai domain serves the web app, so requests there return an HTML page or a 404. Point your OpenAI SDK’s base_url/baseURL at the api subdomain, keep the /api/v1 suffix, and send your key as a Bearer token.

Can I use the OpenAI SDK with Venice AI, or do I need a separate client?

You use the same OpenAI SDK. Create the client with your Venice API key and the Venice base URL instead of OpenAI’s. Chat completions, streaming, and tool calls work the same way; Venice-only options travel through the SDK’s extra_body parameter as a venice_parameters object.

What do venice_parameters actually control?

Venice-only behavior outside the OpenAI spec: built-in web search (enable_web_search), source citations, URL scraping, Venice character personas (character_slug), reasoning-model thinking blocks, and whether Venice’s default system prompt is appended to yours (include_venice_system_prompt). Unknown keys inside the object are silently ignored, so a typo fails quietly rather than with an error.

Does Venice AI keep my prompts?

Per Venice’s documentation, the proxy relays requests over TLS without storing prompt or response content for normal inference, and each model adds one of four privacy modes: Anonymous, Private (contract-enforced zero retention), TEE (hardware-isolated), or E2EE (encrypted to a verified enclave). Venice says it may still keep operational metadata, like timestamps, token counts, and billing data, separate from the content itself.

Can I wire Venice AI into n8n as a chat model?

Yes. Create an OpenAI credential in n8n, paste your Venice key into API Key, and set Base URL to https://api.venice.ai/api/v1. That credential is shared by the OpenAI node, the OpenAI Chat Model sub-node, Embeddings OpenAI, and LM OpenAI. For raw calls or image generation, use the HTTP Request node with Generic Credential Type → Bearer Auth instead.

How this guide was verified

Written by hand from the official documentation, every command re-checked, and reviewed a second time before publishing. Last reviewed on .

Official sources read for this article

Share.

Haythem Rehouma builds and teaches DevOps and AI tooling: Kubernetes, Docker, Terraform, Claude Code, ChatGPT and n8n. Every KubPoint guide is written from the official docs and re-tested before it goes live.

Comments are closed.