Store memories
This guide shows how to send information to Alvia with POST /v1/memories. To send a whole
chat, see Import conversations.
For endpoint schemas and status codes, use the API reference.
Send a passage
Section titled “Send a passage”By default, Alvia reads content as a passage and forms one memory from each durable fact in
it. Send text as your application receives it: a note, a message or a summary of a step.
curl https://api.alvia.ai/v1/memories \ -H "Authorization: Bearer $ALVIA_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "Dana Reyes leads the Atlas migration. The team agreed to freeze schema changes until the cutover on October 6.", "occurred_at": "2026-09-28T16:30:00-04:00", "scope": { "organization_id": "acme", "application_id": "eng-assistant" } }'import osimport requests
API_KEY = os.environ["ALVIA_API_KEY"]
response = requests.post( "https://api.alvia.ai/v1/memories", headers={"Authorization": f"Bearer {API_KEY}"}, json={ "content": ( "Dana Reyes leads the Atlas migration. The team agreed " "to freeze schema changes until the cutover on October 6." ), "occurred_at": "2026-09-28T16:30:00-04:00", "scope": { "organization_id": "acme", "application_id": "eng-assistant", }, }, timeout=30,)response.raise_for_status() # 202 Accepted, empty bodyconst response = await fetch("https://api.alvia.ai/v1/memories", { method: "POST", headers: { Authorization: `Bearer ${process.env.ALVIA_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify({ content: "Dana Reyes leads the Atlas migration. The team agreed " + "to freeze schema changes until the cutover on October 6.", occurred_at: "2026-09-28T16:30:00-04:00", scope: { organization_id: "acme", application_id: "eng-assistant", }, }),});// 202 Accepted, empty bodyif (!response.ok) { throw new Error(`${response.status}: ${await response.text()}`);}package main
import ( "bytes" "encoding/json" "io" "log" "net/http" "os" "time")
func main() { payload, err := json.Marshal(map[string]any{ "content": "Dana Reyes leads the Atlas migration. The team " + "agreed to freeze schema changes until the cutover " + "on October 6.", "occurred_at": "2026-09-28T16:30:00-04:00", "scope": map[string]string{ "organization_id": "acme", "application_id": "eng-assistant", }, }) if err != nil { log.Fatal(err) } req, err := http.NewRequest(http.MethodPost, "https://api.alvia.ai/v1/memories", bytes.NewReader(payload)) if err != nil { log.Fatal(err) } key := os.Getenv("ALVIA_API_KEY") req.Header.Set("Authorization", "Bearer "+key) req.Header.Set("Content-Type", "application/json")
client := &http.Client{Timeout: 30 * time.Second} resp, err := client.Do(req) if err != nil { log.Fatal(err) } defer resp.Body.Close() // 202 Accepted, empty body if resp.StatusCode != http.StatusAccepted { body, _ := io.ReadAll(resp.Body) log.Fatalf("%s: %s", resp.Status, body) }}using System.Net.Http.Json;
var key = Environment.GetEnvironmentVariable("ALVIA_API_KEY");using var http = new HttpClient();http.Timeout = TimeSpan.FromSeconds(30);http.DefaultRequestHeaders.Authorization = new("Bearer", key);
var response = await http.PostAsJsonAsync( "https://api.alvia.ai/v1/memories", new { content = "Dana Reyes leads the Atlas migration. The team " + "agreed to freeze schema changes until the cutover " + "on October 6.", occurred_at = "2026-09-28T16:30:00-04:00", scope = new { organization_id = "acme", application_id = "eng-assistant", }, });response.EnsureSuccessStatusCode(); // 202 Accepted, empty bodyIn this example the passage forms two memories: who leads the migration, and the schema freeze.
Send one statement as one memory
Section titled “Send one statement as one memory”Set infer to false to store content as a single memory. Use it when your text is already
one fact, such as a value from a form or a record you have already summarized.
{ "content": "Acme's billing contact is ap@acme.example.", "infer": false, "scope": { "organization_id": "acme" }}With infer: false, content can be at most 1,000 characters. Alvia normalizes the wording and
adds resolved dates.
Decide what should become memory
Section titled “Decide what should become memory”Set the project’s memory policy before you send information that could hold sensitive facts: its keyword and meaning exclusions keep matching facts from becoming memory. See Filter memories and Memory policies.
Send older information with its original occurred_at, so it is ranked by its real age. See
Point-in-Time Reasoning and change over
time.
Request fields
Section titled “Request fields”| Field | Required | Description |
|---|---|---|
content |
Yes | The text: 1 to 32,000 characters, with at least one letter or digit. At most 1,000 when infer is false. |
infer |
No | true (default) forms a memory from each fact in the text. false stores the text as one memory. |
occurred_at |
No | When the text was stated or observed, as an ISO 8601 date-time. Defaults to now. See Point-in-Time Reasoning and change over time. |
scope |
No | Who or what the memory is about. See Projects and scope. |
Send only these fields: an unknown field returns 400 validation_error.
Response
Section titled “Response”A successful write returns 202 with an empty body. Formation runs after the response and forms
one memory from each durable fact. Formation finishes in
less than a minute, so find the memories with search,
recall or list shortly after the write. See Read memories.
Each write uses your plan’s monthly write allowance:
- A write with
infer: falseuses one write. - A passage uses one write, plus one write for each fact that formation takes from it.
Alvia accepts writes up to your plan’s monthly write allowance, which resets each month. At the
stored-memory limit, writes return 409. See Limits and allowances.
Retries
Section titled “Retries”Retry only requests that failed: network errors, 5xx responses and 429 responses, after the
wait in Retry-After. A 202 means Alvia accepted the write, so do not send it again. When you
retry, send the same content and occurred_at. Each accepted request uses writes.
- A
429withmonthly_write_quota_reachedsucceeds only after the allowance resets. See Production checklist. - Do not retry a
400. Fix the request first.
Errors
Section titled “Errors”| Error | Cause |
|---|---|
400 validation_error |
A field is missing, too long or unknown. errors names each field. |
400 invalid_argumentoccurred_at_in_future |
occurred_at is in the future. |
400 invalid_argumentoccurred_at_too_old |
occurred_at is before 1970. |
401 unauthorized |
The API key is missing or not valid. |
404 not_found |
The project’s deletion started while the request was in progress. |
409 conflictmemory_limit_reached |
The account holds its plan’s stored-memory limit. |
429 rate_limit_exceeded |
Too many requests per second. |
429 rate_limit_exceededmonthly_write_quota_reached |
The monthly write allowance is used up. |
See Errors for every code.