API Reference
All endpoints require Authorization: Bearer <token>.
Table of contents
Characters
| Method | Path | Summary |
|---|---|---|
POST | /v1/characters | Create a new character |
GET | /v1/characters | List all characters for the tenant |
GET | /v1/characters/{id} | Get a character by ID |
PUT | /v1/characters/{id}/profile | Update character display name and description |
PUT | /v1/characters/{id}/aliases | Set searchable aliases for the character |
POST | /v1/characters/{id}/archive | Archive a character |
GET | /v1/characters/resolve/{alias} | Resolve a character by alias |
GET | /v1/characters/{id}/export | Export character memories as Markdown |
Create character
Request body:
{
"name": "My Agent",
"categoryPreset": "developer"
}
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name (must be unique within the tenant) |
categoryPreset | string | no | Memory category layout: developer, standard |
Response 201:
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"name": "My Agent",
"status": "ACTIVE",
"categoryPreset": "developer",
"createdAt": "2024-01-15T10:30:00Z"
}
Memories
| Method | Path | Summary |
|---|---|---|
POST | /v1/characters/{id}/memories | Add a memory (AI-extracted on paid tiers) |
POST | /v1/characters/{id}/memories/direct | Add a memory directly, bypassing AI extraction |
GET | /v1/characters/{id}/memories | List all memories |
GET | /v1/characters/{id}/memories/{memId} | Get a memory by ID |
PUT | /v1/characters/{id}/memories/{memId} | Update memory content |
DELETE | /v1/characters/{id}/memories/{memId} | Delete a memory |
POST | /v1/characters/{id}/memories/search | Semantic search across memories |
GET | /v1/characters/{id}/memories/{memId}/history | Get revision history for a memory |
Add memory
Request body:
{
"content": "User prefers dark mode and vim keybindings",
"category": "preferences",
"importance": "NORMAL"
}
| Field | Type | Required | Description |
|---|---|---|---|
content | string | yes | The memory text (max 10,000 chars) |
category | string | no | Override auto-detected category |
importance | string | no | CRITICAL, HIGH, NORMAL, LOW (default: NORMAL) |
Search memories
Request body:
{
"query": "UI preferences",
"limit": 10,
"category": "preferences"
}
| Field | Type | Required | Description |
|---|---|---|---|
query | string | yes | Natural language search query |
limit | int | no | Max results (default: 10, max: 100) |
category | string | no | Filter to a specific category |
File Sync
| Method | Path | Summary |
|---|---|---|
POST | /v1/characters/{id}/sync | Push a file snapshot for sync |
GET | /v1/characters/{id}/sync/status | Get sync status |
GET | /v1/files/{fileId} | Download a synced file |
GET | /v1/files | List synced files for a character |
POST | /v1/characters/{id}/import | Import and extract memories from a document |
Tier
| Method | Path | Summary |
|---|---|---|
GET | /v1/tier | Get tier info, feature flags, and current usage |
Response 200:
{
"tier": "DEVELOPER",
"features": {
"autoRecallAvailable": true,
"autoCaptureAvailable": true,
"aiExtractionAvailable": true,
"directWriteAvailable": true,
"importPipelineAvailable": true,
"teamSharingEnabled": true,
"minSyncIntervalSeconds": 15,
"maxRequestsPerMinute": 60,
"maxMembers": 3,
"maxApiKeys": 3,
"maxCharacters": 30,
"currentCharacterCount": 5
}
}
Error responses
All errors use a consistent envelope:
{
"error": {
"type": "CharacterNotFound",
"message": "Character not found: 550e8400-e29b-41d4-a716-446655440000",
"status": 404
}
}
Error type → HTTP status mapping
| Error Type | Status | Description |
|---|---|---|
CharacterNotFound | 404 | Character ID does not exist or is not visible |
MemoryNotFound | 404 | Memory ID does not exist |
FileNotFound | 404 | File ID does not exist |
InvalidContent | 400 | Memory content is empty or exceeds limit |
InvalidInput | 400 | Request field is missing or malformed |
DuplicateCharacterName | 400 | A character with this name already exists |
CategoryNotConfigured | 400 | Requested category not in character’s preset |
InvalidPreset | 400 | Unknown categoryPreset value |
VisibilityChangeNotAllowed | 400 | Cannot change character visibility in this state |
ValidationError | 400 | Bean validation failure (field-level errors) |
Unauthorized | 401 | Missing or invalid Bearer token |
AccessDenied | 403 | Token is valid but access is denied |
FeatureNotAvailable | 403 | Feature requires a higher tier |
InsufficientRole | 403 | Member role does not permit this operation |
TierLimitExceeded | 429 | Rate limit or AI ops quota exceeded |
CharacterLimitExceeded | 429 | Character count at tier maximum |
ConflictUnresolved | 409 | Concurrent write conflict |
SnapshotConflict | 409 | File sync snapshot version conflict |
ExtractionFailed | 502 | Upstream AI provider returned an error |
SyncFailed | 502 | File sync backend error |
InternalError | 500 | Unexpected server error |
Interactive docs
The interactive API reference renders the full OpenAPI 3.0 spec with request/response examples, schema types, and a built-in request builder.