---
title: "Save a memory"
method: POST
path: "/memories"
tags: ["Assistant memory"]
---

# Save a memory

`POST /memories`

## Request

- Base URL: `https://tasg.app/api/v1`
- URL: `https://tasg.app/api/v1/memories`
- Auth: HTTP bearer

Requires memory to be enabled for the instance, the workspace AND the caller (opt-in, default off). Scope `user` (default) saves a private memory; near-duplicates refresh the existing row (`dedup_action`), and `supersedes_memory_id` records a correction (the named memory is retired; deleting the correction later reactivates it). Scopes `workspace` and `project` save SHARED team memories through propose-then-approve: they land with status `proposed` (excluded from recall) until a workspace owner (workspace scope) or project owner/editor (project scope) approves them — except a hand-written save by someone who could approve it, which activates immediately. Write gates: workspace scope needs full workspace membership; project scope needs the project owner or editor role. Near-duplicate shared writes are skipped, never refreshed. Rate-limited to 60 requests / 5 min.

## Request body

- object
  - `workspace_id` string, uuid, required
  - `content` string, required
  - `kind` 'user_preference' | 'team_convention' | 'project_fact' | 'entity_relationship' | 'agent_feedback', required
  - `importance` integer
  - `project_id` string, uuid: Required for project scope.
  - `source_note` string
  - `author_type` 'user' | 'agent'
  - `supersedes_memory_id` string: Full UUID or short ref (e.g. `m_3f2a91`) of one of my own active user-scope memories that this one corrects. User scope only.
  - `scope` 'user' | 'workspace' | 'project'
  - `subject_user_id` string, uuid: Who the fact is about — must be tied to the workspace (a project member, direct workspace member or the owner). Shared scopes only.

## Response `200`

Refreshed an existing near-duplicate, or skipped: a user-authored memory already says this, or a matching team memory already exists or awaits approval.

- union
  - object: An assistant memory (camelCase keys).
    - `id` string, uuid, required
    - `workspaceId` string, uuid, required
    - `scope` 'user' | 'workspace' | 'project', required: `user` = private to the subject; `workspace`/`project` = shared team memory, which goes through propose-then-approve.
    - `kind` 'user_preference' | 'team_convention' | 'project_fact' | 'entity_relationship' | 'agent_feedback', required
    - `content` string, required
    - `importance` integer, required
    - `status` 'active' | 'proposed' | 'superseded': `proposed` rows are excluded from recall until approved.
    - `authorType` 'user' | 'agent', required
    - `sourceNote` string, nullable
    - `projectId` string, uuid, nullable
    - `supersededById` string, uuid, nullable
    - `subjectUserId` string, uuid, nullable: Who the memory is about; the subject can always see and delete it.
    - `authorUserId` string, uuid, nullable
    - `createdAt` string, date-time, required
    - `updatedAt` string, date-time
    - `lastUsedAt` string, date-time
    - `dedup_action` 'refreshed'
  - object
    - `ok` boolean, required: Always `false` for a skip.
    - `action` 'skipped', required
    - `reason` string, required

## Other responses

- `201`: Inserted (status `proposed` for shared-scope writes pending approval).
- `400`: Validation failed: the body or query did not match the schema, or a business rule was violated. `error` says which.
- `401`: Missing, invalid, expired or revoked credentials.
- `403`: Authenticated, but not allowed: not a member, insufficient project role or the API token lacks the required scope.
- `404`: Not found, or not visible to the caller (tenancy is enforced: foreign resources look identical to missing ones).
- `429`: Rate limited. Back off and retry after the window in the `RateLimit-*` headers.

---

[API](https://skmtc.dev/tasg/apis/tasg-api.md) · [All operations](https://skmtc.dev/tasg/apis/tasg-api/llms.txt) · [OpenAPI document](https://skmtc.dev/tasg/apis/tasg-api/revisions/cd2a1dbaf5cf?raw)
