This document shows how to create a batch of tasks from a server environment
using gRPC or REST. For more details on creating tasks, see:

- [Create shipment tasks](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/create-shipment-tasks.md.txt)
- [Create other task types](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/create-other-tasks.md.txt)

## Task fields for creating tasks in batch

When creating tasks in batch, each `CreateTasksRequest` element in `requests`
must pass the same validation rules as a `CreateTask` request for a single task,
with the exception that the `parent` and `header` fields are optional.
If set, they must be identical to their respective fields at the top level
`BatchCreateTasksRequest`.

For more information, see the API Reference documentation for `BatchCreateTasks`
for [gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.DeliveryService) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/providers.tasks/batchCreate.md.txt).

### Required batch fields

| Field | Value |
|---|---|
| requests | `Array<CreateTasksRequest>` |

### Optional batch task fields

| Field | Value |
|---|---|
| header | `DeliveryRequestHeader` |

## Create a batch of tasks

The following examples shows how to create both a pickup and a delivery task
using the [Java gRPC library](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/client-libraries-tasks.md.txt#java) or how to make an HTTP REST request to
[`BatchCreateTask`](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/providers.tasks/batchCreate.md.txt). See
[JWT elements](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt.md.txt#jwt-elements)
for the correct JWT syntax.

### gRPC

```java
static final String PROJECT_ID = "my-delivery-co-gcp-project";

DeliveryServiceBlockingStub deliveryService =
  DeliveryServiceGrpc.newBlockingStub(channel);

// Delivery Task settings
Task deliveryTask = Task.newBuilder()
  .setType(Task.Type.DELIVERY)
  .setState(Task.State.OPEN)
  .setTrackingId("delivery-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Delivery Task request
CreateTaskRequest createDeliveryTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8312508")  // Task ID assigned by the Provider
      .setTask(deliveryTask)      // Initial state
      .build();

// Pickup Task settings
Task pickupTask = Task.newBuilder()
  .setType(Task.Type.PICKUP)
  .setState(Task.State.OPEN)
  .setTrackingId("pickup-tracking-id")
  .setPlannedLocation(               // Grand Indonesia East Mall
    LocationInfo.newBuilder().setPoint(
      LatLng.newBuilder().setLatitude(-6.195139).setLongitude(106.820826)))
  .setTaskDuration(
    Duration.newBuilder().setSeconds(2 * 60))
  .build();

// Pickup Task request
CreateTaskRequest createPickupTaskRequest =
  CreateTaskRequest.newBuilder()  // No need for the header or parent fields
      .setTaskId("task-8241890")  // Task ID assigned by the Provider
      .setTask(pickupTask)        // Initial state
      .build();

// Batch Create Tasks settings
String parent = "providers/" + PROJECT_ID;

// Batch Create Tasks request
BatchCreateTasksRequest batchCreateTasksRequest =
  BatchCreateTasksRequest.newBuilder()
      .setParent(parent)
      .addRequests(createDeliveryTaskRequest)
      .addRequests(createPickupTaskRequest)
      .build();

// Error handling
// If Fleet Engine does not have any task(s) with these task ID(s) and the
// credentials of the requestor pass, the service creates the task(s)
// successfully.

try {
  BatchCreateTasksResponse createdTasks = deliveryService.batchCreateTasks(
    batchCreateTasksRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case ALREADY_EXISTS:
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}
```

### REST

To create a delivery and a pickup task from a server environment, make an
HTTP REST call to `BatchCreateTasks`:

```bash
POST https://fleetengine.googleapis.com/v1/providers/<project_id>/batchCreate
```

*\<id\>* is a unique identifier for the task.

The request header must contain a field *Authorization* with the value
*Bearer \<token\>* , where *\<token\>* is issued by your server
according to the guidelines described in [Service account roles](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/service-accounts.md.txt) and
[JSON Web tokens](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/set-up-fleet/jwt.md.txt).

The request body must contain a `BatchCreateTasksRequest` entity.

Example `curl` command:

```bash
# Set $JWT, $PROJECT_ID, $DELIVERY_TRACKING_ID, $DELIVERY_TASK_ID,
# $PICKUP_TRACKING_ID, and $PICKUP_TASK_ID in the local environment
curl -X POST "https://fleetengine.googleapis.com/v1/providers/${PROJECT_ID}/tasks:batchCreate" \
 -H "Content-type: application/json" \
 -H "Authorization: Bearer ${JWT}" \
 --data-binary @- << EOM
{
 "requests" : [
   {
     "taskId": "${DELIVERY_TASK_ID}",
     "task" : {
       "type": "DELIVERY",
       "state": "OPEN",
       "trackingId": "${DELIVERY_TRACKING_ID}",
       "plannedLocation": {
         "point": {
             "latitude": -6.195139,
             "longitude": 106.820826
         }
       },
       "taskDuration": "90s"
     }
   },
   {
     "taskId": "${PICKUP_TASK_ID}",
     "task" : {
       "type": "PICKUP",
       "state": "OPEN",
       "trackingId": "${PICKUP_TRACKING_ID}",
       "plannedLocation": {
         "point": {
             "latitude": -6.195139,
             "longitude": 106.820826
         }
       },
       "taskDuration": "90s"
     }
   }
 ]
}
EOM
```

> [!WARNING]
> **Experimental:** As an experimental feature, the `LocationInfo` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#locationinfo) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt)) field now supports using `place` ([gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rpc/maps.fleetengine.delivery.v1.md.txt#maps.fleetengine.delivery.v1.LocationInfo.FIELDS.string.maps.fleetengine.delivery.v1.LocationInfo.place) or [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/tasks/rest/v1/LocationInfo.md.txt#FIELDS.place)), either alongside or instead of `LatLng`.

## What's next

- [Configure tasks](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/configure-tasks.md.txt)
- [Update tasks](https://developers.google.com/maps/documentation/mobility/fleet-engine/journeys/tasks/update-tasks.md.txt)