# Write an item

> Store a JSON document under a key. Creates the collection if it does not exist — with no indexes, which query then cannot use. Declare indexes with POST /v1/memory/collections first if you need them.

`PUT https://api.zavu.dev/v1/memory/collections/{collection}/items/{key}`

Store a JSON document under a key. Creates the collection if it does not exist — with **no indexes**, which `query` then cannot use. Declare indexes with `POST /v1/memory/collections` first if you need them.

This replaces the whole document; it does not merge. Pass `If-Match` with the revision from a previous read to make the write conditional.

## Parameters

- `collection` (path, string, required): Collection name.
- `key` (path, string, required): Item key. 1-255 chars from A-Z a-z 0-9 . _ : @ -
- `scope` (query, string): Which scope to address: `contact:<contactId>`, `conversation:<conversationId>`, or omitted for the project scope. Note the asymmetry with `POST /v1/memory` and `POST /v1/memory/search`, which take the scope in the request BODY as `scope` plus `contactId`/`conversationId`. Every other Memory endpoint takes it here.
- `If-Match` (header, string): Make the write conditional on the item's current revision, as returned by a previous read or write (plain `3` or ETag-quoted `"3"`). The write is refused with `409 revision_conflict` if the item moved on in between. Without it, the write always wins and silently overwrites a concurrent one.

## Body

- `value` (any, required): The document to store. Any JSON value, max 200KB serialized and 32 levels deep. This is a whole-document write, not a merge: it replaces whatever the key held.
- `ttlSeconds` (integer): Overrides the collection's `defaultTtlSeconds` for this item.

## Responses

### 200

Existing item replaced.

- `item` (object, required): One JSON document in a collection.
  - `key` (string, required)
  - `value` (any): The stored JSON. Any JSON value.
  - `rev` (integer, required): Revision, incremented on every write. Pass it as `If-Match` on a later write to make that write conditional.
  - `createdAt` (string<date-time>, required)
  - `updatedAt` (string<date-time>, required)
  - `expiresAt` (string<date-time>)

### 201

Item created.

- `item` (object, required): One JSON document in a collection.
  - `key` (string, required)
  - `value` (any): The stored JSON. Any JSON value.
  - `rev` (integer, required): Revision, incremented on every write. Pass it as `If-Match` on a later write to make that write conditional.
  - `createdAt` (string<date-time>, required)
  - `updatedAt` (string<date-time>, required)
  - `expiresAt` (string<date-time>)

### 400

Invalid key, scope, TTL, or `If-Match`.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 401

Unauthorized.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 409

`revision_conflict`: the item changed since the revision in `If-Match`. Re-read it and retry.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 413

`document_too_large`: the serialized value exceeds 200KB. Memory is not a blob store; put media in file storage and keep the URL here.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

### 429

The plan's monthly unit quota is spent.

- `code` (string, required)
- `message` (string, required)
- `details` (object)

## Example

```bash
curl -X PUT "https://api.zavu.dev/v1/memory/collections/collection_abc123/items/key_abc123" \
  -H "Authorization: Bearer $ZAVUDEV_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "value": {
    "status": "shipped",
    "total": 42.5
  }
}'
```

```typescript
import Zavudev from "@zavudev/sdk";

const zavu = new Zavudev({ apiKey: process.env.ZAVUDEV_API_KEY });

const result = await zavu.memory.collections.items.put("key_abc123", {
  collection: "collection_abc123",
  value: {
    status: "shipped",
    total: 42.5,
  },
});

console.log(result);
```
