Skip to main content

/memory

CRUD endpoints for storing and retrieving user/team-scoped memory entries on the LiteLLM proxy. Use these to persist conversation context, agent memory, team playbooks, or any key-value data scoped to users and teams.

Overview

FeatureSupportedNotes
Create memoryPOST /v1/memory
List memoriesGET /v1/memory with optional filtering
Get memory by keyGET /v1/memory/{key}
Upsert memoryPUT /v1/memory/{key}
Delete memoryDELETE /v1/memory/{key}
User-scoped accessEntries scoped to user_id
Team-scoped accessEntries scoped to team_id
JSON metadataArbitrary JSON metadata per entry
PaginationPage-based with configurable page size
Key prefix filteringRedis-style namespace scanning
Audit trailcreated_by, updated_by with timestamps
Supported LiteLLM Versionsv1.83.10+

Prerequisites

  • LiteLLM Proxy running with a PostgreSQL database connected
  • Database migrations applied (the LiteLLM_MemoryTable is created automatically)
  • Valid API key for authentication

No additional config.yaml entries required. Endpoints are available automatically once the proxy starts with a connected database.

Quick Start

Create a Memory Entry

Create memory
curl -X POST "http://localhost:4000/v1/memory" \
-H "Authorization: Bearer sk-1234" \
-H "Content-Type: application/json" \
-d '{
"key": "user:123:preferences",
"value": "Prefers concise responses. Timezone: PST.",
"metadata": {"tags": ["preferences", "user-settings"]}
}'

Response:

{
"memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"key": "user:123:preferences",
"value": "Prefers concise responses. Timezone: PST.",
"metadata": {"tags": ["preferences", "user-settings"]},
"user_id": "user-123",
"team_id": "team-abc",
"created_at": "2025-04-21T12:00:00Z",
"created_by": "user-123",
"updated_at": "2025-04-21T12:00:00Z",
"updated_by": "user-123"
}

List Memories

List all memories
curl "http://localhost:4000/v1/memory" \
-H "Authorization: Bearer sk-1234"
Filter by key prefix
curl "http://localhost:4000/v1/memory?key_prefix=user:123:" \
-H "Authorization: Bearer sk-1234"
Paginate results
curl "http://localhost:4000/v1/memory?page=2&page_size=10" \
-H "Authorization: Bearer sk-1234"

Response:

{
"memories": [
{
"memory_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"key": "user:123:preferences",
"value": "Prefers concise responses. Timezone: PST.",
"metadata": {"tags": ["preferences", "user-settings"]},
"user_id": "user-123",
"team_id": "team-abc",
"created_at": "2025-04-21T12:00:00Z",
"created_by": "user-123",
"updated_at": "2025-04-21T12:00:00Z",
"updated_by": "user-123"
}
],
"total": 1
}

Get a Memory by Key

Get memory by key
curl "http://localhost:4000/v1/memory/user:123:preferences" \
-H "Authorization: Bearer sk-1234"

Update (Upsert) a Memory

If the key exists, updates it. If not, creates a new entry.

Upsert memory
curl -X PUT "http://localhost:4000/v1/memory/user:123:preferences" \
-H "Authorization: Bearer sk-1234" \
-H "Content-Type: application/json" \
-d '{
"value": "Prefers concise responses. Timezone: EST. Language: English.",
"metadata": {"tags": ["preferences", "user-settings"], "version": 2}
}'

Delete a Memory

Delete memory
curl -X DELETE "http://localhost:4000/v1/memory/user:123:preferences" \
-H "Authorization: Bearer sk-1234"

Response:

{
"key": "user:123:preferences",
"deleted": true
}

API Reference

POST /v1/memory

Create a new memory entry.

Request Body:

ParameterTypeRequiredDescription
keystringGlobally unique key. Use namespaced keys (e.g., user:123:notes).
valuestringMemory content. Typically markdown or plain text.
metadataany (JSON)Optional JSON metadata (dicts, lists, scalars).
user_idstringScope to a user. Defaults to caller's user_id. Admin-only override.
team_idstringScope to a team. Defaults to caller's team_id. Admin-only override.

Response: 201 — Returns the created LiteLLM_MemoryRow.


GET /v1/memory

List memory entries visible to the caller.

Query Parameters:

ParameterTypeDefaultDescription
keystringFilter by exact key match.
key_prefixstringFilter by key prefix (e.g., user:123:). Takes precedence over key.
pageint1Page number (1-indexed).
page_sizeint50Items per page (max 500).

Response: 200 — Returns MemoryListResponse with memories array and total count.


GET /v1/memory/{key}

Get a single memory entry by key.

Path Parameters:

ParameterTypeDescription
keystringThe memory key to retrieve.

Response: 200 — Returns the LiteLLM_MemoryRow.


PUT /v1/memory/{key}

Upsert a memory entry. Creates the entry if the key doesn't exist; updates it if it does.

Path Parameters:

ParameterTypeDescription
keystringThe memory key to create or update.

Request Body:

ParameterTypeRequiredDescription
valuestring✅ (on create)Memory content. Required when creating, optional when updating.
metadataany (JSON)Updated metadata. Omit to preserve existing value. Set to null to clear.
user_idstringOnly used on create. Admin-only override.
team_idstringOnly used on create. Admin-only override.

Response: 200 — Returns the created/updated LiteLLM_MemoryRow.


DELETE /v1/memory/{key}

Delete a memory entry by key.

Path Parameters:

ParameterTypeDescription
keystringThe memory key to delete.

Response: 200 — Returns {"key": "...", "deleted": true}.

Response Object

All endpoints that return a memory entry use this schema:

{
"memory_id": "string (UUID)",
"key": "string",
"value": "string",
"metadata": "any (JSON) or null",
"user_id": "string or null",
"team_id": "string or null",
"created_at": "datetime",
"created_by": "string",
"updated_at": "datetime",
"updated_by": "string"
}

Access Control

Memory entries are scoped by user_id and team_id, with role-based visibility and write access.

Visibility (Read)

RoleCan See
Proxy AdminAll memory entries
Regular UserEntries where user_id matches their own OR team_id matches their own

Write Access (Update / Delete)

ScenarioWho Can Write
Entry has user_id matching callerOwner can update/delete
Entry is team-scoped only (no user_id)Team admins and org admins only
Any entryProxy admins
info

Team members can read team-scoped entries but only team admins can modify or delete them. This prevents teammates from overwriting each other's entries.

Scoping on Create

  • user_id and team_id default to the caller's identity from their API key
  • Proxy admins can override user_id / team_id to create entries for other users or teams
  • Non-admin callers cannot create entries without at least one of user_id or team_id

Key Naming Conventions

Keys are globally unique. Use namespaced keys to organize entries:

user:{user_id}:preferences      # User preferences
user:{user_id}:context # Conversation context
team:{team_id}:playbook # Team playbook
agent:{agent_id}:memory # Agent memory
project:{project_id}:config # Project configuration

Use key_prefix in the list endpoint to scan all entries in a namespace:

# Get all entries for a user
curl "http://localhost:4000/v1/memory?key_prefix=user:123:" \
-H "Authorization: Bearer sk-1234"

Error Codes

Status CodeMeaning
200Success (GET, PUT, DELETE)
201Created (POST)
400Invalid input (missing required fields, empty PUT body, orphan row)
403Permission denied (write access violation, scope override by non-admin)
404Key not found or not visible to caller
409Duplicate key on creation
500Internal server error (database issues)