# Updating objects with the Public API

Every update in the Public API, a `PUT` or a `PATCH`, changes the object in place: it keeps its ID and everything that hangs off it. A field you leave out keeps its value, so a client sends only what changed.

## Change, keep or empty a field

| You send | The field |
|---|---|
| A value | takes the value |
| Nothing, or `null` | keeps its value |
| Its clear flag, such as `"clearDescription": true` | is emptied |
| A value and its clear flag together | is not changed: the request is refused with `400` and nothing changes |

A field that has no clear flag cannot be emptied by an update.

A list, such as `appIds` on a budget or a cost alert, is replaced whole: send every item it should hold. An empty list removes them all.

To return a budget from a saved cost report to the whole workspace:

```bash
curl --request PUT https://api.costfluent.com/v1/budgets/$BUDGET_ID \
  --header "Authorization: Bearer $COSTFLUENT_API_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{"clearCostReport": true}'
```

## Clear flags

| Object | Clear flags |
|---|---|
| Budget, `PUT /v1/budgets/{budgetId}` | `clearSegment`, `clearCostReport` |
| Cost alert, `PUT /v1/cost-alerts/{alertId}` | `clearComparisonPeriod`, `clearMinimumAmount`, `clearFilter` |
| Cost report, `PUT /v1/cost-reports/{costReportId}` | `clearFolder`, `clearFilter`, `clearStartDate`, `clearEndDate` |
| Folder, `PUT /v1/folders/{folderId}` | `clearParent` |
| Integration, `PUT /v1/providers/{providerId}` | `clearDescription`, `clearSettings` |
| Virtual tag, `PATCH /v1/virtual-tags/{virtualTagId}` | `clearDescription`, `clearDefaultValue` |

## How it behaves

- An update answers `200` with the object as stored, as reading it would, and a deletion answers `204` with no body. Setting a team member or a team's workspace access answers `204`, because it links two objects rather than holding one.
- Renaming an integration with `name` keeps its ID, its credentials and the costs it has already collected.
- A budget measures a segment, a saved cost report or the whole workspace. Naming `segmentId` or `costReportId` moves it there, and its clear flag returns it to the whole workspace.
- A segment always has an owner. Naming `teamId` replaces its team label, and naming `teamLabel` replaces its team.
- A cost report with a custom interval needs both dates, so clearing either is refused until the report uses another interval.
- An integration's `settings` are replaced whole when you send at least one; an empty map keeps them.
- The `saved-filter` operations of a dashboard and a folder are the one exception: there, `savedFilterId: null` detaches the saved filter.
- An allocation rule's update names its `name`, `filter` and `segmentId` every time, and a team, a team member and a team's workspace access are updated whole.
- A workspace's tag policy, `PUT /v1/workspaces/{workspaceId}/tag-policy`, is replaced whole: `rules` is required, and an empty list clears the policy.

:::note
Where reading an object answers with an `ETag`, send it back as `If-Match`, and the update is refused when someone changed the object since you read it. See [Data formats](/api/formats).
:::

## Related

- [Data formats](/api/formats)
- [Errors](/api/errors)
- [API reference](/api)
