The v0 API is now generally available

v0's app-building agent is now accessible programmatically through a new API. Send a prompt and v0 generates an app, starts a dev server in a Vercel Sandbox, and returns a preview URL you can embed in your own interface. The API is generally available today.

Each chat acts as an isolated workspace for a single app, where v0 can read, edit, and run files. Follow-up messages build on the current state, and v0 verifies the code running in the Sandbox to catch and fix errors in real time.

Core workflow

Install the v0 SDK, then create a chat from a prompt.

pnpm add v0@latest

import { v0 } from 'v0'

const result = await v0.chats.create({

message: 'Build an issue triage app for a support team.',

})

if (result.error) {

throw new Error(result.error.message)

}

const chatId = result.data.chat.id

Keep the chat ID for every subsequent request. Send follow-up messages to the same chat to continue building, and v0 edits the existing app in place.

const message = await v0.messages.send({

chatId,

message: 'Add a priority filter and an assignee column.',

})

if (message.error) {

throw new Error(message.error.message)

}

Embed the result by pointing an iframe at a proxy route.

<iframe src="/api/v0-preview/chat_abc123/" />

A prompt goes in, a running app comes out. v0 manages the Sandbox, dev server, and preview behind the scenes. When you're ready, deploy to Vercel with a single API call.

What this enables

  • A white-labeled app builder: Users describe an app and receive one in return.
  • Automated app changes: Trigger v0 from a script, CI job, or webhook to generate or update an app.
  • A build tool for your agents: An agent returns a working app rather than a code snippet.

Request modes and streaming

Chat creation and messages support synchronous, asynchronous, and streaming responses. Sync mode suits callers that need the completed response immediately; async queues work and delivers updates via webhook or polling; streaming renders v0's work as it progresses.

const message = 'Build an issue triage app for a support team.'

// Wait for the completed response.

const completed = await v0.chats.create({ message })

if (completed.error) {

throw new Error(completed.error.message)

}

// Queue work and use the returned IDs to retrieve the result later.

const queued = await v0.chats.createAsync({ message })

if (queued.error) {

throw new Error(queued.error.message)

}

console.log(queued.data.chatId, queued.data.messageId)

// Receive the agent's work as it happens.

const stream = await v0.chats.createStream({ message })

Each message includes ordered parts: text, thinking, file reads and edits, searches, bash commands, tool calls, and agent actions. The same object can drive a one-line status, a changed-files view, or the full trace. Usage data is returned with chat and message responses so you can account for work when it finishes.

const stream = await v0.messages.sendStream({

chatId: 'chat_abc123',

message: 'Add authentication and explain the files you changed.',

})

for await (const update of stream.stream) {

console.log(update.parts)

if (update.usage) {

console.log(update.usage)

}

}

Existing code and design systems

You can create a chat from a repository, ZIP archive, or a set of files, so v0 works from current state. Design Systems 2.0 saves a design system as a skill; include it in a request to load its components, tokens, setup, and starter app. Up to three skills per request can come from team or user memory, skills.sh, or the connected repo, or the agent can pull them automatically.

const result = await v0.chats.createFromRepo({

repo: {

url: 'https://github.com/acme/app',

branch: 'main',

},

title: 'Acme app',

metadata: {

source: 'github',

},

})

if (result.error) {

throw new Error(result.error.message)

}

const chatId = result.data.chat.id

console.log(chatId)

const designSystem = {

type: 'memory',

scope: 'team',

skillName: 'geist-ui',

}

const result = await v0.chats.create({

message: 'Build an admin console with filters and charts.',

skills: [

designSystem,

],

})

You can also enable specific MCP servers for a chat, or use the defaults.

Preview tokens

Each chat gets a short-lived preview token. Fetch it from a server route and proxy browser requests through it, so your v0 API key never reaches the client. While the Sandbox spins up, requests fall back to a loading route; when the preview is ready, traffic forwards to it. Point an iframe at your proxy route and cache the preview details until expiry.

import { fetchPreview, v0 } from 'v0'

export async function proxyPreviewRequest(

request: Request,

chatId: string,

path: string[],

) {

const result = await v0.chats.getPreview({ chatId })

if (result.error) {

throw new Error(result.error.message)

}

return fetchPreview({

request,

preview: result.data,

path,

fallbackUrl: `/api/v0-preview/${chatId}/loading`,

})

}

Agent integration

Give your agent v0 as a tool. When it needs to produce a working app, it calls v0 and receives a running preview or deployment to pass along. The agent stays in control of everything else. Three connection paths are available.

MCP

Connect the v0 MCP server to an IDE, desktop assistant, or MCP-capable agent runtime. The first connection starts an OAuth flow; the server exposes tools for creating chats, listing chats, getting details, listing and sending messages, resolving pending tasks, and fetching preview URLs.

{

"mcpServers": {

"v0": {

"url": "https://v0.app/api/mcp"

}

}

}

AI SDK

For TypeScript agents built with AI SDK, use @v0-sdk/ai-tools to expose v0's API operations as tools in the agent's own loop. The agent decides when to create or continue a chat while your AI SDK run keeps control of orchestration and the final response.

pnpm add @v0-sdk/ai-tools ai @ai-sdk/openai

import { openai } from '@ai-sdk/openai'

import { generateText, stepCountIs } from 'ai'

import { v0ToolsByCategory } from '@v0-sdk/ai-tools'

const { chats, messages } = v0ToolsByCategory()

const result = await generateText({

model: openai('gpt-5.5'),

system: `Use v0 for creating and modifying web apps. Continue an existing v0 chat when a chat ID is available.`,

prompt: 'Build a customer insights app with charts.',

tools: {

...chats,

...messages,

},

stopWhen: stepCountIs(10),

})

eve

For eve agents, add an OpenAPI connection file. eve converts the allowed operations into tools and attaches the API key at execution time, outside model context.

import { defineOpenAPIConnection } from 'eve/connections'

export default defineOpenAPIConnection({

spec: 'https://api.v0.dev/v2/openapi/json',

baseUrl: 'https://api.v0.dev/v2',

description:

'Build and iterate on web apps with v0. Reuse one v0 chat per app-building task.',

auth: {

getToken: async () => ({ token: process.env.V0_API_KEY! }),

},

operations: {

allow: [

'chats_create',

'messages_send',

'messages_resolve',

'chats_getPreview',

],

},

})

Deployment and migration

Create a Vercel project for the chat and manage environment variables, integrations, and settings through the Vercel API. Apps inherit Vercel's security and observability by default. When ready, deploy the chat in one call.

const result = await v0.chats.createVercelProject({

chatId: 'chat_123',

})

if (result.error) {

throw new Error(result.error.message)

}

const vercelProjectId = result.data.vercelProjectId

const result = await v0.chats.deploy({ chatId })

if (result.error) {

throw new Error(result.error.message)

}

const { deploymentId, vercelProjectId } = result.data

Chats from the previous v0 API version don't run on the new one. To migrate, download the old chat as a ZIP and create a new chat from that archive, keeping old identifiers in the new chat's metadata for traceability.

  • Use https://api.v0.dev/v2 for new requests.
  • The chat holds current app state; messages hold history.
  • Replace version workflows with chat file workflows and v0 Project organization with chat metadata.
  • Render message parts, not only final text.

Getting started

Create an API key in v0 settings and install the SDK, or scaffold a complete example app.

pnpm add v0@latest

pnpm create v0-sdk-app@latest my-v0-app

The full documentation and migration guide cover the endpoints and mapping in detail.