> ## Documentation Index
> Fetch the complete documentation index at: https://docs.blackbox.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Cancel Task

> Stop or cancel a running task. This will terminate the sandbox environment and mark the task as stopped.

This endpoint allows you to stop a task that is currently in progress. When you cancel a task, it will update the task status to `stopped`, terminate the associated sandbox environment, and mark the task as completed with an error message indicating it was stopped by the user.

## Authentication

**Required** - You need a BLACKBOX API Key to use this API.

Follow these steps to get your API key:

1. **Click on your Profile Image** in the top right corner at [cloud.blackbox.ai](https://cloud.blackbox.ai)
2. **Click on "BLACKBOX API Token"** from the dropdown menu
3. **Copy the existing token** or **click "Generate"** if you don't have one yet

Your API key will be in the format: `bb_xxxxxxxxxxxxxxxxxxxxxx`

## Headers

<ParamField header="Authorization" type="string" required>
  API Key of the form `Bearer <api_key>`.

  Example: `Bearer bb_b41b647ffbfed27f61656049d3eaeef3d903cc503345d9eb80080d98bc0`
</ParamField>

<ParamField header="Content-Type" type="string" required>
  Must be `application/json`.
</ParamField>

## Path Parameters

<ParamField path="taskId" type="string" required>
  The unique identifier of the task you want to cancel.

  Example: `9qQe2F8Z_nXx9-eJA0BD6`
</ParamField>

## Request Body

<ParamField body="action" type="string" required>
  The action to perform. Must be `"stop"` to cancel the task.
</ParamField>

## Response Fields

<ResponseField name="message" type="string">
  Success message confirming the task was stopped.
</ResponseField>

<ResponseField name="task" type="object">
  Updated task object with the following fields:
</ResponseField>

<ResponseField name="task.id" type="string">
  Task identifier.
</ResponseField>

<ResponseField name="task.userId" type="string">
  Email or ID of the user who created the task.
</ResponseField>

<ResponseField name="task.status" type="string">
  Updated status (will be "stopped").
</ResponseField>

<ResponseField name="task.error" type="string">
  Error message explaining the stop ("Task was stopped by user").
</ResponseField>

<ResponseField name="task.updatedAt" type="string">
  ISO 8601 timestamp of when the task was stopped.
</ResponseField>

<ResponseField name="task.completedAt" type="string">
  ISO 8601 timestamp when the task was stopped.
</ResponseField>

<RequestExample>
  ```bash cURL theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  curl -X PATCH 'https://cloud.blackbox.ai/api/tasks/9qQe2F8Z_nXx9-eJA0BD6' \
    -H 'Authorization: Bearer YOUR_API_KEY' \
    -H 'Content-Type: application/json' \
    -d '{"action": "stop"}'
  ```

  ```javascript Node.js theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  const API_KEY = "YOUR_API_KEY";
  const TASK_ID = "9qQe2F8Z_nXx9-eJA0BD6";
  const API_URL = `https://cloud.blackbox.ai/api/tasks/${TASK_ID}`;

  const response = await fetch(API_URL, {
      method: "PATCH",
      headers: {
          Authorization: `Bearer ${API_KEY}`,
          "Content-Type": "application/json",
      },
      body: JSON.stringify({ action: "stop" }),
  });

  const data = await response.json();
  console.log(data.message); // "Task stopped successfully"
  console.log(`Task ${data.task.id} stopped at ${data.task.completedAt}`);
  ```

  ```python Python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  import requests

  API_KEY = "YOUR_API_KEY"
  TASK_ID = "9qQe2F8Z_nXx9-eJA0BD6"
  API_URL = f"https://cloud.blackbox.ai/api/tasks/{TASK_ID}"

  headers = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json"
  }

  data = {"action": "stop"}

  response = requests.patch(API_URL, headers=headers, json=data)
  result = response.json()

  print(result["message"])  # "Task stopped successfully"
  print(f"Task {result['task']['id']} status: {result['task']['status']}")
  ```

  ```go Go theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  package main

  import (
      "bytes"
      "encoding/json"
      "fmt"
      "io"
      "net/http"
  )

  func main() {
      apiKey := "YOUR_API_KEY"
      taskId := "9qQe2F8Z_nXx9-eJA0BD6"
      url := fmt.Sprintf("https://cloud.blackbox.ai/api/tasks/%s", taskId)

      requestBody, _ := json.Marshal(map[string]string{
          "action": "stop",
      })

      req, _ := http.NewRequest("PATCH", url, bytes.NewBuffer(requestBody))
      req.Header.Add("Authorization", fmt.Sprintf("Bearer %s", apiKey))
      req.Header.Add("Content-Type", "application/json")

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
          panic(err)
      }
      defer resp.Body.Close()

      body, _ := io.ReadAll(resp.Body)
      
      var result map[string]interface{}
      json.Unmarshal(body, &result)
      
      fmt.Println(result["message"])
  }
  ```
</RequestExample>

<ResponseExample>
  ```json Success Response theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  {
    "message": "Task stopped successfully",
    "task": {
      "id": "9qQe2F8Z_nXx9-eJA0BD6",
      "userId": "user@example.com",
      "status": "stopped",
      "error": "Task was stopped by user",
      "updatedAt": "2024-01-15T10:30:00.000Z",
      "completedAt": "2024-01-15T10:30:00.000Z"
    }
  }
  ```

  ```json Error - Task Not In Progress theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  {
    "error": "Task can only be stopped when it is in progress"
  }
  ```

  ```json Error - Task Not Found theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  {
    "error": "Task not found"
  }
  ```

  ```json Error - Unauthorized theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
  {
    "error": "Unauthorized",
    "message": "Invalid or missing API key",
    "status": 401
  }
  ```
</ResponseExample>

## Use Cases

### Cancel a Long-Running Task

Cancel a task that's taking too long or is no longer needed:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
async function cancelTask(taskId) {
  const API_KEY = "YOUR_API_KEY";
  const API_URL = `https://cloud.blackbox.ai/api/tasks/${taskId}`;
  
  try {
    const response = await fetch(API_URL, {
      method: "PATCH",
      headers: {
        Authorization: `Bearer ${API_KEY}`,
        "Content-Type": "application/json",
      },
      body: JSON.stringify({ action: "stop" }),
    });

    if (!response.ok) {
      const error = await response.json();
      throw new Error(error.error || "Failed to cancel task");
    }

    const data = await response.json();
    console.log(data.message); // "Task stopped successfully"
    return data.task;
  } catch (error) {
    console.error("Failed to cancel task:", error.message);
    throw error;
  }
}

