/community/give an agent a memory
innernet
docsskillscommunitycompanycomparesecurityprivacytermscontact

a skill, kept by innernet

give an agent a memory

paste this link into your ai. it will know what to do.

/skills/agent-memory

wire a long-term memory into an ai agent someone is building (a support bot, an assistant, a slack or discord bot, a research script) with two web requests: one before it answers, to remember what matters, and one after, to keep what was said. no sdk to install, any language, ten minutes.

kindskill
when to load itwhen someone pastes this link with an agent key and asks you to add memory to their agent, bot or assistant, or asks how their agent can remember people and conversations between runs.
version1.0.0
last tended2026-10-19
kept byinnernet
reuseCC BY 4.0
reading5 min

give an agent a memory

you are helping someone give the agent they are building a memory that lasts between conversations. it takes two requests to one endpoint. read this whole page, then do it for them in their code, then show them it works.

what they gave you

  • an agent key, starting innernet_. it is a server secret: it reaches this one agent's memory and nothing else of theirs.
  • put it in an environment variable named INNERNET_AGENT_KEY (their .env, their host's secrets, wherever the project keeps secrets). add .env to .gitignore if it is not there.
  • never write the key into source code, never send it to a browser or a mobile app, never print it in logs. if they pasted it in the chat, tell them where you put it.
  • no key yet? ask them to make one: on innernet.live, connections → the agents you keep → make an agent of your own. the key is shown once, when it is made.

the base url is https://innernet.live/api/v1/agents/me (me is whichever agent the key belongs to). every request is a POST with Authorization: Bearer <key> and a JSON body.

first, find the turn

look through their code for the place where one turn happens: a message comes in, the model is called, a reply goes out. that is where both requests go. if there are several (a chat route, a webhook handler, a cli loop), use the one they actually run, and ask if it is unclear.

then ask yourself one question: does this agent talk to many different people (customers, users, members of a server)? if it does, every request carries a user_id: a stable id for the person it is talking to (their account id, a slack user id, an email): 1 to 128 characters of letters, numbers and _ . : @ -. memories are kept per person, and one person's memories never reach another's answer. if it is a personal agent that only ever talks to its owner, leave user_id out.

before it answers: what it remembers

POST https://innernet.live/api/v1/agents/me/context
{ "query": "<the incoming message>", "user_id": "<the person, if any>" }

the answer has text: one block, ready to drop into the system prompt, holding what the agent knows and what it knows about this person. add it under a short heading such as what you remember. when text is empty there is nothing yet, which is normal on day one. if the request fails or takes longer than about two seconds, answer without it: memory must never stop the agent from replying.

after it answers: what to keep

POST https://innernet.live/api/v1/agents/me/memories
{ "messages": [ { "role": "user", "content": "<their message>" }, { "role": "assistant", "content": "<the reply>" } ],
  "user_id": "<the person, if any>" }

innernet reads the exchange, keeps only what is worth keeping (a preference, a fact, a decision, how a task is done), sorts each piece by what kind of thing it is, and hides email addresses, phone numbers, keys and card numbers before anything is stored. send it after the reply has gone out, without waiting on it: keeping should never slow the answer down. the answer lists what was kept.

a helper to start from

adapt it to their stack and their style; keep both calls this small.

typescript (any runtime with fetch):

const MEMORY = "https://innernet.live/api/v1/agents/me";
const headers = { Authorization: `Bearer ${process.env.INNERNET_AGENT_KEY}`, "Content-Type": "application/json" };

export async function remembered(query: string, userId?: string): Promise<string> {
  try {
    const res = await fetch(`${MEMORY}/context`, { method: "POST", headers, body: JSON.stringify({ query, user_id: userId }), signal: AbortSignal.timeout(2000) });
    return res.ok ? ((await res.json()).text ?? "") : "";
  } catch {
    return ""; // answer without memory rather than not at all
  }
}

export function keep(userMessage: string, reply: string, userId?: string): void {
  void fetch(`${MEMORY}/memories`, {
    method: "POST",
    headers,
    body: JSON.stringify({ messages: [{ role: "user", content: userMessage }, { role: "assistant", content: reply }], user_id: userId }),
  }).catch(() => {});
}

python (requests):

import os, threading, requests

MEMORY = "https://innernet.live/api/v1/agents/me"
HEADERS = {"Authorization": f"Bearer {os.environ['INNERNET_AGENT_KEY']}"}

def remembered(query, user_id=None):
    try:
        body = {"query": query, **({"user_id": user_id} if user_id else {})}
        r = requests.post(f"{MEMORY}/context", headers=HEADERS, json=body, timeout=2)
        return r.json().get("text", "") if r.ok else ""
    except requests.RequestException:
        return ""  # answer without memory rather than not at all

def keep(user_message, reply, user_id=None):
    body = {"messages": [{"role": "user", "content": user_message}, {"role": "assistant", "content": reply}], **({"user_id": user_id} if user_id else {})}
    threading.Thread(target=lambda: requests.post(f"{MEMORY}/memories", headers=HEADERS, json=body, timeout=10), daemon=True).start()

leave user_id out of the body entirely when there is no person (as both helpers do): a null is not the same as no field.

show them it works

  1. 1run one turn of their agent with a message that says something worth keeping, such as "i prefer short answers, and i'm in lisbon".
  2. 2run a second turn that needs it, such as "what time is it where i am?". the reply should use what was kept.
  3. 3tell them to open innernet.live → connections → the agents you keep → their agent: memory shows what it kept, sorted by kind, and activity shows each call.

if a request answers 401, the key is wrong or was not loaded into the environment. 404 means the key is not an agent key. 429 means a limit was reached for the minute; it clears on its own.

what they can change later, without code

on their agent's page in innernet: access decides what the agent may read of them and whether what it learns about them reaches their own memory (sealed · asks first · trusted). settings decides what it keeps, what it never keeps, when it forgets, and how much it brings back. nothing in their code has to change for any of it.

going further

  • forget everything about one person: DELETE https://innernet.live/api/v1/agents/me/users/<user_id>.
  • recall a list instead of a block: POST …/me/recall with { "query": "...", "user_id": "...", "limit": 5 }.
  • the whole api, with every field: https://innernet.live/docs/agents-api

keep it where your ai can reach it.

innernet is memory your ai tools read live — every skill, every project, every decision, in one place, connected once. save this skill to yours, or publish one of your own as a link like this.

save it to your innernetsee every skill