# Properties and metadata (/properties-and-metadata)

Where an item keeps its content, its tags and an app's own data, and which to use for each kind of information.



An item's data lives in its properties, its tags and its extensions, and [edges](/edges) link it to other items. The four differ in who decides their shape and in whether a write to them moves the item's [version](/versions). Choosing the right one keeps an app from fighting the model:

| Kind | Holds | Shape set by | Moves the item's version |
| - | - | - | - |
| Properties | The item's content, such as `title` and `body` | The item's type | Yes |
| Tags | Labels, such as `favorite` | Nothing: a tag is a word | No |
| Extensions | An app's own data, under a namespace | The app that writes it | No |
| [Edges](/edges) | Links to other items, such as `about` | The edge type | No: each edge has its own version |

Tags and extensions together make up the item's **metadata record**, the `metadata` object Marfa answers beside the item. In this sense metadata means data about one item, not the metadata map that [Access](/access) describes.

## Properties [#properties]

Use a property when the information is part of what the item is, and every app reading the type should understand it: a task's due date, a bookmark's URL. The item's type declares its properties, as [Items and types](/items-and-types) explains.

An update sends only the properties it changes, and names the version it read:

```http title="Request"
PATCH /items/{id}
Content-Type: application/json

{ "version": 3, "properties": { "title": "Reading list" } }
```

The item comes back at version 4, with its other properties as they were. **A `null` removes nothing.** To remove a property, name it in `clear_properties`:

```http title="Request"
PATCH /items/{id}
Content-Type: application/json

{ "version": 4, "clear_properties": ["notes"] }
```

Naming a property the item doesn't hold isn't an error, so a retry is safe. Marfa refuses a name that's also in `properties`, and a property the type requires ([`items/update-clear`](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md#itemsupdate-clear)).

## Tags [#tags]

Use a tag when a person groups or marks items in their own way: `favorite`, `to-read`, `work`. A tag is a label with no schema and no hierarchy. An item's tags are a set, and a search matches them along with the item's text.

```http title="Request"
POST /items/{id}/tags
Content-Type: application/json

{ "tags": ["favorite"] }
```

A tag holds up to 128 characters and can't be empty, blank, or exactly `.` or `..`, and an item holds at most 100. **Every write that sets tags is held to these rules**, not only [Add tags](/api-reference/metadata/addItemTags), and Marfa refuses one that breaks them with `400 validation_error` ([`items/tag-text`](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md#itemstag-text), [`items/tag-dot-segment`](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md#itemstag-dot-segment), [`items/tags-count`](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md#itemstags-count)).

## Extensions [#extensions]

Use an extension when your app keeps something about an item that only it needs, especially on an item another app wrote: your place in an article a connector brought in.

An extension is a JSON object stored on an item under a namespace, such as `com.example.reader`. Whoever writes a namespace decides what goes in it, and one app's extension **stays out of another's way**: a key reads and writes only the namespaces its [extension map](/access#what-a-credential-reaches) names.

```http title="Request"
PUT /items/{id}/extensions/com.example.reader
Content-Type: application/json

{ "position": 0.42 }
```

Writing a tag or an extension still needs write access to the item's type.

The rules behind this page are in the [items](https://github.com/withmarfa/marfa/blob/main/conformance/spec/items.md) chapter of the contract.
