---
title: Handling Integrations
description: Learn how to handle integration requests and follow-up script permissions in the v0 API
product: Platform API
type: guide
related:
  - /docs/api/v2/reference/messages/resolve-task
  - /docs/api/v2/reference/chats/get-chat
  - /docs/api/v2/reference/messages/get-message
---

# Handling Integrations



Learn how to handle integration requests when a v0 chat pauses and needs input from your app. The short version is:

1. Prompt the agent.
2. Inspect the latest assistant message and read the chat's `vercelProjectId`.
3. Install the integration with the Vercel API.
4. Confirm the install with `POST /v2/chats/{chatId}/messages/resolve`.
5. 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](/docs/api/v2/reference/messages/resolve-task).

## 1. Prompt the agent [#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 [#2-inspect-the-latest-assistant-message]

When a chat is blocked on integration setup, inspect the latest assistant message first. Fetch it with:

* `GET /v2/chats/{chatId}/messages/{messageId}`

An integration request surfaces as an `agent-action` part in the message's `parts` array with `name: "get_or_request_integration"`. Its `data.requestedIntegrations` lists the integration names to install (for example, `["Neon"]`), and `data.requestedMcpPresets` lists any MCP presets. You pass these values back in step 4. The message `content` also describes the request in prose.

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 [#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.

```typescript
import { v0 } from 'v0'

const chat = await v0.chats.get({
  chatId: '123',
})

if (!chat.vercelProjectId) {
  throw new Error('This chat is not linked to a Vercel project yet.')
}

const vercelProjectId = chat.vercelProjectId
```

This step happens outside the v0 API. The exact Vercel API calls depend on your integration flow, but these docs are the relevant starting points:

* [Create Integration Store Free and Paid Plans](https://vercel.com/docs/rest-api/integrations/create-integration-store-free-and-paid-plans)
* [Connect Integration Resource to Project](https://vercel.com/docs/rest-api/integrations/connect-integration-resource-to-project)

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` [#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`.

```typescript
import { v0 } from 'v0'

await v0.messages.resolve({
  chatId: '123',
  task: {
    type: 'confirmed-steps',
    connectedIntegrationNames: ['Neon'],
  },
})
```

If you are rejecting the integration request instead of approving it, pass an empty array:

```json
{
  "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 [#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. The pending action surfaces as a `tool-call` part in the message's `parts` array. While the agent is waiting for your approval, that part includes a `suggestedPermissions` array.

To approve the request, call `resolve` with `task.type: "confirmed-permissions"` and pass the `suggestedPermissions` objects back unchanged as `task.permissions`.

The submitted permissions must match the ones currently pending on the latest blocked assistant message, or `resolve` returns `409 Conflict`.

```json
{
  "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 [#example-flow]

Here is the full flow in plain English:

1. Your app prompts v0 to build something that needs Neon.
2. The assistant stops and asks for the Neon integration, surfaced as a `get_or_request_integration` agent-action part.
3. Your backend reads `vercelProjectId` from `GET /v2/chats/{chatId}` and uses that value in the Vercel API calls that connect Neon.
4. Your backend calls `POST /v2/chats/{chatId}/messages/resolve` with `connectedIntegrationNames: ["Neon"]`.
5. The assistant resumes. If it needs to run a migration script, it stops again with a `tool-call` part that carries `suggestedPermissions`.
6. Your backend passes those `suggestedPermissions` back in a `confirmed-permissions` task to approve.

That is the complete pattern for handling integrations in the Platform API.
