Skip to main content
{
  "user_id": "bob_456",
  "metadata": {
    "name": "Bob Smith",
    "email": "bob@example.com",
    "plan": "premium",
    "signup_date": "2024-01-15"
  },
  "created_at": "2024-01-15T10:30:00Z",
  "last_active_at": "2024-01-15T10:30:00Z"
}

Overview

Users are the core entity in RecallrAI. Each user represents an individual whose context, memories, and conversations you want to track. Every session, memory, and merge conflict is associated with a specific user.

User Object

user_id
string
required
Unique identifier for the user. This should match IDs from your application (e.g., database IDs, auth provider IDs).
metadata
object
Custom metadata object to store additional information about the user (e.g., name, email, preferences).
created_at
timestamp
ISO 8601 timestamp of when the user was created.
last_active_at
timestamp
ISO 8601 timestamp of the user’s last activity.

Creating a User

Create a new user to start tracking their context and memories.
from recallrai import RecallrAI

client = RecallrAI(
    api_key="rai_your_api_key",
    project_id="your_project_id"
)

# Create a user with just an ID
user = client.create_user("alice_123")

# Create a user with metadata
user = client.create_user(
    user_id="bob_456",
    metadata={
        "name": "Bob Smith",
        "email": "bob@example.com",
        "plan": "premium",
        "signup_date": "2024-01-15"
    }
)

print(f"Created user: {user.user_id}")
print(f"Metadata: {user.metadata}")
{
  "user_id": "bob_456",
  "metadata": {
    "name": "Bob Smith",
    "email": "bob@example.com",
    "plan": "premium",
    "signup_date": "2024-01-15"
  },
  "created_at": "2024-01-15T10:30:00Z",
  "last_active_at": "2024-01-15T10:30:00Z"
}
If a user with the same user_id already exists, this operation will raise a UserAlreadyExistsError (409 status code).

Retrieving a User

Get an existing user by their ID.
# Get a user
user = client.get_user("alice_123")

print(f"User ID: {user.user_id}")
print(f"Created: {user.created_at}")
print(f"Last active: {user.last_active_at}")
print(f"Metadata: {user.metadata}")
{
  "user_id": "alice_123",
  "metadata": {
    "name": "Alice Johnson",
    "email": "alice@example.com"
  },
  "created_at": "2024-01-10T08:00:00Z",
  "last_active_at": "2024-01-15T14:25:00Z"
}
If the user doesn’t exist, a UserNotFoundError (404 status code) will be raised.

Listing Users

List all users in your project with pagination.
# List users with pagination
users = client.list_users(
    offset=0,
    limit=20
)

print(f"Total users: {users.total}")
print(f"Retrieved: {len(users.users)} users")

for user in users.users:
    print(f"- {user.user_id} (active: {user.last_active_at})")

# Get next page
if users.has_more():
    next_users = client.list_users(
        offset=users.next_offset(),
        limit=20
    )
offset
integer
default:"0"
Number of users to skip (for pagination).
limit
integer
default:"10"
Maximum number of users to return (1-100).
{
  "users": [
    {
      "user_id": "alice_123",
      "metadata": {"name": "Alice"},
      "created_at": "2024-01-10T08:00:00Z",
      "last_active_at": "2024-01-15T14:25:00Z"
    },
    {
      "user_id": "bob_456",
      "metadata": {"name": "Bob"},
      "created_at": "2024-01-12T10:30:00Z",
      "last_active_at": "2024-01-15T16:00:00Z"
    }
  ],
  "total": 45,
  "offset": 0,
  "limit": 20
}

Updating a User

Update a user’s metadata or change their user ID.
# Update metadata only
user.update(new_metadata={
    "name": "Alice Johnson",
    "email": "alice.johnson@newdomain.com",
    "plan": "enterprise"
})

# Change user ID
user.update(new_user_id="alice_new_id")

# Update both
user.update(
    new_metadata={"name": "Alice J."},
    new_user_id="alice_final"
)

print(f"Updated user: {user.user_id}")
print(f"New metadata: {user.metadata}")
metadata
object
New metadata to replace the existing metadata. This completely replaces the old metadata.
new_user_id
string
New user ID. Must be unique across all users in the project.
{
  "user_id": "alice_new_id",
  "metadata": {
    "name": "Alice Johnson",
    "email": "alice.johnson@newdomain.com",
    "plan": "enterprise"
  },
  "created_at": "2024-01-10T08:00:00Z",
  "last_active_at": "2024-01-15T15:30:00Z"
}
  • If the new_user_id already exists, a UserAlreadyExistsError (409) will be raised
  • The metadata is completely replaced, not merged. Send all fields you want to keep

Refreshing User Data

