Blocks and profiles
Read, write and curate memory blocks, and manage end-user profiles with /v1/blocks and /v1/memory/users.
Blocks and user profiles are small, hand-maintained documents that are always included in a recall. See Memory types.
| Method | Path | Capability |
|---|---|---|
GET | /v1/blocks/{workspaceId} | read |
PUT | /v1/blocks/{workspaceId} | write |
POST | /v1/blocks/{workspaceId}/curate | curate |
GET | /v1/memory/users/{workspaceId}/{userId}/profile | read |
PUT | /v1/memory/users/{workspaceId}/{userId}/profile | write |
DELETE | /v1/memory/users/{workspaceId}/{userId}/profile | write |
Memory blocks
A block has a label (for example conventions or tech_stack), a value of free text, an agent scope and an optional application:
agentScope: "*"(the default) is the workspace-shared block, visible to every agent.- Any other value scopes the block to one agent. The credential must be bound to that agent, otherwise the request is refused with
403 policy_denied.
Block values are capped at 2,000 characters by default (workspace setting blocks.maxValueChars, 200–10,000). Writes that would overflow fail rather than truncate. Every write is screened, and content flagged as suspicious is rejected with 400.
List blocks
GET /v1/blocks/{workspaceId}?agentId=…&applicationId=…
agentId defaults to * (the shared blocks). Returns an array:
[
{
"id": "…",
"workspaceId": "…",
"applicationId": null,
"agentScope": "*",
"label": "tech_stack",
"value": "PostgreSQL, Redis, .NET 10",
"charLimit": 2000,
"isReadOnly": false,
"updatedAt": "2026-10-01T09:00:00Z"
}
]Create or replace a block
PUT /v1/blocks/{workspaceId} — upsert by label and scope.
{ "label": "tech_stack", "value": "PostgreSQL, Redis, .NET 10", "agentScope": "*", "applicationId": null }Response: {"status":"updated"}. A rejected value (screening, character limit, read-only block) answers 400 VALIDATION_FAILED.
Curate a block
POST /v1/blocks/{workspaceId}/curate — edit a block line by line, which is safer for agents than rewriting the whole value.
{ "label": "conventions", "action": "replace", "match": "error format", "value": "Errors use RFC 7807 problem+json", "agentScope": "*" }action | Needs | Effect |
|---|---|---|
add | value | Appends a line (creates the block if it doesn't exist). |
replace | match, value | Replaces the first line containing match (case-insensitive). |
remove | match | Removes the first line containing match (case-insensitive). |
Response: {"status":"curated"}. An unknown action, a missing argument, an unknown block (for replace/remove) or no matching line answers 400.
MCP: get_blocks, curate_block. .NET: GetBlocksAsync, UpdateBlockAsync, CurateBlockAsync.
User profiles
One profile document per end user (userId) in a workspace. When a recall names that userId, the profile is returned as userProfile and rendered right after the blocks. Profiles are capped at 2,000 characters by default (userProfile.maxChars). With the workspace setting userProfile.autoEnrich, consolidation appends preference facts it finds for that user.
Every profile endpoint requires a credential allowed to act for that user — one with canActForUsers, or one whose proved user is userId. Otherwise 403 policy_denied.
Get a profile
GET /v1/memory/users/{workspaceId}/{userId}/profile[?applicationId=…]
Returns the stored profile, or 404 if there is none.
Create or replace a profile
PUT /v1/memory/users/{workspaceId}/{userId}/profile
{ "content": "Vegetarian. Prefers short answers. Lives in Berlin.", "applicationId": null }Response: {"status":"updated"}. Content over the limit, or an invalid user ID, answers 400.
Delete a profile
DELETE /v1/memory/users/{workspaceId}/{userId}/profile[?applicationId=…] → 204.
MCP: get_user_profile.