API Reference
Add Memory
Create a new memory record through the extraction pipeline. The handler authenticates the caller, resolves the effective end user, and either accepts the candidate (returning a memory id) or records a structured discard reason.
POST/memory/add
Authentication
Accepts a JWT bearer token (Authorization: Bearer eyJ…) or an API key (X-API-Key: ms_live_…). API-key callers should send X-Project-ID unless the key is project-locked. Cross-tenant operators must send X-Tenant-ID.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
text | string | required | The text to store. content is accepted as an alias and normalised into text. |
metadata | object | optional | Caller-controlled JSON. Filterable at query time. |
tags | string[] | optional | Free-form labels. |
importance | number | optional | 0..1 hint to the ranker. |
session_id | string | optional | Links the memory to a chat session. |
request.json
{"text": "User prefers dark mode and concise responses.","metadata": {"source": "chat","user_id": "u_42"}}
Response
Returns 200 OK with the following body.
| Field | Type | Required | Description |
|---|---|---|---|
id | integer | optional | Server-assigned memory id. |
status | string | optional | pending until embedding lands; then embedded. |
decision | string | optional | created, discarded_low_signal, discarded_redundant, … |
extracted_type | string | optional | Classification (fact, event, decision, …). |
created_at | string | optional | RFC 3339 UTC timestamp. |
200.json
{"id": 184213,"status": "pending","decision": "created","extracted_type": "fact","created_at": "2026-05-04T12:30:11Z"}
Errors
| Status | Code | Description |
|---|---|---|
| 400 | validation_error | Body or query failed schema validation. The error includes the offending field name. |
| 401 | unauthenticated | Missing or invalid bearer token / API key. |
| 403 | forbidden | Authenticated principal lacks the required scope, role, or project access. |
| 404 | not_found | Target resource does not exist or is not visible to the calling tenant. |
| 429 | rate_limited | Per-IP or per-route limit exceeded. Respect the Retry-After header. |
| 500 | internal_error | Unhandled server error. Quote the request_id when contacting support. |
Examples
cURL
curl -X POST https://api.memorysync.io/memory/add \-H "Authorization: Bearer $MEMORYSYNC_KEY" \-H "Content-Type: application/json" \-d '{"text": "User prefers dark mode and concise responses.","metadata": {"source": "chat","user_id": "u_42"}}'
javascript
import { MemorySync } from 'memorysync'const client = new MemorySync({ apiKey: process.env.MEMORYSYNC_KEY })const result = await client.request({method: 'POST',path: '/memory/add',body: {"text": "User prefers dark mode and concise responses.","metadata": {"source": "chat","user_id": "u_42"}},})console.log(result)
python
from memorysync import Clientclient = Client(api_key=os.environ["MEMORYSYNC_KEY"])result = client.request(method="POST",path="/memory/add",json={"text": "User prefers dark mode and concise responses.","metadata": {"source": "chat","user_id": "u_42"}},)print(result)
Behavior & notes
Idempotent through Idempotency-Key; replays within 24h return the original response unchanged. Embedding is queued asynchronously — the response returns before the vector lands.
When your organisation is over its monthly write quota, the route silently returns 200 with {"status":"ok"} and the memory is not stored. No error is surfaced to the caller. Watch the usage dashboard or configure quota alerts to detect this state.