Appearance
Metadata
Attach custom metadata to every request for tracking, filtering, and analytics.
What is Metadata?
Metadata is arbitrary key-value data you attach to requests. Mandatum allows you to track context about each request without modifying your prompts.
Common use cases:
- User tracking: Associate requests with specific users
- Session tracking: Group requests by session
- A/B testing: Track which variant a user saw
- Feature flags: Record which features were enabled
- Environment: Distinguish dev/staging/production
- Cost attribution: Track costs per team or project
Adding Metadata
Python
python
from mandatum import Mandatum
client = Mandatum(api_key="your-api-key")
response = client.prompts.run(
prompt_name="customer-classifier",
input_variables={"message": "I need help"},
metadata={
"user_id": "user_123",
"session_id": "session_456",
"source": "web_app",
"environment": "production",
"team": "customer-support",
"version": "v2.1.0"
}
)TypeScript
Coming Soon
A TypeScript/JavaScript SDK is in development. For now, use the REST API directly.
REST API
bash
curl -X POST https://mandatum-api.gavelinivar.com/api/v1/prompts/customer-classifier/run \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input_variables": {
"message": "I need help"
},
"metadata": {
"user_id": "user_123",
"session_id": "session_456",
"source": "web_app",
"environment": "production"
}
}'Metadata Types
Metadata values can be:
- Strings:
"user_123","production","v2.1.0" - Numbers:
42,3.14 - Booleans:
true,false - Null:
null - Arrays:
["tag1", "tag2"] - Objects:
{"plan": "pro", "seats": 5}
Example with Mixed Types
python
metadata = {
"user_id": "user_123", # string
"session_duration": 145.5, # number
"is_premium": True, # boolean
"tags": ["vip", "early_access"], # array
"subscription": { # object
"plan": "pro",
"seats": 5,
"renewal_date": "2025-12-31"
}
}Filtering by Metadata
In Dashboard
- Navigate to Logs
- Click Add Filter
- Select Metadata
- Choose key and value
Via API
python
# Filter logs by user
logs = client.logs.list(
metadata={"user_id": "user_123"}
)
# Filter by multiple metadata fields
logs = client.logs.list(
metadata={
"environment": "production",
"team": "customer-support"
}
)
# Filter by nested metadata
logs = client.logs.list(
metadata={"subscription.plan": "pro"}
)Advanced Filters
python
# Greater than
logs = client.logs.list(
metadata_filters={
"session_duration": {"gt": 100}
}
)
# In array
logs = client.logs.list(
metadata_filters={
"team": {"in": ["sales", "support"]}
}
)
# Exists
logs = client.logs.list(
metadata_filters={
"user_id": {"exists": True}
}
)Analytics by Metadata
Group by Metadata
Track costs, usage, and performance by any metadata field:
python
# Costs per user
user_costs = client.analytics.get_costs(
group_by="metadata.user_id",
start_date="2025-01-01",
end_date="2025-01-31"
)
for user in user_costs:
print(f"User {user.user_id}: ${user.cost_usd:.2f}")
# Usage per team
team_usage = client.analytics.get_usage(
group_by="metadata.team"
)
for team in team_usage:
print(f"{team.name}: {team.request_count} requests")
# Latency by environment
env_latency = client.analytics.get_latency(
group_by="metadata.environment"
)
for env in env_latency:
print(f"{env.name}: {env.avg_ms}ms avg")Segment Analytics
Compare performance across segments:
python
# Premium vs free users
premium_analytics = client.analytics.get_metrics(
metadata={"subscription.plan": "pro"}
)
free_analytics = client.analytics.get_metrics(
metadata={"subscription.plan": "free"}
)
print(f"Premium users: {premium_analytics.avg_latency_ms}ms avg latency")
print(f"Free users: {free_analytics.avg_latency_ms}ms avg latency")Common Patterns
User Tracking
Track individual users:
python
metadata = {
"user_id": "user_123",
"user_email": "alice@example.com",
"user_plan": "pro"
}Session Tracking
Group requests by session:
python
metadata = {
"session_id": "session_456",
"session_start": "2025-01-15T10:00:00Z",
"ip_address": "192.168.1.1"
}A/B Testing
Track experiment variants:
python
metadata = {
"experiment_id": "prompt_v2_test",
"variant": "control", # or "variant_a"
"cohort": "early_adopters"
}Cost Attribution
Attribute costs to teams/projects:
python
metadata = {
"team": "customer-support",
"project": "chatbot-v2",
"cost_center": "engineering"
}Feature Flags
Track which features are enabled:
python
metadata = {
"feature_flags": {
"new_ui": True,
"advanced_analytics": False,
"beta_integrations": True
}
}Environment Tracking
Distinguish environments:
python
metadata = {
"environment": "production", # or "staging", "development"
"deployment_version": "v2.1.0",
"region": "us-east-1"
}Best Practices
Use Consistent Keys
Define a standard metadata schema:
python
# Good: consistent naming
metadata = {
"user_id": "user_123",
"session_id": "session_456",
"environment": "production"
}
# Bad: inconsistent naming
metadata = {
"userId": "user_123",
"session": "session_456",
"env": "prod"
}Document Your Schema
Create a metadata schema document:
python
METADATA_SCHEMA = {
"user_id": "string - Unique user identifier",
"session_id": "string - Session identifier",
"environment": "string - Environment (production|staging|development)",
"team": "string - Team name (sales|support|engineering)",
"version": "string - Application version (semver)"
}Don't Store PII Unnecessarily
Avoid storing sensitive personal information:
python
# Good: use IDs
metadata = {
"user_id": "user_123"
}
# Bad: storing PII
metadata = {
"user_email": "alice@example.com",
"user_phone": "+1-555-0123",
"user_address": "123 Main St"
}Keep Metadata Lightweight
Limit metadata size to improve performance:
python
# Good: lightweight
metadata = {
"user_id": "user_123",
"team": "support"
}
# Bad: too much data
metadata = {
"user_full_profile": {...}, # Large nested object
"entire_session_history": [...], # Large array
"application_state": {...} # Unnecessary data
}Use Namespacing
Namespace related metadata:
python
metadata = {
"user.id": "user_123",
"user.plan": "pro",
"session.id": "session_456",
"session.start_time": "2025-01-15T10:00:00Z",
"request.source": "web_app",
"request.ip": "192.168.1.1"
}Exporting Metadata
Include in Exports
Metadata is included in log exports:
python
# Export logs with metadata
client.logs.export(
format="csv",
output_file="logs_with_metadata.csv",
include_metadata=True
)CSV format:
csv
timestamp,prompt_name,status,user_id,session_id,environment,cost_usd
2025-01-15T10:00:00Z,classifier,success,user_123,session_456,production,0.004
2025-01-15T10:01:00Z,classifier,success,user_123,session_456,production,0.004Privacy & GDPR
Delete User Data
Delete all logs for a user:
python
# GDPR: Right to be forgotten
client.logs.delete_by_metadata(
metadata={"user_id": "user_123"}
)Anonymize Data
Anonymize user data:
python
# Anonymize all data for a user
client.logs.anonymize(
metadata={"user_id": "user_123"},
fields=["user_id", "user_email"]
)After anonymization:
python
# Before
metadata = {"user_id": "user_123", "user_email": "alice@example.com"}
# After
metadata = {"user_id": "anonymous_xxx", "user_email": "anonymous@example.com"}