---
updatedAt: 2026-04-21T00:11:16.000Z
agentTools:
  projectIndex: https://docs.onfleet.com/llms.txt
---

# Working with metadata

## The metadata object

Every entry in the `metadata` array must adhere to the following structure:

<Table align={["left","left","left"]}>
  <thead>
    <tr>
      <th style={{ textAlign: "left" }}>
        Name
      </th>

      <th style={{ textAlign: "left" }}>
        Type
      </th>

      <th style={{ textAlign: "left" }}>
        Description
      </th>
    </tr>
  </thead>

  <tbody>
    <tr>
      <td style={{ textAlign: "left" }}>
        name
      </td>

      <td style={{ textAlign: "left" }}>
        string
      </td>

      <td style={{ textAlign: "left" }}>
        The name of the property.
      </td>
    </tr>

    <tr>
      <td style={{ textAlign: "left" }}>
        type
      </td>

      <td style={{ textAlign: "left" }}>
        string
      </td>

      <td style={{ textAlign: "left" }}>
        The type of the property. Must be one of `[ "boolean", "number", "string", "object", "array" ]`.
      </td>
    </tr>

    <tr>
      <td style={{ textAlign: "left" }}>
        subtype
      </td>

      <td style={{ textAlign: "left" }}>
        string
      </td>

      <td style={{ textAlign: "left" }}>
        Required only for entries of type `array`, used for future visualization purposes. Must be one of `[ "boolean", "number", "string", "object" ]`.
      </td>
    </tr>

    <tr>
      <td style={{ textAlign: "left" }}>
        visibility
      </td>

      <td style={{ textAlign: "left" }}>
        array of strings
      </td>

      <td style={{ textAlign: "left" }}>
        Whether the metadata object should be visible to the `api`, the `dashboard`, and/or `worker`. Defaults to `[ "api" ]`.
      </td>
    </tr>

    <tr>
      <td style={{ textAlign: "left" }}>
        value
      </td>

      <td style={{ textAlign: "left" }}>
        * <br />
      </td>

      <td style={{ textAlign: "left" }}>
        The value of the property. The JSON type must match the type (and subtype) provided for the entry.
      </td>
    </tr>
  </tbody>
</Table>

### Examples

> 👍 Valid Metadata Examples
>
> These valid metadata entries show the different types available:

```json Valid Metadata: Boolean Type
{
    "name": "isOnfleetTrained",
    "type": "boolean",
    "value": true
}
```
```json Valid Metadata: Number Type
{
    "name": "hourlyRate",
    "type": "number",
    "value": 27.33
}
```
```json Valid Metadata: String Type
{
    "name": "hometown",
    "type": "string",
    "value": "Tiburon, CA"
}
```
```json Valid Metadata: Object Type
{
    "name": "load",
    "type": "object",
    "value": {
	      "ambient": {
		        "artichokes": 18,
            "strawberries": 23
        },
	      "cold": {
		        "strawberries": 52
	      },
	      "hot": {
            "apple-pie": 5
    	  }
    }
}
```
```json Valid Metadata: Array Type
{
    "name": "paymentOptions",
    "type": "array",
    "subtype": "string",
    "value": [
        "visa",
        "mc",
        "amex",
        "btc"
    ]
}
```

> ❗️ Invalid Metadata Examples
>
> The following metadata entries are invalid.

```json
{
    "name": "lifetimeValue",
    "type": "number",
    "value": "3827.4"
}
```

**Reason: value is expected as a number, however a string was provided.**

```json
{
    "name": "preferredDropoffLocations",
    "type": "array",
    "subtype": "string",
    "value": [
        "-122.42271423339842,37.7897092979573",
        "-122.46803283691405,37.76040136229719",
        -122.41550445556639,
        37.76420119453823
    ]
}
```

**Reason: string subtype expects all array members to be of type string, however both string and number members were provided.**

## Working with metadata

The following entity operations are available.

### Creating metadata

You can add metadata to a new entity by providing it at creation.

