> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://developers.awork.com/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://developers.awork.com/_mcp/server.

# Updates multiple tasks with the selected operation.

POST https://api.awork.com/api/v1/tasks/batch/{operation}
Content-Type: application/json

Updates multiple tasks with the selected operation. Supported operations move tasks, change dates, manage tags, change status or type, assign users, copy tasks, and delete tasks.
The user must have `write` permission for the requested tasks and related entities.

Reference: https://developers.awork.com/apiv1/tasks/post-tasks-batch-by-operation

## Authentication

- `Authorization` header (bearer token, required) — Bearer authentication of the form `Bearer <token>`, where token is your auth token.

## Request

### Path parameters

- `operation` (string, required) — The operation to perform on all tasks.

### Body (application/json)

This endpoint expects a BatchOperationForm.

- `taskIds` (list of string, required) — The list of task ids to perform the batch operation on.
- `newTaskListId` (string, optional, nullable) — The id of the new task list. Needed if operation is 'movetotasklist'. Optional if operation is 'movetoproject'.
- `removeFromCurrentList` (boolean, optional, nullable) — Whether to remove the task from all its current task lists. Optional for operation 'movetotasklist'.
- `newProjectId` (string, optional, nullable) — The id of the new project to move the tasks to. Needed if operation is 'movetoproject'.
- `newParentTaskId` (string, optional, nullable) — The id of the task that will be the new parent of the selected tasks. Needed if operation is 'moveundertask'.
- `taskStatusMapping` (list of TaskStatusMappingForm, optional, nullable) — The task status mapping from old task status to new task status. Optional for operation 'movetoproject'.
- `newDueDate` (string, optional, nullable) — The new due date for the tasks. Optional for operation 'setdates'. If not set, due and start date will be removed.
- `newStartDate` (string, optional, nullable) — The new start date for the tasks. Optional for operation 'setdates'. Only gets used when NewDueDate is set.
- `removeDueDate` (boolean, optional, nullable) — Whether to remove the due date. Required for operation 'setdates'.
- `removeStartDate` (boolean, optional, nullable) — Whether to remove the start date. Required for operation 'setdates'.
- `tags` (list of TagForm, optional, nullable) — List of tags to add to the tasks. If task already has tag, tag is skipped.
- `deleteTimeTrackings` (boolean, optional, nullable) — Whether to delete the timetrackings of each task when deleting tasks. Optional for operation 'delete'.
- `newTypeOfWorkId` (string, optional, nullable) — The new type of work id for the tasks. Required if operation is 'changetypeofwork'.
- `changeTimeEntries` (boolean, optional, nullable) — Whether to change the type of work of the timeentries for each task aswell. Optional for operation 'changetypeofwork'.
- `userIds` (list of string, optional, nullable) — Depending on the batch operation, it can be either the ids of the user to assign ('assignusers', required) or the ids of the user to remove ('unassignusers', optional, if not provided unassigns all users).
- `removeOldAssignments` (boolean, optional, nullable) — Whether to replace or add user assignments to a task that has users already assigned. Optional for operation 'assignusers'.
- `isPrio` (boolean, optional, nullable) — Whether to set the tasks to be prio or not. Required for operation 'setprio'.
- `daysOffset` (double, optional, nullable) — In case of an adjust date operation, define the number (positive or negative) of days that will be added/subtracted to the task dates. It can be a decimal number (fraction of day)
- `adjustSuccessors` (boolean, optional, nullable) — If set to true, it will adjust the dates of successor tasks as well.
- `adjustSubtasks` (boolean, optional, nullable) — If set to true, it will adjust the dates of subtasks of selected tasks. If set to false, it will only adjust the dates of the selected tasks.
- `plannerData` (PlannerOperationData, optional) — Data specific to planner batch operations for handling drag and drop in the planner UI.
- `newTaskStatusId` (string, optional, nullable, deprecated) — Deprecated for 'movetoproject': use TaskStatusMapping instead. The id of the new task status id to change the tasks to. Needed if operation is 'movetoproject' or 'changetaskstatus'.

## Response

### 207

Multi-Status

- `ok` (StatusResult, optional)
- `notFound` (StatusResult, optional)
- `unauthorized` (StatusResult, optional)
- `badRequest` (StatusResult, optional)

## Errors

### 400 Bad Request Error

Bad Request

- `code` (string, required) — The error code.
- `description` (string, required) — The description of the error.
- `link` (string, required) — The link to the API documentation page.
- `details` (list of string, optional, nullable) — A list of details describing the error.
- `validationErrors` (list of ValidationErrorResponse, optional, nullable) — If a validation error occurred, this contains the validation errors for each property.
- `traceId` (string, optional, nullable) — The request trace id for tracking the request.

### 401 Unauthorized Error

Unauthorized

- `code` (string, required) — The error code.
- `description` (string, required) — The description of the error.
- `link` (string, required) — The link to the API documentation page.
- `details` (list of string, optional, nullable) — A list of details describing the error.
- `validationErrors` (list of ValidationErrorResponse, optional, nullable) — If a validation error occurred, this contains the validation errors for each property.
- `traceId` (string, optional, nullable) — The request trace id for tracking the request.

## Types

### TaskStatusMappingForm

- `oldStatusId` (string, required) — The old task status id.
- `newStatusId` (string, required) — The new task status id.

### TagForm

