Save it from anywhere.
#memory can be a shared memory for the tools you use. With your permission, connected applications and AI assistants can save useful information and find it again when you need it.
Connect an assistant with MCP setup, or jump to the API reference.
One memory across your tools
Imagine a meeting tool saving a client conversation in #memory. Before your next meeting, a connected AI assistant could find those notes and help you prepare. When the meeting tool updates its summary, it can update the same memory instead of adding another copy.
Information captured in one place becomes useful in another. You spend less time copying notes between tools or explaining the same background again. Each connection gives you another way to use the information you have already saved.
You control access
You give each application its own digital key, called a token. Choose whether it can read, save and update, or also delete memories. You can limit its access to memories with specific keywords, such as “work” or “clients”. Encrypted content stays unreadable through this connection.
You can revoke a key at any time to stop future access. Information an application has already read may still be held or processed by its provider.
What you can connect today
Developers can use the API below to build connections that save text, update memories their integration created, and find information by words or keywords. Saved memories appear across your #memory devices. A developer or a compatible tool needs to set up each connection; the meeting example above illustrates what they can build.
Updates and deletes through the API are limited to memories created through an integration. Deletion is currently limited to plain text memories; memories with attachments or sharing must be deleted in the #memory app.
Connect an AI assistant with MCP
Add the server below to your assistant’s custom connectors and choose OAuth. #memory opens a sign-in and approval page, then returns you to the assistant. Start with read access and optionally restrict the connection by keyword.
https://www.usememory.com/api/mcp
OAuth uses authorization code with required S256 PKCE, dynamic client registration, and approved assistant client-metadata hosts. Access tokens last one hour; rotating refresh tokens work within a 30-day connection. Reusing a refresh token revokes the connection. OAuth credentials work only on this MCP resource, never as app sessions or REST API keys.
Discovery: protected resource metadata and authorization server metadata. The resource indicator is https://www.usememory.com/api/mcp. Request read, optionally write, delete, and offline_access. The consent screen can grant fewer permissions than requested; respect the scopes returned with the token.
For manual setup, create a personal key in your account. Send Authorization: Bearer mem_YOUR_TOKEN. For VS Code Chat, add the following to your user MCP configuration. It prompts for the key so you do not have to save a secret in a project file.
{
"inputs": [
{
"type": "promptString",
"id": "memory-token",
"description": "#memory API token",
"password": true
}
],
"servers": {
"memory": {
"type": "http",
"url": "https://www.usememory.com/api/mcp",
"headers": {
"Authorization": "Bearer ${input:memory-token}"
}
}
}
}Ask “What was the place Dani recommended? Cite the memory you found.” The assistant can search your permitted memories, read the relevant matches, and use your existing keywords to try another search. An empty result means it did not find a match within its access. The assistant writes the answer; #memory supplies the evidence.
With write permission, ask “Remember that Dani recommended Cedar Café in Lisbon. Tag it restaurants and lisbon.” The assistant is instructed to save a clear note only when you ask, and to reuse suitable existing keywords. This is not automatic recording of your conversations. Configure your client to confirm saves and deletions.
Word and keyword search is available today. Browsing and synchronization tools remain available for those tasks. Technical tool success does not establish that the assistant found the right memory or answered correctly.
VS Code setup guide. The Chat view supports prompted inputs; the separate Agent Host has different configuration requirements. Revoke a connection or key in your account to stop future access. To change OAuth permissions, revoke and reconnect.
To monitor reliability, we collect hourly usage counts, timings, result counts and error categories linked to internal account and key IDs. These metrics do not include your search text, keywords, memory content or key secret. Reports cover up to 30 days; expired counters are removed by a daily cleanup job.
API reference
A token-authenticated JSON API for external systems — CRMs, automations, scripts, agents — acting on the token owner's memories. Mint tokens at /account. Every token can read all of the owner's memories (encrypted ones stay unreadable).
Scope "write" creates memories and updates the ones an integration created; scope "delete" deletes them while they are text-only (no attachments, never shared with a person, group or channel, no public link — anything else is deleted in the #memory app). Memories written in the app, and encrypted or read-only memories, are never changed or deleted. A token may be restricted to memories carrying one of its keywords; then search, fetch, list and counts all honour that restriction. Anything a connected application reads may be processed by that application's provider; revoking a token stops future access but cannot retract what was already read.
externalRef is your record's id (1–200 characters; no whitespace, slashes or control characters; not "." or ".." — those are unaddressable once URL-normalized; "id" is a reserved path word and the "memory:" prefix is reserved for generated refs).
A push with a known externalRef replaces the content and swaps the keywords that integration itself introduced; keywords the user added are always kept, even when the integration sends the same word. A keyword-restricted token can only create or update memories it can read back, and never touches a memory outside its restriction (403 outside_grant).
externalRefs are unique per account, not per token: a keyword-restricted token pushing to a ref that already names a memory outside its restriction gets 403 outside_grant under the plan limit, so it can learn that the ref exists, but never the memory's content or keywords. At the limit such a push gets 402 memory_limit_exceeded (503 billing_unavailable when the plan cannot be checked), and a generated "memory:" ref gets 400 invalid_request, exactly like an unused ref. Give each integration its own ref namespace, e.g. an "sf:" prefix for Salesforce records.
Pass sourceUpdatedAt to make late, out-of-order deliveries harmless. Errors are always { "error": message, "code": snake_code }.
Quick start
curl -X POST https://www.usememory.com/api/v1/memories \
-H "Authorization: Bearer mem_YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"content":"Acme Corp — renewal due 2026-12-01","keywords":["acme","renewal"],"externalRef":"sf:opp:006Xa0000012345","sourceUpdatedAt":"2026-09-24T10:00:00Z"}'POST/api/v1/memories
Creates a memory owned by the token owner, or updates the integration memory with the same externalRef. The memory appears on all of the owner's devices. A create counts toward the owner's plan memory limit, the same one the apps enforce.
Bearer mem_… personal API token (minted at /account) with scope "write" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Body
contentstring · required- 1–10 000 characters, trimmed
keywordsstring[] · required- 1–10; each trimmed, leading # removed, lowercased, 1–40 characters, no commas
externalRefstring · optional- your record id; present ⇒ update if it exists. Absent ⇒ a generated "memory:<uuid>" ref is returned
sourceUpdatedAtISO-8601 · optional- your record's modification time; a push not newer than the last applied one is skipped. Full timestamp with a zone offset required (e.g. "2026-09-25T12:00:00Z" or "2026-09-25T12:00:00.123+02:00") — a bare date like "2026-09-25" is rejected. Fractional seconds are compared at full precision, up to 6 digits (microseconds); more digits are rejected
Success
201 { "id", "externalRef", "outcome": "created" } · 200 { …, "outcome": "updated" | "stale" }Errors
- 400 invalid_request
- 401 invalid_token
- 402 memory_limit_exceeded (the owner's plan has no room for another memory; only creates are refused — updates to existing memories still apply)
- 403 account_unavailable (this account is being deleted)
- 403 insufficient_scope
- 403 outside_grant
- 409 memory_locked (encrypted or read-only)
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
- 503 billing_unavailable (the plan could not be checked; retry)
GET/api/v1/memories
Lists the owner's memories, most recently updated first. updatedSince polls for changed memories that still exist: deletions are not reported. To detect deletions, page through the full list and compare ids.
Bearer mem_… personal API token (minted at /account) with scope "read" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Query
limitinteger · optional- 1–100, default 50
cursorstring · optional- opaque; nextCursor from the previous page
updatedSinceISO-8601 · optional- only memories changed at or after this time. When polling, start each window a few seconds before the previous poll time: a write is stamped just before it commits. Full timestamp with a zone offset required (e.g. "2026-09-25T12:00:00Z") — a bare date like "2026-09-25" is rejected. At most 6 fractional-second digits
Success
{ "memories": [{ "id", "externalRef": string|null, "content", "keywords": string[], "createdAt", "updatedAt", "locked": boolean, "readOnly": boolean } — an encrypted memory is locked with content ""], "nextCursor": string|null }Errors
- 400 invalid_request
- 401 invalid_token
- 403 insufficient_scope
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
GET/api/v1/memories/{externalRef}
One memory by its externalRef (URL-encode it).
Bearer mem_… personal API token (minted at /account) with scope "read" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Success
{ "id", "externalRef": string|null, "content", "keywords": string[], "createdAt", "updatedAt", "locked": boolean, "readOnly": boolean } — an encrypted memory is locked with content ""Errors
- 400 invalid_request
- 401 invalid_token
- 403 insufficient_scope
- 404 not_found
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
GET/api/v1/memories/id/{id}
One memory by UUID, including memories written in the app, which have no externalRef.
Bearer mem_… personal API token (minted at /account) with scope "read" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Success
{ "id", "externalRef": string|null, "content", "keywords": string[], "createdAt", "updatedAt", "locked": boolean, "readOnly": boolean } — an encrypted memory is locked with content ""Errors
- 400 invalid_request (not a UUID)
- 401 invalid_token
- 403 insufficient_scope
- 404 not_found
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
DELETE/api/v1/memories/{externalRef}
Deletes a text-only memory an integration created. Only plain memories can be deleted through the API: a memory with attachments, one that was ever shared with a person, group or channel, or one with a public link answers 409 delete_in_app ("This memory has attachments, a public link or is shared with people; delete it in the #memory app.") and is left untouched. The memory enters a one-way deleting state first: edits from any device are refused, as are new attachments, shares and public links, a second delete request answers 409 deletion_in_progress, and if the work is interrupted at any point — even after the memory itself is gone — the server finishes and verifies it from a durable record of the operation. Memories written in the app, and memories outside a token's keyword restriction, cannot be deleted through the API.
Bearer mem_… personal API token (minted at /account) with scope "delete" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Success
204 (no body): irreversible deletion accepted; teardown and file cleanup may finish through background retries
Errors
- 400 invalid_request
- 401 invalid_token
- 403 account_unavailable (this account is being deleted)
- 403 insufficient_scope
- 404 not_found (no integration memory with that ref)
- 409 delete_in_app (the memory has attachments, a public link or is shared with people — delete it in the #memory app)
- 409 deletion_in_progress (already being deleted)
- 409 memory_locked
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
GET/api/v1/search
Ranks the memories this token can see by full-text relevance (keywords weigh more than body text), then recency. Encrypted memories and memories outside the token's keyword restriction never appear. Deletions are not reported here either.
Bearer mem_… personal API token (minted at /account) with scope "read" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Query
qstring · optional- full-text query, ≤ 200 characters; all words must match (quotes for phrases, - to exclude); language-neutral, so names, identifiers and Hebrew work as typed
keywordstring · optional- repeatable, one keyword per parameter (?keyword=acme&keyword=renewal); every keyword must be present; each value is one keyword, commas included, otherwise normalised like saved keywords (trimmed, leading # removed, lowercased), at most 10
limitinteger · optional- 1–50, default 20
Success
{ "hits": [{ "id", "externalRef": string|null, "title": string (first line, ≤ 80 chars), "snippet": string (≤ 200 chars), "keywords": string[], "updatedAt", "score": number }] } — evidence only; fetch the memory by id for its contentErrors
- 400 invalid_request (neither q nor keyword, or limit out of range)
- 401 invalid_token
- 403 insufficient_scope
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error
GET/api/v1/keywords
The owner's keywords with how many memories carry each: a map of what is saved, to consult before searching.
Bearer mem_… personal API token (minted at /account) with scope "read" — 401 invalid_token otherwise, 403 insufficient_scope without the scope
Query
limitinteger · optional- 1–500, default 200
offsetinteger · optional- from the previous page's nextOffset
Success
{ "keywords": [{ "keyword": string, "count": number }], "nextOffset": number|null } — most used firstErrors
- 400 invalid_request
- 401 invalid_token
- 403 insufficient_scope
- 429 rate_limited (120 requests/minute per token; honour Retry-After)
- 500 server_error