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

# Documents

> Records with filterable attributes and the state judgments are made about.

A document is a record with an `id`, flat filterable `attributes`, and `state`: the JSON content that judgments are made about.

```json theme={null}
{
  "id": "t_123",
  "revision": 42,
  "incarnation": 7,
  "attributes": {"plan": "pro", "region": "eu", "tags": ["vip"]},
  "state": {"subject": "...", "body": "...", "messages": [{"role": "customer", "text": "..."}]},
  "created_at": "2026-09-01T09:00:00Z",
  "updated_at": "2026-09-23T12:00:00Z"
}
```

* **`attributes`** is a flat map of strings, numbers, booleans, string arrays and nulls, at most 64 keys. Attributes are filterable and sortable. They are never sent to an engine unless a judgment's context recipe names them.
* **`state`** is any JSON object up to 1 MB. It is never filterable.
* **`revision`** increases every time the document changes. It is the namespace's sequence number at the change, so it is monotonic but not contiguous.
* **`incarnation`** is the sequence at which the document was created. Deleting a document and writing the same id again starts a new incarnation with no answers and no history.
* **`created_at`** is when the document was created: the time of the write that created it, or the `created_at` that write gave, such as a record's original creation time when you [import existing data](/guides/import-existing-data). A given `created_at` may be at most 5 minutes in the future. A later write never changes it; a new incarnation gets a new one. [Relations](/concepts/relations) read related documents newest created first.

## Writing

`POST /namespaces/{ns}` takes up to 1,000 documents or 64 MB, and applies its operations in this order: `upsert`, `patch`, `append`, `delete`. They commit atomically, and a request is never split across two commits.

| Operation | Effect                                                                                                                                                                                                                                          |
| --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `upsert`  | Replaces the whole document. An optional `created_at` sets its creation time if this write creates it.                                                                                                                                          |
| `patch`   | Merges the top-level keys of `attributes` and `state`. A key set to `null` is removed. Patching a missing document creates it, and an optional `created_at` sets its creation time then.                                                        |
| `append`  | Pushes `values` onto the array at `path` inside `state`, creating it if needed. An element identical to one of the array's last 64 is skipped, so retries are safe. To append two identical elements on purpose, give each a unique `id` field. |
| `delete`  | Removes the document. Its answers and evaluations stay in history until the namespace is deleted.                                                                                                                                               |

Every write is idempotent by construction, so retrying a request is always safe. A write returns once its batch is durable in object storage, in roughly 80 to 150 ms. With `wait_for`, it also waits until the named judgments have answers for this revision, up to `wait_timeout_ms`: 5,000 by default, and a value above 10,000 is lowered to 10,000. An empty `wait_for` is the same as leaving it out. On timeout the write is still committed, and those answers come back `pending`, which here means only that they were not ready within the wait. A large write waits on its first 16 documents at interactive priority; the rest are judged with ordinary catch-up and usually come back `pending`. A get works [freshness](/concepts/freshness) out from the stored answer instead, so the same answer can read `unavailable` there if the document was never judged in its current incarnation, or `stale` under a policy that will not judge the new revision on its own.

Writes to one document are applied in the order they commit, so concurrent `patch` and `append` writes from different clients all stand. If a server fails, a write caught while another takes over is refused with `rate_limited`; retry it, as the SDKs do. See [system behavior](/behavior#your-data).

## Reading

`GET /namespaces/{ns}/documents/{id}` returns the document with its answers. Add `include=history` for its evaluations, newest first, and `include=history,context,raw` for the compiled context and raw engine response of each. `POST /namespaces/{ns}/query` filters, ranks and pages. See [answers](/concepts/answers#querying-answers).
