Batch memory mutations
Queue durable updates or deletes for up to 1,000 memories with explicit per-item results.
FishMem batch mutations are durable asynchronous operations. They validate the whole request, persist one operation, and process bounded chunks through the same task worker used by other long-running work.
Batch update
PUT /v1/memories/batch
curl -X PUT https://fishmem.com/v1/memories/batch \
-H "Authorization: Bearer fm_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: customer-refresh-2026-07-30" \
-d '{
"memories": [
{
"memory_id": "mem_1",
"content": "Customer uses the Pro plan.",
"version": "2026-07-30T00:00:00.000Z"
},
{
"memory_id": "mem_2",
"metadata": {"source": "crm"}
}
]
}'Each item accepts the same mutable fields as
PUT /v1/memories/{id}: content, metadata,
importance, memory_type, and optional optimistic version. At least one
mutable field is required.
Batch delete
DELETE /v1/memories/batch
curl -X DELETE https://fishmem.com/v1/memories/batch \
-H "Authorization: Bearer fm_..." \
-H "Content-Type: application/json" \
-H "Idempotency-Key: remove-import-42" \
-d '{
"memories": [
{"memory_id": "mem_1"},
{"memory_id": "mem_2"}
]
}'Request limits
memoriesmust contain 1–1,000 items.- Every
memory_idmust be unique within the request. - The encoded request must be at most 750,000 UTF-8 bytes.
Idempotency-Keyis required and must contain 1–200 characters.
The byte limit keeps the durable task row below the strictest supported runtime's row-size boundary. Split larger payloads into several independently identifiable batches.
Accepted operation
Both endpoints return HTTP 202 with an operation:
{
"id": "task_...",
"kind": "batch_update",
"status": "pending",
"attempts": 0,
"max_attempts": 5,
"error": null,
"next_attempt_at": "2026-07-30T00:00:00.000Z",
"result": null,
"created_at": "2026-07-30T00:00:00.000Z",
"updated_at": "2026-07-30T00:00:00.000Z"
}Poll GET /v1/operations/{id}. A completed task
returns explicit per-item results:
{
"id": "task_...",
"kind": "batch_update",
"status": "success",
"result": {
"total": 2,
"processed": 2,
"succeeded": 1,
"failed": 1,
"items": [
{
"memory_id": "mem_1",
"status": "succeeded",
"event": "UPDATE"
},
{
"memory_id": "missing",
"status": "failed",
"error": {
"code": "MEMORY_NOT_FOUND",
"message": "Memory not found"
}
}
]
}
}Failure and retry semantics
Batch mutations are not falsely described as an all-or-nothing transaction: canonical storage and vector projections cross different durable systems. Validation happens before enqueue. During execution, permanent item errors such as not-found and version conflicts are recorded on that item and processing continues. Infrastructure failures retry the current chunk; already completed items replay through deterministic child idempotency keys.
Reusing the parent key with the exact request returns the same operation.
Reusing it with different items returns 409 IDEMPOTENCY_CONFLICT.
Credits
Batch update and delete are free. They still appear in request and operation observability.