Refresh a user object to get the latest data from the server.
# Refresh to get latest data
user.refresh()

print(f"Refreshed at: {user.last_active_at}")
print(f"Current metadata: {user.metadata}")
Use refresh() when you have a User object but want to ensure it has the latest data from the server (e.g., after another process might have modified it).

Deleting a User

Delete a user and all their associated data (sessions, memories, merge conflicts).
# Delete a user
user.delete()

print("User deleted successfully")
{
  "message": "User deleted successfully"
}
This action is irreversible! Deleting a user will permanently delete:
  • The user record
  • All sessions for this user
  • All memories associated with this user
  • All merge conflicts for this user
Make sure you have backups or exports if needed before deleting.

Getting Recent Messages

Retrieve the last N messages for a user across all their sessions.
# Get last 10 messages
messages = user.get_last_n_messages(10)

print(f"Total messages: {len(messages.messages)}")

for msg in messages.messages:
    print(f"[{msg.role}] {msg.message}")
    print(f"  Session: {msg.session_id}")
    print(f"  Time: {msg.created_at}")

# Get last 50 messages
messages = user.get_last_n_messages(50)
limit
integer
required
Number of recent messages to retrieve (1-100).
{
  "messages": [
    {
      "message_id": "msg_abc123",
      "session_id": "sess_xyz789",
      "role": "user",
      "message": "What restaurants do you recommend?",
      "created_at": "2024-01-15T14:25:00Z"
    },
    {
      "message_id": "msg_def456",
      "session_id": "sess_xyz789",
      "role": "assistant",
      "message": "Based on your preference for Italian cuisine...",
      "created_at": "2024-01-15T14:25:10Z"
    }
  ]
}
This is useful for:
  • Displaying recent conversation history in a UI
  • Getting context for a new conversation
  • Debugging and monitoring user interactions

Common Patterns

Get or Create User

from recallrai.exceptions import UserNotFoundError

def get_or_create_user(client, user_id, metadata=None):
    """Get existing user or create if doesn't exist."""
    try:
        return client.get_user(user_id)
    except UserNotFoundError:
        return client.create_user(user_id, metadata=metadata)

# Usage
user = get_or_create_user(
    client,
    "alice_123",
    metadata={"name": "Alice"}
)

Batch User Creation

# Create multiple users
user_data = [
    {"user_id": "alice_123", "metadata": {"name": "Alice"}},
    {"user_id": "bob_456", "metadata": {"name": "Bob"}},
    {"user_id": "charlie_789", "metadata": {"name": "Charlie"}},
]

created_users = []
for data in user_data:
    try:
        user = client.create_user(
            user_id=data["user_id"],
            metadata=data["metadata"]
        )
        created_users.append(user)
        print(f"✓ Created {user.user_id}")
    except Exception as e:
        print(f"✗ Failed to create {data['user_id']}: {e}")

print(f"Successfully created {len(created_users)} users")

User Migration

# Migrate user ID (e.g., from temporary to permanent ID)
def migrate_user_id(user, new_id):
    """Migrate user to a new ID."""
    old_id = user.user_id
    user.update(new_user_id=new_id)
    print(f"Migrated user from {old_id} to {new_id}")
    return user

# Usage
temp_user = client.get_user("temp_guest_123")
permanent_user = migrate_user_id(temp_user, "registered_user_456")

Error Handling

Raised when trying to access a user that doesn’t exist.
from recallrai.exceptions import UserNotFoundError

try:
    user = client.get_user("nonexistent_user")
except UserNotFoundError as e:
    print(f"User not found: {e.message}")
    # Handle appropriately (e.g., create user, show error)
Raised when trying to create a user with an ID that already exists, or when updating to an existing user ID.
from recallrai.exceptions import UserAlreadyExistsError

try:
    user = client.create_user("alice_123")
except UserAlreadyExistsError as e:
    print(f"User already exists: {e.message}")
    # Handle appropriately (get existing user instead)
    user = client.get_user("alice_123")
Raised when provided data doesn’t meet validation requirements.
from recallrai.exceptions import ValidationError

try:
    # Invalid user_id format or invalid metadata
    user = client.create_user("")  # Empty user_id
except ValidationError as e:
    print(f"Invalid data: {e.message}")

Best Practices

Use meaningful user IDs: Use stable identifiers from your system (database IDs, auth provider IDs) rather than sequential numbers or temporary values.
Store relevant metadata: Include information that might be useful for personalization (preferences, plan type, demographics) but avoid storing sensitive data.
Handle not found errors: Always handle UserNotFoundError gracefully, especially in chat applications where users might be accessing stale links.
Don’t store PII unnecessarily: Only store metadata that’s needed for your use case. Avoid storing sensitive information like passwords, SSNs, or payment details.

Next Steps

I