Handling Integrations
Learn how to handle integration requests and follow-up script permissions in the v0 Platform API
Learn how to handle integration requests when a v0 chat pauses and needs input from your app. The short version is:
- Prompt the agent.
- Inspect the latest assistant message and read the chat's
vercelProjectId. - Install the integration with the Vercel API.
- Confirm the install with
POST /v1/chats/{chatId}/tasks/resolve. - Handle script permissions if the agent asks for them next.
This guide focuses on the integration flow. For the full task schema, see Resolve Task.
1. Prompt the agent
Start or continue a chat with a request that depends on an integration.
For example:
- "Build a waiting list app with Neon."
- "Create a dashboard that uses Supabase auth."
If the agent can continue without extra setup, it will. If it needs an integration, it will stop and ask your app to handle it.
2. Inspect the latest assistant message
When a chat is blocked on integration setup, inspect the latest assistant message first. The blocked task is exposed in experimental_content on:
GET /v1/chats/{chatId}GET /v1/chats/{chatId}/messages/{messageId}
If you use GET /v1/chats/{chatId}, read the last assistant message in the messages array. Chat messages are returned oldest to newest.
For integration requests, you will typically see an assistant message part with:
- stop reason
user-input-required - type
task-get-or-request-integration-v1
Inside that message content, you'll usually see a request telling you which integration to install, such as Neon or Supabase.
The same GET /v1/chats/{chatId} response also includes vercelProjectId at the top level. You will need that value in the next step.
Use the latest blocked assistant message only. If you try to resolve an older task after the chat has moved on, resolve-task returns 409 Conflict.
3. Install the integration with the Vercel API
Once you know which integration the assistant is asking for, install or connect it in Vercel.
Use the chat's vercelProjectId for the project-scoped Vercel API calls in this step. In the beta chat response types, vercelProjectId is the linked Vercel project ID. Do not use projectId here. projectId is the separate v0 project ID, and it is deprecated in the chat response.
import { v0 } from 'v0-sdk'
const chat = await v0.chats.getById({
chatId: '123',
})
if (!chat.vercelProjectId) {
throw new Error('This chat is not linked to a Vercel project yet.')
}
const vercelProjectId = chat.vercelProjectIdThis step happens outside the v0 Platform API. The exact Vercel API calls depend on your integration flow, but these docs are the relevant starting points:
When you call the Vercel endpoint that connects a resource to a project, pass vercelProjectId from the chat.
After the integration is actually connected, return to the v0 chat and confirm it with resolve-task.
4. Confirm the install with resolve-task
Use task.type: "confirmed-steps" after the integration is installed. Pass the integration names exactly as the assistant requested them, such as Neon or Supabase.
import { v0 } from 'v0-sdk'
await v0.chats.resolveTask({
chatId: '123',
task: {
type: 'confirmed-steps',
connectedIntegrationNames: ['Neon'],
},
})If you are rejecting the integration request instead of approving it, pass an empty array:
{
"task": {
"type": "confirmed-steps",
"connectedIntegrationNames": []
}
}You can also confirm other setup work with the same task type, including MCP presets, scripts, and environment variables.
5. Handle script permissions if needed
After the integration is connected, the assistant may ask for permission to run follow-up scripts, such as database setup or migrations.
When that happens, inspect the latest assistant message again. For permission requests, you will typically see:
- stop reason
permissions - a
suggestedPermissionspayload in the blocked assistant message
To approve the request, call resolve-task with task.type: "confirmed-permissions" and send back the suggestedPermissions objects from the latest blocked assistant message.
Pass the permission objects back unchanged. The submitted permissions must match the permissions currently pending on the latest blocked assistant message.
{
"task": {
"type": "confirmed-permissions",
"permissions": [
{
"type": "ALLOW_DYNAMIC_TOOL_STRICT",
"toolName": "SystemAction",
"input": {
"systemAction": "executeScript",
"executeScript": "/scripts/setup-db.sql"
}
}
]
}
}To reject the request, ignore the permission request and send any other follow-up message.
Example Flow
Here is the full flow in plain English:
- Your app prompts v0 to build something that needs Neon.
- The assistant stops with
user-input-requiredand asks for the Neon integration. - Your backend reads
vercelProjectIdfromGET /v1/chats/{chatId}and uses that value in the Vercel API calls that connect Neon. - Your backend calls
POST /v1/chats/{chatId}/tasks/resolvewithconnectedIntegrationNames: ["Neon"]. - The assistant resumes. If it needs to run a migration script, it stops again with
permissions. - Your backend reads
suggestedPermissionsfrom the latest assistant message and sends them back withconfirmed-permissions.
That is the complete pattern for handling integrations in the Platform API.