---
title: Resolve Task
description: Resolves a chat that's blocked waiting for user input and continues the conversation.
product: Platform API
type: reference
prerequisites:
  - /docs/api/platform/quickstart
related:
  - /docs/api/platform/guides/handling-integrations
---

# Resolve Task



<EndpointDisplay method="post" path="/chats/{chatId}/tasks/resolve" />

## Usage [#usage]

Use this endpoint when a chat is blocked on user input. This includes interacting with plan mode, answering agent questions, confirming integration installations, and responding to permission requests.

The submitted `task.type` must match the blocked task from the most recent assistant message. If the latest message is not the task you are resolving, the endpoint returns `409 Conflict`.

If a task payload is structurally valid but empty in a way that would not carry meaningful user intent, the endpoint returns `422 Unprocessable Entity`. For example, blank `plan-exit-response.content`, empty `answered-questions.answers`, and empty `confirmed-permissions.permissions` are rejected.

<CustomCodeBlock languages="['TypeScript', 'cURL']" defaultLanguage="TypeScript">
  <CodeVariant
    language="TypeScript"
    title="TypeScript Example"
    code="`import { v0 } from 'v0-sdk'

const result = await v0.chats.resolveTask({
  chatId: '123',
  task: {
    type: 'plan-exit-response',
    status: 'approved',
    content: 'Proceed with the implementation.',
  },
})

console.log(result)`"
  />

  <CodeVariant
    language="cURL"
    title="cURL Example"
    code="`curl -X POST https://api.v0.dev/v1/chats/123/tasks/resolve \
  -H &#x22;Authorization: Bearer $V0_API_KEY&#x22; \
  -H &#x22;Content-Type: application/json&#x22; \
  -d '{
    &#x22;task&#x22;: {
      &#x22;type&#x22;: &#x22;plan-exit-response&#x22;,
      &#x22;status&#x22;: &#x22;approved&#x22;,
      &#x22;content&#x22;: &#x22;Proceed with the implementation.&#x22;
    }
  }'`"
  />
</CustomCodeBlock>

## Before You Call It [#before-you-call-it]

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}`

Submit the matching resolution payload for the latest blocked task only.

## Task Types [#task-types]

### `confirmed-steps` [#confirmed-steps]

Use when the assistant is blocked on integration, MCP preset, script, or environment setup. To reject the agent's request, pass an empty array for the relevant field.

```json
{
  "task": {
    "type": "confirmed-steps",
    "connectedIntegrationNames": ["Supabase"],
    "connectedMcpPresetNames": ["Linear"],
    "appliedScripts": ["scripts/bootstrap.sh"],
    "addedEnvVars": ["SUPABASE_URL"]
  }
}
```

### `plan-exit-response` [#plan-exit-response]

Use when the assistant proposed a plan and is waiting for approval, rejection, or requested changes.

```json
{
  "task": {
    "type": "plan-exit-response",
    "status": "request-changes",
    "content": "Keep the API shape but split validation into a helper."
  }
}
```

### `answered-questions` [#answered-questions]

Use when the assistant asked one or more multiple-choice questions.

```json
{
  "task": {
    "type": "answered-questions",
    "answers": [
      {
        "questionId": "db-choice",
        "questionText": "Which database should I use?",
        "selectedLabels": ["PostgreSQL"]
      }
    ]
  }
}
```

### `confirmed-permissions` [#confirmed-permissions]

Use when the assistant is blocked on tool or environment variable approval. The submitted permissions must match the permissions currently pending on the latest blocked assistant message.

```json
{
  "task": {
    "type": "confirmed-permissions",
    "permissions": [
      {
        "type": "ALLOW_DYNAMIC_TOOL_STRICT",
        "toolName": "SystemAction",
        "input": {
          "systemAction": "executeScript",
          "executeScript": "/app/scripts/migrate.sql"
        }
      }
    ]
  }
}
```

## API Signature [#api-signature]

### Request [#request]

#### Path Parameters [#path-parameters]

<APISignature
  parameters="[
    {
      &#x22;name&#x22;: &#x22;chatId&#x22;,
      &#x22;type&#x22;: &#x22;string&#x22;,
      &#x22;required&#x22;: true,
      &#x22;description&#x22;: &#x22;The unique identifier of the chat containing the pending task. Provided as a path parameter.&#x22;
    }
  ]"
/>

#### Body [#body]

<APISignature
  parameters="[
    {
      &#x22;name&#x22;: &#x22;task&#x22;,
      &#x22;type&#x22;: &#x22;object&#x22;,
      &#x22;required&#x22;: true,
      &#x22;description&#x22;: &#x22;The task resolution payload. The latest message in the active chat fork must be an assistant message blocked on the matching task type.&#x22;,
      &#x22;deprecated&#x22;: false,
      &#x22;properties&#x22;: [
        {
          &#x22;name&#x22;: &#x22;type&#x22;,
          &#x22;type&#x22;: &#x22;'confirmed-steps' | 'plan-exit-response' | 'answered-questions' | 'confirmed-permissions'&#x22;,
          &#x22;required&#x22;: true,
          &#x22;description&#x22;: &#x22;The blocked task type being resolved.&#x22;,
          &#x22;deprecated&#x22;: false
        }
      ]
    },
    {
      &#x22;name&#x22;: &#x22;responseMode&#x22;,
      &#x22;type&#x22;: &#x22;'sync' | 'async' | 'experimental_stream'&#x22;,
      &#x22;required&#x22;: false,
      &#x22;description&#x22;: &#x22;Controls how the response is delivered.&#x22;,
      &#x22;deprecated&#x22;: false
    },
    {
      &#x22;name&#x22;: &#x22;modelConfiguration&#x22;,
      &#x22;type&#x22;: &#x22;object&#x22;,
      &#x22;required&#x22;: false,
      &#x22;description&#x22;: &#x22;Overrides for the model behavior.&#x22;,
      &#x22;deprecated&#x22;: false
    }
  ]"
/>

### Response [#response]

Returns the updated chat object, using the same response shape as `GET /v1/chats/{chatId}`.