```curl Recipient Request 
$ curl -X POST "https://onfleet.com/api/v2/recipients" \
     -u "<your_api_key>:" \
     -d '{
       "name": "Saul Goodman",
       "phone": "505-374-2733",
       "notes": "Change for $100 always required.",
       "metadata": [
         {
           "name": "isHighNetWorth",
           "type": "boolean",
           "value": false
         },
         {
           "name": "otherCustomerConnections",
           "type": "array",
           "subtype": "string",
           "value": [
             "walt-4864619e",
             "tuco-b7ec089b",
             "mike-6df58fee"
           ]
         }
       ]
     }'
```
```curl Task Request
$ curl -X POST "https://onfleet.com/api/v2/tasks" \
  -u "YOUR_API_KEY:" \
  -d '{
    "destination": {
      "address": {
        "unparsed": "543 Howard St, SF, CA, USA"
      }
    },
    "recipients": [],
    "metadata": [
      {
        "name": "order_id",
        "type": "string",
        "value": "ORD-88291",
        "visibility": ["api", "dashboard"]
      },
      {
        "name": "age_verified",
        "type": "boolean",
        "value": true,
        "visibility": ["api"]
      },
      {
        "name": "item_count",
        "type": "number",
        "value": 4,
        "visibility": ["api", "dashboard"]
      }
    ]
  }'
```

```json Recipient Response
{
  "id": "KepP1xpV5Lmxkm2P3PYVddcz",
  // ...
  "metadata": [
    {
      "name": "isHighNetWorth",
      "type": "boolean",
      "value": false,
      "visibility": [
        "api"
      ]
    },
    {
      "name": "otherCustomerConnections",
      "type": "array",
      "subtype": "string",
      "value": [
        "walt-4864619e",
        "tuco-b7ec089b",
        "mike-6df58fee"
      ],
      "visibility": [
        "api"
      ]
    }
  ]
}
```
```json Task Response
{
    "id": "D~TU2BtWMzLWJlY2Q7Ge4zIx",
     // ...
    "metadata": [
        {
            "type": "string",
            "visibility": [
                "api",
                "dashboard"
            ],
            "value": "ORD-88291",
            "name": "order_id"
        },
        {
            "type": "boolean",
            "visibility": [
                "api"
            ],
            "value": true,
            "name": "age_verified"
        },
        {
            "type": "number",
            "visibility": [
                "api",
                "dashboard"
            ],
            "value": 4,
            "name": "item_count"
        }
    ],
      // ...
}
```

You can also add metadata to an existing entity by updating it directly. This replaces any metadata previously set on the entity.

```curl Request
$ curl -X PUT "https://onfleet.com/api/v2/workers/h*wSb*apKlDkUFnuLTtjPke7" \
     -u "<your_api_key>:" \
     -d '{
       "metadata": [
         {
           "name": "nickname",
           "type": "string",
           "value": "Puffy"
         },
         {
           "name": "otherDetails",
           "type": "object",
           "value": {
             "availability": {
               "mon": "10:00",
               "wed": "13:30",
               "sat": "16:20"
             },
             "trunkSize": 9.5,
             "premiumInsurance": false
           }
         }
       ]
     }'
```

```json Response
{
  "id": "h*wSb*apKlDkUFnuLTtjPke7",
  // ...
  "metadata": [
    {
      "name": "nickname",
      "type": "string",
      "value": "Puffy",
      "visibility": [
        "api"
      ]
    },
    {
      "name": "otherDetails",
      "type": "object",
      "value": {
        "availability": {
          "mon": "10:00",
          "sat": "16:20",
          "wed": "13:30"
        },
        "premiumInsurance": false,
        "trunkSize": 9.5
      },
      "visibility": [
        "api"
      ]
    }
  ]
  // ...
}
```

### Updating metadata

You can update existing metadata for entities by using the `$set` and `$pop` commands.

#### $set

The upsert-like `$set` command updates existing metadata properties (based on an exact, case-sensitive `name` match) if they exist or creates them otherwise.

Here is an example of an administrator entity before a `$set` request:

```json
{
  "id": "EJmsbJgHiRLPjNVE7GEIPs7*",
  // ...
  "metadata": [
    {
      "name": "supportRequestsHandled",
      "type": "number",
      "value": 281,
      "visibility": [
        "api"
      ]
    },
    {
      "name": "languages",
      "type": "array",
      "subtype": "string",
      "value": [
        "en",
        "ar",
        "ru"
      ],
      "visibility": [
        "api"
      ]
    }
  ]
}
```

Request

```curl Request
$ curl -X PUT "https://onfleet.com/api/v2/admins/EJmsbJgHiRLPjNVE7GEIPs7*" \
     -u "<your_api_key>:" \
     -d '{"metadata":{"$set":[{"name":"supportRequestsHandled","type":"number","value":331},{"name":"isHighPerformer","type":"boolean","value":true}]}}'
```

