Memory API
API for agents to store and retrieve key-value memory scoped by owner + project.
Endpoints
PUT /api/memory
GET /api/memory?project={project}&key={key} # single lookup
GET /api/memory?project={project} # list lookup
DELETE /api/memory?project={project}&key={key}
Authentication
All requests require a Bearer token.
Authorization: Bearer <token>
Use a server-issued token with read for GET and write for PUT/DELETE. Credentials belonging to the same Google owner share this namespace. Provider account selection does not change legacy memory keys. Unknown or revoked credentials return 401; these endpoints never auto-register a token.
Project format
- Type: string (max 128 characters)
- Empty strings / whitespace-only input are rejected (prevents orphan records that become inaccessible after normalizing to an empty string)
- The stored value is the input after
trim()(only leading/trailing whitespace removed, inner spaces and case preserved) - Full normalization is applied only when generating the internal partition key (
projectKey):trim().toLowerCase().replace(/\s+/g, '-') - Example:
" My Project "→ stored:"My Project", PK:my-project
Key format
- Allowed characters:
a-z,0-9,_,- - Length: 1-64 characters
- Examples:
user_name,session-id,api_version
Value constraints
- Type: string only (empty string allowed)
- Max length: 10000 characters
PUT /api/memory
Stores or updates the value of a memory key (upsert). createdAt retains the original creation time and only updatedAt is refreshed.
Request Body
{
"project": "vibemon",
"key": "user_name",
"value": "alice"
}
Fields
| Field | Type | Required | Description |
|---|---|---|---|
project |
string | Yes | Project name (stored after trim, see Project format) |
key |
string | Yes | Memory key ([a-z0-9_-]{1,64}) |
value |
string | Yes | String value (max 10000 characters) |
Success (200)
{
"success": true,
"memory": {
"project": "vibemon",
"key": "user_name",
"value": "alice",
"createdAt": "2026-04-14T09:00:00.000Z",
"updatedAt": "2026-04-14T09:00:00.000Z"
}
}
GET /api/memory (single lookup)
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project |
string | Yes | Project name |
key |
string | Yes | Key to look up |
Success (200)
{
"memory": {
"project": "vibemon",
"key": "user_name",
"value": "alice",
"createdAt": "2026-04-14T09:00:00.000Z",
"updatedAt": "2026-04-14T09:00:00.000Z"
}
}
Not Found (404)
{ "error": "Not found" }
GET /api/memory (list lookup)
Omitting key returns all memory for the project in ascending key order.
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project |
string | Yes | Project name |
Success (200)
{
"memories": [
{
"project": "vibemon",
"key": "api_version",
"value": "v2",
"createdAt": "2026-04-14T08:00:00.000Z",
"updatedAt": "2026-04-14T08:00:00.000Z"
},
{
"project": "vibemon",
"key": "user_name",
"value": "alice",
"createdAt": "2026-04-14T09:00:00.000Z",
"updatedAt": "2026-04-14T09:00:00.000Z"
}
]
}
Returns { "memories": [] } for an empty project.
DELETE /api/memory
Query Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
project |
string | Yes | Project name |
key |
string | Yes | Key to delete |
Success (200)
{
"success": true,
"project": "vibemon",
"projectKey": "vibemon",
"key": "user_name"
}
The response returns both the original project and the normalized projectKey, so callers can confirm the actual partition key.
Note: Deleting a non-existent key still returns 200 (idempotent).
Errors
| Status | Error (example) | Description |
|---|---|---|
| 400 | project must be a string / project must contain non-whitespace characters |
Missing project, type error, or whitespace-only input |
| 400 | project exceeds maximum length of 128 characters |
Project length exceeded |
| 400 | value must be a string / value exceeds maximum length of 10000 characters |
Value type/length error |
| 400 | Invalid key format... |
Key format error |
| 401 | Invalid or expired API token | Missing, malformed, unknown, deleted, or revoked credential |
| 403 | Token requires read/write permission | Token lacks the scope required by the method |
| 429 | Request limit exceeded | Shared owner request budget exceeded |
| 404 | Not found |
Target not found in single lookup |
| 405 | Method not allowed |
Method other than PUT/GET/DELETE |
| 503 | Service temporarily unavailable | Storage failure; retry with backoff |
Examples
curl
TOKEN=<issued-token>
# Store
curl -X PUT https://vibemon.io/api/memory \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"project":"vibemon","key":"user_name","value":"alice"}'
# Single lookup
curl "https://vibemon.io/api/memory?project=vibemon&key=user_name" \
-H "Authorization: Bearer $TOKEN"
# List lookup
curl "https://vibemon.io/api/memory?project=vibemon" \
-H "Authorization: Bearer $TOKEN"
# Delete
curl -X DELETE "https://vibemon.io/api/memory?project=vibemon&key=user_name" \
-H "Authorization: Bearer $TOKEN"
JavaScript
const TOKEN = '<issued-token>';
const BASE = 'https://vibemon.io/api/memory';
// Store
await fetch(BASE, {
method: 'PUT',
headers: {
'Authorization': `Bearer ${TOKEN}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({ project: 'vibemon', key: 'user_name', value: 'alice' }),
});
// List lookup
const res = await fetch(`${BASE}?project=vibemon`, {
headers: { 'Authorization': `Bearer ${TOKEN}` },
});
const { memories } = await res.json();
Related documents
- Status API - Agent status reporting (
POST/DELETE /api/status) - Statuses API - Project status list (
GET /api/statuses) - Metrics API - Activity metrics
- Stats API - Owner statistics
- Entity definitions - AgentMemory data model