--- title: "Review Inferred Memories" sidebarTitle: "Memory Review" description: "List and act on low-confidence inferred memories — approve, decline, or undo" icon: "list-checks" --- Supermemory's graph automatically **derives** new facts from patterns across your existing memories (see [Graph Memory](/concepts/graph-memory)). These derived facts are guesses — the engine wasn't told them directly — so they are flagged as **inferred** (`isInference: true`) and **down-weighted in search** until confirmed. These two endpoints let you build a review experience on top of that queue: list the inferred memories awaiting review, then **approve**, **decline**, or **undo** a decision on each one. These endpoints are scoped to a single [container tag](/concepts/container-tags) (space), under `/v3/container-tags/{containerTag}`. ## How review affects ranking While a memory is unreviewed and inferred it is down-weighted in search, so the engine's guesses rank below facts you stated explicitly. Reviewing it resolves that either way: | Action | Result | Effect on search | |--------|--------|------------------| | **Approve** | `isInference` cleared | Ranks like a stated fact — no longer down-weighted | | **Decline** | `isForgotten` set | Removed from search entirely — a rejected guess is forgotten | | **Undo** | back to unreviewed | Returns to the queue; inferred and down-weighted again | A reviewed memory is stamped with `reviewStatus` in its metadata so it drops out of the review queue (declined memories also leave search, since they're forgotten). **Undo** clears that stamp — and un-forgets a declined memory — bringing it back. --- ## List Inferred Memories Return the inferred memories for a container tag that are still awaiting review (the review queue). Reviewed memories are excluded. ``` GET /v3/container-tags/{containerTag}/inferred ``` ```typescript const res = await fetch( "https://api.supermemory.ai/v3/container-tags/user_123/inferred", { headers: { "Authorization": `Bearer ${API_KEY}` } } ); const { memories, total } = await res.json(); ``` ```bash curl "https://api.supermemory.ai/v3/container-tags/user_123/inferred" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" ``` ### Path parameters | Parameter | Type | Description | |-----------|------|-------------| | `containerTag` | string | The container tag / space to read the review queue for | ### Response ```json { "memories": [ { "id": "mem_abc123", "memory": "Alex likely works on Stripe's core payments product", "parentCount": 3, "createdAt": "2025-01-15T10:30:00.000Z", "updatedAt": "2025-01-15T10:30:00.000Z", "metadata": { "source": "derive" } } ], "total": 1 } ``` | Field | Type | Description | |-------|------|-------------| | `memories[].id` | string | Memory entry ID — pass to the review endpoint | | `memories[].memory` | string | The inferred memory text | | `memories[].parentCount` | number | How many source memories this was derived from. Higher = stronger signal | | `memories[].createdAt` | string | ISO 8601 timestamp | | `memories[].updatedAt` | string | ISO 8601 timestamp | | `memories[].metadata` | object \| null | Arbitrary metadata stored on the memory | | `total` | number | Count of unreviewed inferred memories returned | The queue returns up to **50** memories, ordered by `parentCount` descending (most strongly supported first), then by `createdAt` descending. It excludes anything that is forgotten, expired, or already reviewed. An unknown or empty container tag returns `{ "memories": [], "total": 0 }`. --- ## Review an Inferred Memory Record a decision on a single inferred memory. ``` POST /v3/container-tags/{containerTag}/inferred/{memoryId}/review ``` ```typescript const res = await fetch( "https://api.supermemory.ai/v3/container-tags/user_123/inferred/mem_abc123/review", { method: "POST", headers: { "Authorization": `Bearer ${API_KEY}`, "Content-Type": "application/json" }, body: JSON.stringify({ action: "approve" }) } ); const result = await res.json(); // { id: "mem_abc123", isInference: false, isForgotten: false, reviewStatus: "approved" } ``` ```bash curl -X POST \ "https://api.supermemory.ai/v3/container-tags/user_123/inferred/mem_abc123/review" \ -H "Authorization: Bearer $SUPERMEMORY_API_KEY" \ -H "Content-Type: application/json" \ -d '{"action": "approve"}' ``` ### Path parameters | Parameter | Type | Description | |-----------|------|-------------| | `containerTag` | string | The container tag / space the memory belongs to | | `memoryId` | string | The memory entry ID from the list endpoint | ### Body parameters | Parameter | Type | Required | Description | |-----------|------|----------|-------------| | `action` | string | yes | One of `approve`, `decline`, or `undo` | The reject action is named **`decline`**. There is no `reject` value. **Action semantics:** - **`approve`** — Promote the memory: clears `isInference`, so it ranks like a stated fact instead of a down-weighted guess. Stamps `reviewStatus: "approved"`. - **`decline`** — Reject the suggestion: the memory is **forgotten** (`isForgotten: true`) and stamped `reviewStatus: "declined"`, so it leaves both search and the review queue. - **`undo`** — Revert a prior `approve`/`decline` back to the unreviewed inferred state: restores `isInference: true`, un-forgets the memory (`isForgotten: false`), and clears the review stamp, so it returns to the queue. ### Response ```json { "id": "mem_abc123", "isInference": false, "isForgotten": false, "reviewStatus": "approved" } ``` | Field | Type | Description | |-------|------|-------------| | `id` | string | The reviewed memory ID | | `isInference` | boolean | `false` after approve; `true` after decline or undo | | `isForgotten` | boolean | `true` after decline (the memory is forgotten); `false` otherwise | | `reviewStatus` | `"approved"` \| `"declined"` \| `null` | The new status; `null` after an undo | ### Errors | Status | When | |--------|------| | `401` | Missing or invalid authentication | | `404` | The container tag or memory was not found in your organization | | `409` | The memory isn't reviewable for this action — it's not an inferred memory, or there's no prior review to undo | --- ## Building a review experience The endpoints are designed for an optimistic, one-at-a-time review UI (swipe to keep / decline, with undo). A typical client fetches the queue once, then pops each card off locally as the user decides — `undo` re-adds it. ```typescript import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query"; const BASE = "https://api.supermemory.ai/v3"; const key = (tag: string) => ["inferred-memories", tag] as const; export type InferredMemory = { id: string; memory: string; parentCount: number; createdAt: string; updatedAt: string; metadata: Record | null; }; export type ReviewAction = "approve" | "decline" | "undo"; export function useInferredMemories(containerTag: string) { return useQuery({ queryKey: key(containerTag), queryFn: async (): Promise => { const res = await fetch(`${BASE}/container-tags/${containerTag}/inferred`, { headers: { Authorization: `Bearer ${API_KEY}` }, }); if (!res.ok) throw new Error("Failed to load review queue"); const data = await res.json(); return data.memories ?? []; }, staleTime: 60_000, }); } export function useReviewInferredMemory(containerTag: string) { const queryClient = useQueryClient(); return useMutation({ mutationFn: async (vars: { memoryId: string; action: ReviewAction }) => { const res = await fetch( `${BASE}/container-tags/${containerTag}/inferred/${vars.memoryId}/review`, { method: "POST", headers: { Authorization: `Bearer ${API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ action: vars.action }), }, ); if (!res.ok) throw new Error("Review failed"); return res.json(); }, onSuccess: (_data, { memoryId, action }) => { // approve/decline remove the card; undo brings it back, so refetch. if (action === "undo") { queryClient.invalidateQueries({ queryKey: key(containerTag) }); return; } queryClient.setQueryData(key(containerTag), (prev) => prev?.filter((m) => m.id !== memoryId), ); }, }); } ``` There is no separate "skip" action. A swipe-to-skip is purely client-side — don't send a request and the memory simply stays in the queue for a later session. --- ## Next Steps - [Graph Memory](/concepts/graph-memory) — How inferred (`derive`) memories are created - [Memory Operations](/recall/memory-operations) — Create, forget, and update memories - [Search](/recall/search) — How inferred memories are ranked in results