- `name` (string, required) — The name of the tag to delete.
- `color` (string, optional, nullable) — The color of the tag. Use one of 'red', 'coral', 'yellow', 'green', 'teal', 'arctic', 'blue', 'azure', 'purple', 'violet'.

### PlannerOperationData

Data specific to planner batch operations for handling drag and drop in the planner UI.

- `referenceTaskId` (string, required) — The reference task that was dragged (determines delta calculation).
- `targetStartDate` (string, optional, nullable) — Target start date for the reference task (used to calculate start date delta). Null if no start date change.
- `targetEndDate` (string, optional, nullable) — Target end date for the reference task (used to calculate end date delta). Null if no end date change. Allows extending or shortening task duration.
- `targetLaneOrder` (integer, optional, nullable) — Target lane order for vertical moves in planner. Null if no lane change.
- `setDates` (boolean, optional) — Whether to set absolute dates for the task (not delta-based). When true, only a single task can be modified. Only applies when TargetStartDate or TargetEndDate is provided.
- `moveType` (enum, optional) — Defines the type of move operation in the planner.
  - Allowed values: `DateOnly`, `LaneOnly`, `DateAndLane`, `AssigneeChange`, `AssigneeAndLane`, `AssigneeAndDate`

### StatusResult

- `ids` (list of string, optional, nullable)

### ValidationErrorResponse

The validation error response.

- `property` (string, optional, nullable) — The name of the property that failed validation.
- `message` (string, optional, nullable) — The reason why this property failed validation.

## Examples

**Request**

```json
{
  "taskIds": [
    "string"
  ]
}
```

**Response**

```json
{
  "ok": {
    "ids": [
      "string"
    ]
  },
  "notFound": {
    "ids": [
      "string"
    ]
  },
  "unauthorized": {
    "ids": [
      "string"
    ]
  },
  "badRequest": {
    "ids": [
      "string"
    ]
  }
}
```

**SDK Code**

```python
import requests

url = "https://api.awork.com/api/v1/tasks/batch/operation"

payload = { "taskIds": ["string"] }
headers = {
    "Authorization": "Bearer <token>",
    "Content-Type": "application/json"
}

response = requests.post(url, json=payload, headers=headers)

print(response.json())
```

```javascript
const url = 'https://api.awork.com/api/v1/tasks/batch/operation';
const options = {
  method: 'POST',
  headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
  body: '{"taskIds":["string"]}'
};

try {
  const response = await fetch(url, options);
  const data = await response.json();
  console.log(data);
} catch (error) {
  console.error(error);
}
```

```go
package main

import (
	"fmt"
	"strings"
	"net/http"
	"io"
)

func main() {

	url := "https://api.awork.com/api/v1/tasks/batch/operation"

	payload := strings.NewReader("{\n  \"taskIds\": [\n    \"string\"\n  ]\n}")

	req, _ := http.NewRequest("POST", url, payload)

	req.Header.Add("Authorization", "Bearer <token>")
	req.Header.Add("Content-Type", "application/json")

	res, _ := http.DefaultClient.Do(req)

	defer res.Body.Close()
	body, _ := io.ReadAll(res.Body)

	fmt.Println(res)
	fmt.Println(string(body))

}
```

```ruby
require 'uri'
require 'net/http'

url = URI("https://api.awork.com/api/v1/tasks/batch/operation")

http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true

request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n  \"taskIds\": [\n    \"string\"\n  ]\n}"

response = http.request(request)
puts response.read_body
```

```java
import com.mashape.unirest.http.HttpResponse;
import com.mashape.unirest.http.Unirest;

HttpResponse<String> response = Unirest.post("https://api.awork.com/api/v1/tasks/batch/operation")
  .header("Authorization", "Bearer <token>")
  .header("Content-Type", "application/json")
  .body("{\n  \"taskIds\": [\n    \"string\"\n  ]\n}")
  .asString();
```

```php
<?php
require_once('vendor/autoload.php');

$client = new \GuzzleHttp\Client();

$response = $client->request('POST', 'https://api.awork.com/api/v1/tasks/batch/operation', [
  'body' => '{
  "taskIds": [
    "string"
  ]
}',
  'headers' => [
    'Authorization' => 'Bearer <token>',
    'Content-Type' => 'application/json',
  ],
]);

echo $response->getBody();
```

```csharp
using RestSharp;

var client = new RestClient("https://api.awork.com/api/v1/tasks/batch/operation");
var request = new RestRequest(Method.POST);
request.AddHeader("Authorization", "Bearer <token>");
request.AddHeader("Content-Type", "application/json");
request.AddParameter("application/json", "{\n  \"taskIds\": [\n    \"string\"\n  ]\n}", ParameterType.RequestBody);
IRestResponse response = client.Execute(request);
```

```swift
import Foundation

let headers = [
  "Authorization": "Bearer <token>",
  "Content-Type": "application/json"
]
let parameters = ["taskIds": ["string"]] as [String : Any]

let postData = JSONSerialization.data(withJSONObject: parameters, options: [])

let request = NSMutableURLRequest(url: NSURL(string: "https://api.awork.com/api/v1/tasks/batch/operation")! as URL,
                                        cachePolicy: .useProtocolCachePolicy,
                                    timeoutInterval: 10.0)
request.httpMethod = "POST"
request.allHTTPHeaderFields = headers
request.httpBody = postData as Data

let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
  if (error != nil) {
    print(error as Any)
  } else {
    let httpResponse = response as? HTTPURLResponse
    print(httpResponse)
  }
})

dataTask.resume()
```