> [!NOTE]
> **Note:** **Before constructing a vehicle request** , read the requirements under [Vehicle requests](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles.md.txt#vehicle_requests) in the Introduction.

|---|---|---|
| This document covers important vehicle fields you can update when creating and managing vehicles. - `vehicle_state`: Determines the availability of the vehicle for new trips. - `vehicle_type`: Required field when creating a vehicle. The field can also serve as a filter criteria for vehicle matches. See [Create a vehicle](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/on-demand-create-vehicle.md.txt#required_fields_for_on-demand_trips) for details on setting this field. - `attributes[]`: An optional array of type [`VehicleAttribute`](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/trips/rpc/maps.fleetengine.v1.md.txt#vehicleattribute). Use them to define custom criteria to enhance filtering behavior when searching or listing vehicles. |   | For a complete list of vehicle fields, see: - [`Vehicle message`](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/trips/rpc/maps.fleetengine.v1.md.txt#vehicle) (gRPC) - [`Vehicle resource`](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/trips/rest/v1/providers.vehicles.md.txt) (REST) |

## Vehicle state field

Your system can set vehicle state to `OFFLINE` or `ONLINE`. For example, you
might set vehicle state to `ONLINE` every day at 9 AM and `OFFLINE` every day
at 5 PM.

| OFFLINE mode | ONLINE mode |
|---|---|
| Use `OFFLINE` to indicate that a vehicle is not accepting new trips. Note that the vehicle can still complete assigned trips while in this state. | - A `Vehicle` created in the `ONLINE` state may be immediately returned in response to `SearchVehicles` queries. See [Search vehicles](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/on-demand-search-vehicle.md.txt) for more details. - Vehicles created in the `ONLINE` state should use the `last_location` field in the `CreateVehicle` call. |

## Vehicle attributes field

Use the vehicle `attributes` field to create customized criteria to enable your
consumers or fleet operators to find vehicles in your fleet across a wider
variety of search criteria. This enhances the capabilities of your apps to
provide better vehicle matches over what you would from using search criteria
based solely on other vehicle fields. Each vehicle can have at most 100
attributes, and each one must have a unique key. Values can be strings,
booleans, or numbers.

For example, you could declare a custom attribute called *class* to
differentiate your rideshare vehicles across class levels. You'd use the
following string values to represent vehicle class levels: `ECONOMY`,
`STANDARD`, and `LUXURY`.

However, custom attribute values don't have to be mutually exclusive. You might
use criteria such as *pet-friendly* , *non-smoking* , and *able to take longer
trips* . Each of these could be a separate custom attribute that uses boolean
values. A given vehicle could be assigned all three of these custom attributes
along with the *class* custom attribute set to the appropriate string value.

Using attributes this way can provide you a wide variety of features useful to
finding vehicles for trips with specific needs. For instructions on how
to use custom attributes as query filters, see [Search vehicles](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/on-demand-search-vehicle.md.txt).

### Update vehicle attributes

You can update vehicle attributes using either `UpdateVehicle` or
`UpdateVehicleAttributes`. Each `attributes` key can only have one value **per
vehicle** . You declare custom vehicle attributes using the `attributes`
in the field mask, and then providing values based on the method below.

| `UpdateVehicle` |   | `UpdateVehicleAttributes` |
|---|---|---|
| This API does not allow updating only a single attribute. When using this method, any use of the `attributes` field in the field mask results in the **entire set** of vehicle attributes being re-declared for the vehicle. This results in an overwrite of any pre-existing attribute not explicitly included in the field mask. If you use this method to declare a new custom attribute, you must also re-declare every custom attribute you want the vehicle to retain. If you exclude the `attributes` in the field mask, then this method leaves existing custom attributes as previously defined for the vehicle. If you use `attributes` in the field mask, but without setting values, that is equivalent to removing all custom attributes from the vehicle. |   | This method accepts a **specific list** of attributes to update. The request updates or adds only those attributes specified in the field mask. Pre-existing attributes that are not specified remain unaltered. |

## Update vehicle fields example

This section shows how to update vehicle fields using `UpdateVehicleRequest`,
which includes an `update_mask` to indicate which fields to update. See the
Protocol Buffers documentation on [field masks](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/protobuf.dev/reference/cpp/api-docs/google.protobuf.util.field_mask_util) for details.

> [!NOTE]
> **Note:** The `update_mask` must always be set. Fleet Engine rejects requests with an empty `update_mask` field.

Updates to fields other than `last_location` require *Fleet Engine On-demand
Admin* privileges.

### Example: enable new trip type and custom attribute

This example enables `back_to_back` trips for the vehicle and also specifies a
new attribute: `class`. As noted in [Update vehicle attributes](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/on-demand-vehicle-fields.md.txt#update_vehicle_attributes) earlier,
updating the `attributes` field using this approach requires you to indicate all
custom attributes you want to retain. Therefore the example shows a `cash_only`
value written to preserve it from being overwritten during an update operation
that specifies the `attributes` field.

To update only the value of one key-value attribute pair, use the
`UpdateVehicleAttributes` method instead and don't include the `attribute` field
in the field mask for the `UpdateVehicle` request.

See the `providers.vehicles.update` reference for [gRPC](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/trips/rpc/maps.fleetengine.v1.md.txt#updatevehiclerequest) and [REST](https://developers.google.com/maps/documentation/mobility/fleet-engine/reference/trips/rest/v1/providers.vehicles/update.md.txt).

### gRPC

```java
static final String PROJECT_ID = "project-id";
static final String VEHICLE_ID = "vid-8241890";

VehicleServiceBlockingStub vehicleService = VehicleService.newBlockingStub(channel);

String vehicleName = "providers/" + PROJECT_ID + "/vehicles/" + VEHICLE_ID;
Vehicle updatedVehicle = Vehicle.newBuilder()
    .setVehicleState(VehicleState.ONLINE)
    .addAllAttributes(ImmutableList.of(
        VehicleAttribute.newBuilder().setKey("class").setValue("ECONOMY").build(),
        VehicleAttribute.newBuilder().setKey("cash_only").setValue("false").build()))
    .setBackToBackEnabled(true)
    .build();

UpdateVehicleRequest updateVehicleRequest = UpdateVehicleRequest.newBuilder()
    .setName(vehicleName)
    .setVehicle(updatedVehicle)
    .setUpdateMask(FieldMask.newBuilder()
        .addPaths("vehicle_state")
        .addPaths("attributes")
        .addPaths("back_to_back_enabled"))
    .build();

try {
  Vehicle updatedVehicle =
      vehicleService.updateVehicle(updateVehicleRequest);
} catch (StatusRuntimeException e) {
  Status s = e.getStatus();
  switch (s.getCode()) {
    case NOT_FOUND:
      // Most implementations will call CreateVehicle in this case
      break;
    case PERMISSION_DENIED:
      break;
  }
  return;
}
// If no Exception, Vehicle updated successfully.
```

### REST

```bash
curl -X PUT \
  "https://fleetengine.googleapis.com/v1/providers/project-id/vehicles/vid-8241890?updateMask=vehicle_state,attributes,back_to_back_enabled" \
  -H "Authorization: Bearer $JWT" \
  -H "Content-Type: application/json" \
  --data-binary @- << EOM
{
    "vehicleState": "ONLINE",
    "attributes": [
      {"key": "class", "value": "LUXURY"},
      {"key": "cash_only", "value": "false"}
    ],
    "backToBackEnabled": true
}
EOM
```

## What's next

- [Update a vehicle location](https://developers.google.com/maps/documentation/mobility/fleet-engine/essentials/vehicles/on-demand-update-vehicle.md.txt)