> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kirafin.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Metadata

> The key-value object several resources carry for information the resource itself does not model.

Several resources carry a `metadata` object. It holds additional information about that resource as key-value string pairs, stored as you send them and returned unchanged.

Users, virtual accounts, recipients and payouts each have one, and the rules below are the same on all of them.

## The limits

| Rule                            | Limit                |
| ------------------------------- | -------------------- |
| Keys per resource               | 50                   |
| Key length                      | 1 to 40 characters   |
| Characters not allowed in a key | `[` and `]`          |
| Value length                    | Up to 500 characters |
| Value type                      | String only          |

<Warning>
  **The 50-key limit is checked after the merge, not on what you send.** A resource already carrying 30 keys, patched with 30 more, is 60 keys and the call fails with a `400` — even though neither the stored object nor your patch broke the limit on its own.
</Warning>

A value must be a string. Numbers, booleans and nested objects are rejected — send `"42"`, not `42`.

## Updating it

Where metadata can be changed after creation, the update is a patch, not a replacement. A user takes one on Update a user, and a virtual account takes one on its own patch calls. On a recipient and a payout, metadata is set when you create the resource and not changed afterwards.

The patch rules are the same wherever it is accepted:

* **A key with a value** — sets that key, leaving the others alone.
* **A key with an empty string** — deletes that key.
* **`{}`** — clears every key.

```json theme={null}
{ "metadata": { "order_id": "A-17", "old_ref": "" } }
```

That call sets `order_id`, deletes `old_ref`, and leaves every other key in place. The 50-key limit is checked on the result, not on the patch.

<Note>
  Empty-string values are delete markers, so they never reach storage. A key you set to `""` is gone from the next response, not present-and-empty.
</Note>

## Filtering a listing by it

The four list endpoints that return metadata also filter on it, using bracket syntax:

```
?metadata[order_id]=A-17&metadata[region]=eu
```

A resource matches only if it carries **every** pair you send, with exactly those values — no partial match, no wildcard. Filter keys follow the same rules as stored keys, and `total` counts the matches, not the collection.
