Documentation Index Fetch the complete documentation index at: https://veniceai-experiment-guides-top-level-tab.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
The Vercel AI SDK is the most popular way to build AI features in Next.js, React, Svelte, and Vue apps. Venice works out of the box as an OpenAI-compatible provider.
Setup
npm install ai @ai-sdk/openai
Provider Configuration
Create a Venice provider using the OpenAI-compatible adapter:
// lib/venice.ts
import { createOpenAI } from '@ai-sdk/openai' ;
const openai = createOpenAI ({
apiKey: process . env . VENICE_API_KEY ! ,
baseURL: 'https://api.venice.ai/api/v1' ,
});
// Use .chat() to ensure compatibility with Venice's chat completions endpoint
export const venice = ( modelId : string ) => openai . chat ( modelId );
Using .chat() ensures requests go to Venice’s /chat/completions endpoint. The default openai('model') syntax may use newer OpenAI endpoints that Venice doesn’t support yet.
Streaming Chat (Next.js App Router)
API Route
// app/api/chat/route.ts
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
export async function POST ( req : Request ) {
const { messages } = await req . json ();
const result = streamText ({
model: venice ( 'venice-uncensored' ),
system: 'You are a helpful, privacy-respecting AI assistant.' ,
messages ,
});
return result . toDataStreamResponse ();
}
React Component
// app/page.tsx
'use client' ;
import { useChat } from '@ai-sdk/react' ;
export default function Chat () {
const { messages , input , handleInputChange , handleSubmit , isLoading } = useChat ();
return (
< div className = "max-w-2xl mx-auto p-4" >
< div className = "space-y-4 mb-4" >
{ messages . map (( m ) => (
< div key = { m . id } className = { m . role === 'user' ? 'text-right' : 'text-left' } >
< span className = "font-bold" > { m . role === 'user' ? 'You' : 'Venice' } : </ span >
< p className = "whitespace-pre-wrap" > { m . content } </ p >
</ div >
)) }
</ div >
< form onSubmit = { handleSubmit } className = "flex gap-2" >
< input
value = { input }
onChange = { handleInputChange }
placeholder = "Ask anything..."
className = "flex-1 border rounded px-3 py-2"
disabled = { isLoading }
/>
< button type = "submit" disabled = { isLoading } className = "bg-red-600 text-white px-4 py-2 rounded" >
Send
</ button >
</ form >
</ div >
);
}
Generating Text (Non-Streaming)
import { generateText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const { text } = await generateText ({
model: venice ( 'zai-org-glm-4.7' ),
prompt: 'Explain zero-knowledge proofs in simple terms.' ,
});
console . log ( text );
Structured Output
import { generateObject } from 'ai' ;
import { venice } from '@/lib/venice' ;
import { z } from 'zod' ;
const { object } = await generateObject ({
model: venice ( 'venice-uncensored' ),
schema: z . object ({
recipe: z . object ({
name: z . string (),
ingredients: z . array ( z . string ()),
steps: z . array ( z . string ()),
prepTimeMinutes: z . number (),
}),
}),
prompt: 'Generate a recipe for chocolate chip cookies.' ,
});
console . log ( object . recipe . name );
console . log ( `Prep time: ${ object . recipe . prepTimeMinutes } minutes` );
import { streamText , tool } from 'ai' ;
import { venice } from '@/lib/venice' ;
import { z } from 'zod' ;
const result = streamText ({
model: venice ( 'zai-org-glm-4.7' ),
messages: [{ role: 'user' , content: 'What is the weather in Tokyo?' }],
tools: {
getWeather: tool ({
description: 'Get current weather for a location' ,
parameters: z . object ({
location: z . string (). describe ( 'City name' ),
}),
execute : async ({ location }) => {
// Your weather API call here
return { temperature: 22 , condition: 'Sunny' , location };
},
}),
},
});
for await ( const part of result . fullStream ) {
if ( part . type === 'text-delta' ) {
process . stdout . write ( part . textDelta );
} else if ( part . type === 'tool-result' ) {
console . log ( 'Tool result:' , part . result );
}
}
Image Generation
Venice image generation can be called directly alongside the AI SDK:
// app/api/image/route.ts
export async function POST ( req : Request ) {
const { prompt } = await req . json ();
const response = await fetch ( 'https://api.venice.ai/api/v1/image/generate' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ process . env . VENICE_API_KEY } ` ,
'Content-Type' : 'application/json' ,
},
body: JSON . stringify ({
model: 'qwen-image' ,
prompt ,
width: 1024 ,
height: 1024 ,
}),
});
const data = await response . json ();
return Response . json ({ image: data . images [ 0 ] });
}
Multi-Model Chat (Model Selector)
Let users choose between Venice models:
// app/api/chat/route.ts
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const ALLOWED_MODELS = [
'venice-uncensored' ,
'zai-org-glm-4.7' ,
'qwen3-vl-235b-a22b' ,
'qwen3-4b' ,
];
export async function POST ( req : Request ) {
const { messages , model : modelId } = await req . json ();
if ( ! ALLOWED_MODELS . includes ( modelId )) {
return new Response ( 'Invalid model' , { status: 400 });
}
const result = streamText ({
model: venice ( modelId ),
messages ,
});
return result . toDataStreamResponse ();
}
// Client component with model selector
'use client' ;
import { useChat } from '@ai-sdk/react' ;
import { useState } from 'react' ;
const MODELS = [
{ id: 'venice-uncensored' , name: 'Venice Uncensored' , desc: 'Fast & uncensored' },
{ id: 'zai-org-glm-4.7' , name: 'GLM 4.7' , desc: 'Most intelligent (private)' },
{ id: 'qwen3-vl-235b-a22b' , name: 'Qwen Vision' , desc: 'Advanced vision + text' },
{ id: 'qwen3-4b' , name: 'Venice Small' , desc: 'Fastest & cheapest' },
];
export default function Chat () {
const [ model , setModel ] = useState ( 'venice-uncensored' );
const { messages , input , handleInputChange , handleSubmit } = useChat ({
body: { model },
});
return (
< div >
< select value = { model } onChange = { ( e ) => setModel ( e . target . value ) } >
{ MODELS . map (( m ) => (
< option key = { m . id } value = { m . id } > { m . name } — { m . desc } </ option >
)) }
</ select >
{ /* ... chat UI ... */ }
</ div >
);
}
Web Search Integration
Pass Venice parameters for web search:
import { streamText } from 'ai' ;
import { venice } from '@/lib/venice' ;
const result = streamText ({
model: venice ( 'venice-uncensored' ),
messages: [{ role: 'user' , content: 'What happened in AI news today?' }],
// Venice-specific parameters
experimental_providerMetadata: {
venice_parameters: {
enable_web_search: 'auto' ,
},
},
});
If experimental_providerMetadata doesn’t pass through, you can use a custom fetch wrapper or call the Venice API directly for web search features.
Embeddings
For embeddings, use textEmbeddingModel() on the provider directly:
import { embed , embedMany } from 'ai' ;
import { createOpenAI } from '@ai-sdk/openai' ;
const openai = createOpenAI ({
apiKey: process . env . VENICE_API_KEY ! ,
baseURL: 'https://api.venice.ai/api/v1' ,
});
// Single embedding
const { embedding } = await embed ({
model: openai . textEmbeddingModel ( 'text-embedding-bge-m3' ),
value: 'Privacy-first AI infrastructure' ,
});
// Batch embeddings
const { embeddings } = await embedMany ({
model: openai . textEmbeddingModel ( 'text-embedding-bge-m3' ),
values: [
'Venice AI provides private inference.' ,
'Zero data retention guaranteed.' ,
'OpenAI SDK compatible.' ,
],
});
Environment Variables
# .env.local
VENICE_API_KEY = your-venice-api-key
Recommended Models
Use Case Model Why Chat apps venice-uncensoredFast, cheap, no filtering Complex tasks zai-org-glm-4.7Private flagship reasoning Vision apps qwen3-vl-235b-a22bAdvanced image understanding High-volume qwen3-4bCheapest at $0.05/1M Tool calling zai-org-glm-4.7Reliable function calling
Vercel AI SDK Docs Official Vercel AI SDK documentation
Venice Models Browse all Venice models