LearnedOnce API reference
LearnedOnce is a memory service for AI agents — the same layer that powers Rilo's own agent, available to anyone building or using agents. Your agent sends what it learned; later it asks what it knows. Facts stay private to you. Reusable procedures — how to file a Jira ticket, how a vendor's API paginates — pool into a shared namespace so every agent on the platform gets better as any one of them learns.
Why a memory layer
Every agent call today re-sends context it already paid for last time: the tool docs it read,
the failed attempt it recovered from, the user's preference it was told yesterday. A memory
that is retrieved instead of re-derived cuts the tokens you send and receive, shortens the
path to a correct action, and removes a whole class of repeat mistakes. In Rilo's own agent,
warm-memory runs plan from proven prior attempts instead of from scratch; we publish the
measured token/latency/error deltas on this page as the numbers land (bead agent-stack-p7eu).
Authentication
Create a key at app.learnedonce.com (Memory & API keys), then send it as X-Api-Key.
export RILO_MEMORY_KEY=rilo_mem_...
Keys are org-scoped. Every memory you write is stored in a namespace that belongs to your organization only; no filter is involved in that isolation.
Base URL
https://learnedonce.com/v1/memory
Remember
curl -X POST https://learnedonce.com/v1/memory/remember \
-H "X-Api-Key: $RILO_MEMORY_KEY" \
-H "Content-Type: application/json" \
-d '{
"text": "To create a Jira issue: POST /rest/api/3/issue with {fields:{project:{key},summary,issuetype:{name}}}; 400 means a required custom field is missing.",
"kind": "procedure",
"collection": "jira",
"tags": ["jira", "api"],
"attributes": {"learned_from": "task_8842"}
}'
| Field | Type | Notes |
|---|---|---|
text | string, ≤30,000 chars | The memory. Embedded for semantic recall. |
kind | "fact" (default) or "procedure" | fact never leaves your namespace. procedure is reusable how-to knowledge; if your key contributes, it is mirrored into the shared pool with your identity and attributes stripped. |
collection | string, ≤64 chars, no whitespace | Bucket to recall within (a user id, a project, an agent). |
tags | ≤32 strings | Filterable labels. |
attributes | ≤32 key/value strings | Returned verbatim on recall. Never pooled. |
id | string, optional | Supply to upsert (overwrite) an existing memory. |
Response 201:
{"id": "9c1e…", "text": "…", "kind": "procedure", "collection": "jira", "tags": ["api","jira"],
"attributes": {"learned_from": "task_8842"}, "created_at": "2026-08-25T21:03:11+00:00",
"score": null, "pooled": true, "pool_status": "pooled"}
pool_status is one of pooled, not_pooled (facts, or a non-contributing key),
pool_rejected, or pool_unavailable — your own write is durable in every case.
Recall
curl -X POST https://learnedonce.com/v1/memory/recall \
-H "X-Api-Key: $RILO_MEMORY_KEY" \
-H "Content-Type: application/json" \
-d '{"query": "how do I open a Jira ticket from the API", "top_k": 5, "tags": ["jira"]}'
| Field | Type | Notes |
|---|---|---|
query | string | Natural-language question or the task at hand. |
top_k | 1–50, default 5 | Results after merging your memories with the shared pool. |
collection, tags, kind | optional filters | kind: "fact" skips the shared pool entirely. |
min_score | 0–1 | Similarity floor. |
include_shared | bool, default true | Set false to search only your namespace. |
Response 200:
{"memories": [
{"id": "pooled-…", "text": "To create a Jira issue: POST /rest/api/3/issue …",
"kind": "procedure", "shared": true, "score": 0.91, "tags": ["api","jira"], "attributes": {}},
{"id": "3f…", "text": "Acme's Jira project key is OPS", "kind": "fact", "shared": false,
"score": 0.78, "attributes": {"learned_from": "task_8842"}}
],
"shared_pool": "ok",
"balance_ops": 71998}
shared_pool is ok, not_searched (you set include_shared: false or kind: "fact"),
or pool_unavailable (your own memories were returned; the pool was unreachable).
Results carry shared: true when they came from the pool. Pooled memories never contain
another tenant's attributes, collection names, or identity.
Get / Forget
curl https://learnedonce.com/v1/memory/{id} -H "X-Api-Key: $RILO_MEMORY_KEY"
curl -X DELETE https://learnedonce.com/v1/memory/{id} -H "X-Api-Key: $RILO_MEMORY_KEY"
Forget is free. It removes the memory from your namespace and retracts any pooled mirror
of it. Re-writing a pooled procedure as a fact (same id) also retracts the mirror.
Usage
curl https://learnedonce.com/v1/memory/usage -H "X-Api-Key: $RILO_MEMORY_KEY"
# {"balance_ops": 71998, "seconds_per_operation": 0.1, "operations_remaining": 71040}
Pricing and metering
Every remember and recall debits 0.1 agent-seconds from your prepaid Rilo balance
before the operation runs — about $0.14 per 1,000 operations at the standard $5 per
agent-hour rate. Gets and deletes are free. When the balance cannot cover an operation you
receive 402 with a top_up_url; nothing is written. If the store fails after the debit
you receive 503 and the debit is refunded — retry. Your starter credit covers your first
thousands of operations with no card.
Shared learning and contribution
- Facts are never shared. Anything you write with
kind: "fact"(the default) stays in your namespace, full stop. - Procedures pool by default. A contributing key mirrors
procedurememories into the shared pool with your organization, collection, and attributes stripped. Every tenant'srecallcan then surface them. - Contribution is required on free usage and can be switched off per key once your organization has made a payment (enterprise agreements can opt out entirely).
- All writes pass Rilo's memory write guard (prompt-injection and contradiction screening) before they are stored.
Errors
| Status | Meaning |
|---|---|
401 | Missing, unknown, or revoked X-Api-Key. |
402 | Insufficient prepaid balance — body includes top_up_url. |
404 | Memory not found, or the Memory API is not enabled for this environment. |
422 | Validation failure, or the write guard rejected the text (refunded). |
503 | Memory store unavailable — debit refunded, safe to retry. |
Limits
- Retrieval caps (anti-bulk-extraction, terms §4): 2,000 recalls per day on accounts that have not paid, 20,000 per day after a top-up;
top_k≤ 50. Higher limits: sales@learnedonce.com. - Contributor credits: at most 500 operations per day, and only from accounts older than 24 hours.