```json Response
{
  "id": "EJmsbJgHiRLPjNVE7GEIPs7*",
  // ...
  "metadata": [
    {
      "name": "supportRequestsHandled",
      "type": "number",
      "value": 331,
      "visibility": [
        "api"
      ]
    },
    {
      "name": "languages",
      "type": "array",
      "subtype": "string",
      "value": [
        "en",
        "ar",
        "ru"
      ],
      "visibility": [
        "api"
      ]
    },
    {
      "name": "isHighPerformer",
      "type": "boolean",
      "value": true,
      "visibility": [
        "api"
      ]
    }
  ]
}
```

<br />

The example below adds a new `delivery_preferences` field to a task while retaining all existing entries.

```curl Curl
curl -X PUT "https://onfleet.com/api/v2/tasks/l6AA3a7COZvLs316QIsqMfWe" \
  -u "YOUR_API_KEY:" \
  -d '{
    "metadata": [
  {
    "name": "order_id",
    "type": "string",
    "value": "ORD-88291",
    "visibility": ["api", "dashboard"]
  },
  {
    "name": "age_verified",
    "type": "boolean",
    "value": true,
    "visibility": ["api"]
  },
  {
    "name": "item_count",
    "type": "number",
    "value": 4,
    "visibility": ["api", "dashboard"]
  },
  {
    "name": "delivery_preferences",
    "type": "object",
    "value": {
      "leave_at_door": true,
      "contact_on_arrival": false
    },
    "visibility": ["api"]
  }
]
}'
```

Response

```python JSON
{
    "id": "l6AA3a7COZvLs316QIsqMfWe",
  // ...
    "metadata": [
        {
            "type": "string",
            "visibility": [
                "api",
                "dashboard"
            ],
            "value": "ORD-88291",
            "name": "order_id"
        },
        {
            "type": "boolean",
            "visibility": [
                "api"
            ],
            "value": true,
            "name": "age_verified"
        },
        {
            "type": "number",
            "visibility": [
                "api",
                "dashboard"
            ],
            "value": 4,
            "name": "item_count"
        },
        {
            "type": "object",
            "visibility": [
                "api"
            ],
            "value": {
                "contact_on_arrival": false,
                "leave_at_door": true
            },
            "name": "delivery_preferences"
        }
    ],
    // ...
}
```

The example below adds a new `New_Location` field to a team.

```Text Curl
curl -X PUT "https://onfleet.com/api/v2/teams/9PVeSqj*RxI46~aD*M812DkY" \
  -u "YOUR_API_KEY:" \
  -d ' {
    "metadata": {
        "$set":[
            {
                "name":"New_Location",
                "type":"boolean",
                "value":true
            }
        ]
    }
}'
```

Response

```python JSON
{
    "id": "9PVeSqj*RxI46~aD*M812DkY",
    "timeCreated": 1740590327000,
    "timeLastModified": 1774189583099,
    "name": "Team Kitchener",
    "workers": [
        "mQpa~QD~LYcG89bPdig8sREj",
        "sLB6mGxkXylco27jnJ0Ca2CF",
        "mM*PRrLDRSCzC~V6xNHiYS3~"
    ],
    "managers": [],
    "metadata": [
        {
            "type": "boolean",
            "visibility": [
                "api"
            ],
            "value": true,
            "name": "New_Location"
        }
    ],
    "hub": "NqP2A0*flulajomC~If3bnxD",
    "enableSelfAssignment": true
}
```

<br />

#### $pop

The `$pop` command allows for the removal of one or more metadata entries for a given entity.

Here is an example of a task entity before a `$pop` request:

```json
{
  "id": "LDJXqd2HEoGVhgmjxOawxgjF",
  // ...
  "metadata": [
    {
      "name": "customerId",
      "type": "string",
      "value": "4ef29b3e84eba9f2",
      "visibility": [
        "api"
      ]
    },
    {
      "name": "isDisenfranchised",
      "type": "boolean",
      "value": true,
      "visibility": [
        "api"
      ]
    }
  ]
}
```

> **Request**

```curl Request
$ curl -X PUT "https://onfleet.com/api/v2/tasks/LDJXqd2HEoGVhgmjxOawxgjF" \
     -u "<your_api_key>:" \
     -d '{"metadata":{"$pop":[{"name":"isDisenfranchised"}]}}'
```