// Usage
try {
  const stoppedTask = await cancelTask("9qQe2F8Z_nXx9-eJA0BD6");
  console.log(`Task ${stoppedTask.id} stopped at ${stoppedTask.completedAt}`);
} catch (error) {
  console.error("Error:", error.message);
}
```

### Cancel with Timeout

Automatically cancel a task if it exceeds a certain duration:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
async function runTaskWithTimeout(taskId, timeoutMs = 300000) {
  const API_KEY = "YOUR_API_KEY";
  
  // Start monitoring the task
  const timeoutPromise = new Promise((_, reject) => {
    setTimeout(() => reject(new Error("Task timeout")), timeoutMs);
  });
  
  const taskPromise = async () => {
    while (true) {
      const statusResponse = await fetch(
        `https://cloud.blackbox.ai/api/tasks/${taskId}/status`,
        {
          headers: { Authorization: `Bearer ${API_KEY}` },
        }
      );
      const status = await statusResponse.json();
      
      if (status.isDone) {
        return status;
      }
      
      await new Promise(resolve => setTimeout(resolve, 2000));
    }
  };
  
  try {
    return await Promise.race([taskPromise(), timeoutPromise]);
  } catch (error) {
    if (error.message === "Task timeout") {
      console.log("Task exceeded timeout, cancelling...");
      await cancelTask(taskId);
      throw new Error("Task was cancelled due to timeout");
    }
    throw error;
  }
}

// Usage
try {
  const result = await runTaskWithTimeout("9qQe2F8Z_nXx9-eJA0BD6", 300000);
  console.log("Task completed:", result);
} catch (error) {
  console.error("Task error:", error.message);
}
```

### Python Cancel Example

```python theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
import requests

