Documentation Index Fetch the complete documentation index at: https://ulpi.mintlify.app/llms.txt
Use this file to discover all available pages before exploring further.
API Reference
Complete REST API reference for the Memory Module. Use these endpoints for direct integration, automation, or when MCP isnβt available.
Prefer MCP? Most users should use MCP Integration for seamless AI assistant integration. Use this API for custom integrations, automation scripts, or non-MCP tools.
Base URL
https://api.ulpi.io/api/v1/memories
Authentication
All endpoints require Bearer token authentication :
Authorization: Bearer YOUR_API_KEY
X-Tenant-ID: your-repository-id
Get your API key:
Log into app.ulpi.io
Navigate to your repository β Settings β API Keys
Click βGenerate New Keyβ
Store securely (shown only once!)
Endpoints
POST /memories
Store a new memory.
Request:
curl -X POST https://api.ulpi.io/api/v1/memories \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id" \
-H "Content-Type: application/json" \
-d '{
"content": "Our API uses JWT bearer token authentication. Tokens expire after 30 days of inactivity.",
"sector": "semantic",
"tags": ["api", "authentication", "documentation"],
"source": "API documentation v2",
"metadata": {
"version": "2.0",
"author": "engineering-team"
}
}'
Parameters:
content (required, string): The information to store
sector (optional, string): episodic | semantic | procedural | emotional | reflective
tags (optional, array): List of tags for organization
source (optional, string): Where this came from
metadata (optional, object): Custom JSON metadata
Response:
{
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"content" : "Our API uses JWT bearer..." ,
"sector" : "semantic" ,
"salience" : 1.0 ,
"access_count" : 0 ,
"tags" : [ "api" , "authentication" , "documentation" ],
"source" : "API documentation v2" ,
"metadata" : {
"version" : "2.0" ,
"author" : "engineering-team"
},
"created_at" : "2025-01-25T10:30:00Z" ,
"last_accessed_at" : null
}
}
Status Codes:
201: Created successfully
400: Invalid request format
401: Unauthorized (bad API key)
422: Validation failed
429: Rate limit exceeded
POST /memories/search
Search memories with hybrid ranking.
Request:
curl -X POST https://api.ulpi.io/api/v1/memories/search \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id" \
-H "Content-Type: application/json" \
-d '{
"query": "API authentication methods",
"limit": 10,
"sector": "semantic",
"min_salience": 0.3,
"expand_waypoints": true,
"max_hops": 3
}'
Parameters:
query (required, string): Search text
limit (optional, int): Results to return (default: 10, max: 100)
sector (optional, string): Filter by cognitive sector
tags (optional, array): Filter by tags
min_salience (optional, float): Minimum salience threshold (0.0-1.0)
expand_waypoints (optional, bool): Enable context expansion (default: true)
max_hops (optional, int): Waypoint traversal depth (default: 3, max: 5)
Response:
{
"data" : [
{
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"content" : "Our API uses JWT bearer..." ,
"sector" : "semantic" ,
"salience" : 0.95 ,
"score" : 0.92 ,
"access_count" : 15 ,
"tags" : [ "api" , "authentication" ],
"created_at" : "2025-01-15T10:00:00Z" ,
"last_accessed_at" : "2025-01-24T15:30:00Z"
}
],
"meta" : {
"total" : 42 ,
"search_time_ms" : 145 ,
"waypoints_expanded" : true
}
}
Status Codes:
200: Success
400: Invalid request
401: Unauthorized
GET /memories/
Retrieve specific memory by ID.
Request:
curl https://api.ulpi.io/api/v1/memories/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id"
Response:
{
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"content" : "Our API uses JWT bearer..." ,
"sector" : "semantic" ,
"salience" : 0.95 ,
"access_count" : 15 ,
"tags" : [ "api" , "authentication" ],
"source" : "API documentation" ,
"metadata" : {},
"created_at" : "2025-01-15T10:00:00Z" ,
"last_accessed_at" : "2025-01-24T15:30:00Z" ,
"embedding_status" : "completed"
}
}
Status Codes:
200: Success
404: Memory not found
401: Unauthorized
Note: Accessing a memory increments access_count and updates last_accessed_at.
PATCH /memories/
Update memory content or metadata.
Request:
curl -X PATCH https://api.ulpi.io/api/v1/memories/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id" \
-H "Content-Type: application/json" \
-d '{
"content": "Updated: Our API uses JWT bearer token authentication. Tokens now expire after 60 days.",
"tags": ["api", "authentication", "updated"],
"metadata": {
"last_updated_by": "admin",
"version": "2.1"
}
}'
Parameters:
content (optional, string): Update the content
tags (optional, array): Replace tags
source (optional, string): Update source
metadata (optional, object): Replace metadata
Response:
{
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"content" : "Updated: Our API uses..." ,
"tags" : [ "api" , "authentication" , "updated" ],
"updated_at" : "2025-01-25T16:00:00Z"
}
}
Status Codes:
200: Updated successfully
404: Memory not found
422: Validation failed
Note: Cannot change sector after creation. Embeddings regenerate automatically.
POST /memories//reinforce
Explicitly boost memory salience.
Request:
curl -X POST https://api.ulpi.io/api/v1/memories/550e8400-e29b-41d4-a716-446655440000/reinforce \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id" \
-H "Content-Type: application/json" \
-d '{
"profile": "maintenance"
}'
Parameters:
profile (optional, string): Reinforcement strength
quick_refresh: +0.05
maintenance: +0.10 (default)
deep_learning: +0.15
emergency: +0.25
Response:
{
"data" : {
"id" : "550e8400-e29b-41d4-a716-446655440000" ,
"old_salience" : 0.75 ,
"new_salience" : 0.85 ,
"profile_used" : "maintenance" ,
"boost_applied" : 0.10
}
}
Status Codes:
200: Reinforced successfully
404: Memory not found
GET /memories//waypoints
Get semantic connections for a memory.
Request:
curl https://api.ulpi.io/api/v1/memories/550e8400-e29b-41d4-a716-446655440000/waypoints \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id"
Parameters (query string):
limit (optional, int): Number of waypoints (default: 20)
min_weight (optional, float): Minimum similarity (default: 0.75)
Response:
{
"data" : [
{
"connected_memory_id" : "660e8400-e29b-41d4-a716-446655440001" ,
"weight" : 0.85 ,
"connected_memory" : {
"id" : "660e8400-e29b-41d4-a716-446655440001" ,
"content" : "Token refresh endpoint: POST /api/auth/refresh" ,
"sector" : "semantic" ,
"salience" : 0.90
}
}
],
"meta" : {
"total_waypoints" : 5
}
}
DELETE /memories/
Permanently delete a memory.
Request:
curl -X DELETE https://api.ulpi.io/api/v1/memories/550e8400-e29b-41d4-a716-446655440000 \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id"
Response:
{
"message" : "Memory deleted successfully"
}
Status Codes:
204: Deleted successfully
404: Memory not found
Warning: This is permanent and cannot be undone!
POST /memories/prune
Remove low-salience memories in bulk.
Request:
curl -X POST https://api.ulpi.io/api/v1/memories/prune \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id" \
-H "Content-Type: application/json" \
-d '{
"threshold": 0.1,
"sector": "episodic",
"dry_run": true
}'
Parameters:
threshold (optional, float): Salience threshold (default: 0.1)
sector (optional, string): Only prune specific sector
dry_run (optional, bool): Preview without deleting (default: false)
Response:
{
"data" : {
"memories_pruned" : 42 ,
"threshold_used" : 0.1 ,
"sector_filter" : "episodic" ,
"dry_run" : true
}
}
GET /memories/stats
Get system statistics.
Request:
curl https://api.ulpi.io/api/v1/memories/stats \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "X-Tenant-ID: your-repo-id"
Response:
{
"data" : {
"total_memories" : 1523 ,
"by_sector" : {
"episodic" : 320 ,
"semantic" : 810 ,
"procedural" : 245 ,
"emotional" : 98 ,
"reflective" : 50
},
"avg_salience" : 0.67 ,
"hot_memories" : 45 ,
"total_waypoints" : 3042 ,
"embeddings_today" : 127 ,
"storage_used_mb" : 24.5
}
}
Rate Limits
Plan Rate Limit Starter 60 requests/minute Pro 300 requests/minute Enterprise 1000 requests/minute
Headers returned:
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 45
X-RateLimit-Reset: 1643097600
429 Response:
{
"message" : "Rate limit exceeded" ,
"retry_after" : 30
}
Error Responses
All errors return consistent JSON format:
{
"message" : "Validation failed" ,
"errors" : {
"content" : [ "The content field is required." ],
"sector" : [ "Invalid sector. Must be one of: episodic, semantic, procedural, emotional, reflective" ]
}
}
Status Codes:
400: Bad Request (malformed JSON, invalid parameters)
401: Unauthorized (missing/invalid API key)
403: Forbidden (valid auth but no access)
404: Not Found (resource doesnβt exist)
422: Unprocessable Entity (validation failed)
429: Too Many Requests (rate limit exceeded)
500: Internal Server Error
For endpoints returning lists, use cursor-based pagination:
Request:
curl https://api.ulpi.io/api/v1/memories?limit= 20 & cursor = eyJpZCI6MTIzfQ \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"data" : [ ... ],
"meta" : {
"next_cursor" : "eyJpZCI6MTQzfQ" ,
"prev_cursor" : "eyJpZCI6MTAzfQ" ,
"has_more" : true
}
}
Webhooks
Coming soon! Subscribe to memory events:
memory.created
memory.accessed
memory.pruned
waypoint.created
Official SDKs available:
JavaScript / Node.js npm install @ulpi/memory-sdk
Go go get github.com/ulpi-io/memory-go
Community SDKs: PHP, Ruby, Rust (see GitHub )
Code Examples
JavaScript / Node.js
const { MemoryClient } = require ( '@ulpi/memory-sdk' );
const client = new MemoryClient ({
apiKey: process . env . ULPI_API_KEY ,
tenantId: process . env . ULPI_TENANT_ID
});
// Store a memory
const memory = await client . memories . create ({
content: "Our API uses JWT authentication..." ,
sector: "semantic" ,
tags: [ "api" , "auth" ]
});
// Search memories
const results = await client . memories . search ({
query: "authentication methods" ,
limit: 10 ,
expandWaypoints: true
});
// Reinforce a memory
await client . memories . reinforce ( memory . id , {
profile: "maintenance"
});
from ulpi_memory import MemoryClient
client = MemoryClient(
api_key = os.environ[ "ULPI_API_KEY" ],
tenant_id = os.environ[ "ULPI_TENANT_ID" ]
)
# Store a memory
memory = client.memories.create(
content = "Our API uses JWT authentication..." ,
sector = "semantic" ,
tags = [ "api" , "auth" ]
)
# Search memories
results = client.memories.search(
query = "authentication methods" ,
limit = 10 ,
expand_waypoints = True
)
# Reinforce a memory
client.memories.reinforce(
memory.id,
profile = "maintenance"
)
# Store
curl -X POST https://api.ulpi.io/api/v1/memories \
-H "Authorization: Bearer $ULPI_API_KEY " \
-H "X-Tenant-ID: $ULPI_TENANT_ID " \
-H "Content-Type: application/json" \
-d '{"content":"Our API uses JWT...","sector":"semantic"}'
# Search
curl -X POST https://api.ulpi.io/api/v1/memories/search \
-H "Authorization: Bearer $ULPI_API_KEY " \
-H "X-Tenant-ID: $ULPI_TENANT_ID " \
-H "Content-Type: application/json" \
-d '{"query":"authentication","limit":10}'
# Reinforce
curl -X POST https://api.ulpi.io/api/v1/memories/MEMORY_ID/reinforce \
-H "Authorization: Bearer $ULPI_API_KEY " \
-H "X-Tenant-ID: $ULPI_TENANT_ID " \
-H "Content-Type: application/json" \
-d '{"profile":"maintenance"}'
Best Practices
When storing multiple memories, use async/parallel requests to improve throughput. Donβt wait for each to complete sequentially.
Always implement retry logic with exponential backoff for 5xx errors and rate limits (429).
Never commit keys to version control
Use environment variables
Rotate keys quarterly
Use separate keys per environment
Cache search results when possible
Implement client-side rate limiting
Monitor X-RateLimit-Remaining header
Upgrade plan if consistently hitting limits
Support
API Issues:
Response Times:
Starter: 48 hours
Pro: 24 hours (priority)
Enterprise: 4 hours (dedicated)
Next Steps
MCP Integration Use with AI assistants instead of direct API
Best Practices Optimization tips and strategies
Workflows Real-world integration examples
Getting Started Quick setup guide