```json Response
{
  "id": "LDJXqd2HEoGVhgmjxOawxgjF",
  // ...
  "metadata": [
    {
      "name": "customerId",
      "type": "string",
      "value": "4ef29b3e84eba9f2",
      "visibility": [
        "api"
      ]
    }
  ]
}
```

If you wish to fully remove an entity’s metadata, you may update the entity via PUT and simply provide an empty `metadata` array.

To remove a field, fetch the entity, filter out the entry, and PUT the remaining array back. The example below removes `delivery_preferences` from a task.

Example

```javascript curl
curl -X PUT "https://onfleet.com/api/v2/tasks/kc5SA4k8YkMYMQMQMkMQM" \
  -u "YOUR_API_KEY:" \
  -H "Content-Type: application/json" \
  -d '{
    "metadata": [
      {
        "name": "order_id",
        "type": "string",
        "value": "ORD-88291",
        "visibility": ["api", "dashboard"]
      },
      {
        "name": "age_verified",
        "type": "boolean",
        "value": true,
        "visibility": ["api"]
      },
      {
        "name": "item_count",
        "type": "number",
        "value": 4,
        "visibility": ["api", "dashboard"]
      }
    ]
  }'
```
```javascript JS
const auth = "Basic " + btoa("YOUR_API_KEY:");
const taskId = "kc5SA4k8YkMYMQMQMkMQM";

// Step 1: Fetch existing task
const getRes = await fetch(`https://onfleet.com/api/v2/tasks/${taskId}`, {
  headers: { "Authorization": auth }
});
const task = await getRes.json();

// Step 2: Filter out the field to remove
const filtered = task.metadata.filter(e => e.name !== "synced_to_crm");

// Step 3: PUT the remaining array back
const putRes = await fetch(`https://onfleet.com/api/v2/tasks/${taskId}`, {
  method: "PUT",
  headers: { "Authorization": auth, "Content-Type": "application/json" },
  body: JSON.stringify({ metadata: filtered })
});
const data = await putRes.json();
console.log(data);
```
```python python
import requests, base64, json

credentials = base64.b64encode(b"YOUR_API_KEY:").decode("utf-8")
headers = {"Authorization": f"Basic {credentials}", "Content-Type": "application/json"}
task_id = "kc5SA4k8YkMYMQMQMkMQM"

# Step 1: Fetch existing task
task = requests.get(
    f"https://onfleet.com/api/v2/tasks/{task_id}",
    headers=headers
).json()

# Step 2: Filter out the field to remove
filtered = [e for e in task["metadata"] if e["name"] != "synced_to_crm"]

# Step 3: PUT the remaining array back
response = requests.put(
    f"https://onfleet.com/api/v2/tasks/{task_id}",
    headers=headers,
    data=json.dumps({"metadata": filtered})
)
print(response.json())
```
```php php
<?php
$taskId = "kc5SA4k8YkMYMQMQMkMQM";
$auth = "YOUR_API_KEY:";

// Step 1: Fetch existing task
$ch = curl_init("https://onfleet.com/api/v2/tasks/{$taskId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_USERPWD, $auth);
$task = json_decode(curl_exec($ch), true);
curl_close($ch);

// Step 2: Filter out the field to remove
$filtered = array_values(array_filter(
    $task["metadata"],
    fn($e) => $e["name"] !== "synced_to_crm"
));

// Step 3: PUT the remaining array back
$payload = json_encode(["metadata" => $filtered]);
$ch = curl_init("https://onfleet.com/api/v2/tasks/{$taskId}");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
curl_setopt($ch, CURLOPT_USERPWD, $auth);
curl_setopt($ch, CURLOPT_HTTPHEADER, ["Content-Type: application/json"]);

$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
```

**Response**

```json
{
  "id": "kc5SA4k8YkMYMQMQMkMQM",
  "shortId": "8f983639",
  "metadata": [
    {
      "name": "order_id",
      "type": "string",
      "value": "ORD-88291",
      "visibility": ["api", "dashboard"]
    },
    {
      "name": "age_verified",
      "type": "boolean",
      "value": true,
      "visibility": ["api"]
    },
    {
      "name": "item_count",
      "type": "number",
      "value": 4,
      "visibility": ["api", "dashboard"]
    }
  ]
}
```

> ℹ️ **Updating metadata**\
> Note that metadata can also be updated via the Update endpoint for each supported Entity.
>
> While metadata can be updated during any state of a Task, we strongly recommend keeping a record of the response when executing that API request.