def cancel_task(task_id: str, api_key: str):
    """Cancel a running task"""
    url = f'https://cloud.blackbox.ai/api/tasks/{task_id}'
    headers = {
        'Authorization': f'Bearer {api_key}',
        'Content-Type': 'application/json'
    }
    data = {'action': 'stop'}
    
    response = requests.patch(url, headers=headers, json=data)
    
    if response.status_code == 200:
        result = response.json()
        print(f"Task stopped: {result['message']}")
        return result['task']
    else:
        error = response.json()
        raise Exception(error.get('error', 'Failed to cancel task'))

# Usage
try:
    stopped_task = cancel_task('9qQe2F8Z_nXx9-eJA0BD6', 'YOUR_API_KEY')
    print(f"Task {stopped_task['id']} status: {stopped_task['status']}")
except Exception as e:
    print(f"Error: {e}")
```

### Cancel Multiple Tasks

Cancel multiple tasks at once:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
async function cancelMultipleTasks(taskIds) {
  const API_KEY = "YOUR_API_KEY";
  
  const cancelPromises = taskIds.map(async (taskId) => {
    try {
      const response = await fetch(
        `https://cloud.blackbox.ai/api/tasks/${taskId}`,
        {
          method: "PATCH",
          headers: {
            Authorization: `Bearer ${API_KEY}`,
            "Content-Type": "application/json",
          },
          body: JSON.stringify({ action: "stop" }),
        }
      );
      
      if (response.ok) {
        const data = await response.json();
        return { taskId, success: true, data };
      } else {
        const error = await response.json();
        return { taskId, success: false, error: error.error };
      }
    } catch (error) {
      return { taskId, success: false, error: error.message };
    }
  });
  
  const results = await Promise.all(cancelPromises);
  
  const successful = results.filter(r => r.success);
  const failed = results.filter(r => !r.success);
  
  console.log(`Cancelled ${successful.length} tasks`);
  if (failed.length > 0) {
    console.log(`Failed to cancel ${failed.length} tasks:`, failed);
  }
  
  return results;
}

// Usage
const taskIds = ["task1", "task2", "task3"];
const results = await cancelMultipleTasks(taskIds);
```

### Graceful Shutdown

Implement graceful shutdown when user exits application:

```javascript theme={"theme":{"light":"github-light-default","dark":"github-dark-default"}}
class TaskManager {
  constructor(apiKey) {
    this.apiKey = apiKey;
    this.activeTasks = new Set();
    
    // Handle process termination
    process.on('SIGINT', () => this.shutdown());
    process.on('SIGTERM', () => this.shutdown());
  }
  
  async startTask(taskId) {
    this.activeTasks.add(taskId);
    // ... start task logic
  }
  
  async shutdown() {
    console.log('Shutting down, cancelling active tasks...');
    
    const cancelPromises = Array.from(this.activeTasks).map(taskId =>
      fetch(`https://cloud.blackbox.ai/api/tasks/${taskId}`, {
        method: "PATCH",
        headers: {
          Authorization: `Bearer ${this.apiKey}`,
          "Content-Type": "application/json",
        },
        body: JSON.stringify({ action: "stop" }),
      })
    );
    
    await Promise.allSettled(cancelPromises);
    console.log('All tasks cancelled');
    process.exit(0);
  }
}

// Usage
const manager = new TaskManager("YOUR_API_KEY");
```

## Important Notes

1. **Only Active Tasks**: You can only stop tasks that are currently in `processing` or `saving` status. Completed, failed, or already stopped tasks cannot be stopped again.

2. **Sandbox Termination**: The API will attempt to gracefully shutdown all associated sandbox environments. If sandbox termination fails, the task status will still be updated to `stopped`.

3. **Followup Messages**: If the task has active followup messages, the last one will be marked as stopped with an appropriate status message.

4. **Irreversible**: Once a task is stopped, it cannot be resumed from where it left off. You would need to create a new task to restart the work.

5. **Error Handling**: Always check the response status code. A 400 error indicates the task is not in a state that can be stopped.

## Error Codes

| Status Code | Error                 | Description                                    |
| ----------- | --------------------- | ---------------------------------------------- |
| 200         | Success               | Task stopped successfully                      |
| 400         | Bad Request           | Task is not in progress and cannot be stopped  |
| 401         | Unauthorized          | Invalid or missing API key                     |
| 404         | Not Found             | Task doesn't exist or user doesn't have access |
| 500         | Internal Server Error | Server-side error occurred                     |
