docsagents
make an agent, give it a memory, recall from it, and forget, over plain https.
3 pages

the agents api

Base url https://innernet.live/api/v1. Every call takes Authorization: Bearer <key>. Bodies and answers are JSON, snake_case.

keys#

keymade wheremay do
your own key (innernet_…, read + write)dashboard → connections → apimake, change and remove agents; act on any of your agents by slug
an agent keyyour agents space → an agent → keys (it is shown once when you make the agent there; an agent made through the API starts with no key of its own)that one agent's memory, and the person's own memory only as deep as they allow (person.read). Use me for its slug

An agent key is a server secret: never ship it to a browser or a mobile app. It reaches every memory that agent keeps, its users' included.

make an agent#

bash
curl https://innernet.live/api/v1/agents \
  -H "Authorization: Bearer $INNERNET_KEY" \
  -d '{ "name": "support desk", "kind": "product", "purpose": "answers our customers about orders" }'

kind is personal (it works for you) or product (it works for other people). settings is optional; every setting has a default (agent settings).

Add "parent": "support-desk" (a slug or an id) to make a sub-agent under one of your top-level agents. It takes the parent's kind and a copy of its settings, so settings here changes only what you name; it keeps a memory and keys of its own. Two levels only (a sub-agent cannot have sub-agents), at most 50 under one agent, and your 100 agents count them. Every agent says the slug of the one it works under in parent (null for a top-level agent). Removing an agent that has sub-agents answers 409 until they are removed; the dashboard asks, then removes them together.

remember#

bash
curl https://innernet.live/api/v1/agents/support-desk/memories \
  -H "Authorization: Bearer $INNERNET_KEY" \
  -d '{ "user_id": "cus_8f2a",
        "messages": [{ "role": "user", "content": "i run three stores and ship on mondays" }] }'
fieldwhat it does
content or messageswhat to keep: a text, or a conversation (role user · assistant · system · tool)
inferpull separate memories out of it (the default), or keep the text as given
subjectagent · owner · user. When absent: the extraction decides, or user when user_id is given
user_idone of the agent's users
dimensionfor a memory about you: the part of your life it belongs to (preferences, tools, habits …). A name that is not one is refused
run_ida run, a thread or a session; run memories expire after retention.run_days
kindfact · preference · episode · procedure · instruction · note (for infer: false)
tags · metadata · importance (1–5)yours to set and filter by
immutablenever changed and never replaced by a newer version
event_atwhen it happened, for backfilling
expires_at or ttl_dayswhen it is deleted
instructionsextra rules for this call's extraction

The answer lists what was kept, what was offered to you (about_you), what was skipped and why (an exact duplicate, an excluded topic, a kind turned off), and how many emails, phone numbers, secrets and card numbers were hidden first. A near-duplicate of something it already keeps (nearly the same words) becomes a new version of it; GET …/memories/{id}/history shows the chain. A changed fact ("ships on fridays", then "ships on mondays") is not nearly the same words: change the old memory with PATCH, and that makes the new version.

recall#

bash
curl https://innernet.live/api/v1/agents/support-desk/recall \
  -H "Authorization: Bearer $INNERNET_KEY" \
  -d '{ "query": "when do they ship?", "user_id": "cus_8f2a", "limit": 5 }'

Without a user_id (or a subject), recall reads the agent's own memories and what it keeps about you, never its users': one customer's prompt is never built from another's memories because a field was forgotten. Recall ranks by the words of the query, by recency and by importance, and with rerank: true re-reads the best matches by meaning. include_person: true adds the facts of yours the agent may read. Filters take and · or · not over kind, subject, user_id, run_id, tags, importance, created_at, event_at, expires_at and metadata.<key>, with eq ne in nin gt gte lt lte contains exists:

json
{ "query": "setup", "filters": { "and": [ { "kind": { "in": ["fact", "preference"] } }, { "metadata.store": "north" } ] } }

context#

POST /agents/{agent}/context answers with one block ready for a system prompt: what the agent knows and what it knows of this user, trimmed to budget_tokens. What it may know of you is added when the agent's recall.include_person setting is on and person.read is not none.

the rest#

methodpathwhat
GET/agentsyour agents, sub-agents included (each says its parent)
GET · PATCH · DELETE/agents/{agent}read, change (status: "paused" pauses), remove
GET/agents/{agent}/memorieslist, newest first: subject, user_id, run_id, kind, tag, limit, cursor. Answers { memories, next_cursor }; pass next_cursor back as cursor (an ISO time, null on the last page)
GET · PATCH · DELETE/agents/{agent}/memories/{id}one memory; changing its words makes a new version
GET/agents/{agent}/memories/{id}/historyits versions
POST/agents/{agent}/forgetby ids or filters, with dry_run
DELETE/agents/{agent}/users/{user_id}everything about one of its users, with a count
GET/agents/{agent}/exportthe agent and every memory
GET/agents/{agent}/eventsits ledger: what it did, as counts

errors#

{ "error": code, "message": "…" } with 404 not_found (no such agent for this key), 403 forbidden (an agent key managing agents), 423 paused, 400 invalid, 409 conflict (a slug taken, an immutable memory), 429 rate_limited, 413 too_large.

webhooks#

Set one in the agent's settings in your agents space; there is no API for it yet, and the signing secret is shown once when you save. Every delivery is a POST with x-innernet-event and x-innernet-signature: t=<unix>,v1=<hex>, where v1 is HMAC-SHA256 of <t>.<body> with the agent's signing secret. Events: memory.created, memory.updated, memory.forgotten, funnel.held, funnel.decided (with decision: keep or decline to a held ask, send when you move a memory into your memory by hand, withdraw when you take one back). One attempt, five seconds; the last answer shows in the dashboard.

clients#

python
from innernet import Innernet

desk = Innernet().agent("support-desk")      # reads INNERNET_API_KEY
desk.remember("ships on mondays", user_id="cus_8f2a")
desk.recall("when do they ship?", user_id="cus_8f2a")
desk.forget_user("cus_8f2a")
ts
import { Innernet } from "@innernet/sdk";

const desk = new Innernet({ apiKey: process.env.INNERNET_API_KEY! }).agents.of("support-desk");
await desk.remember({ content: "ships on mondays", userId: "cus_8f2a" });
await desk.recall({ query: "when do they ship?", userId: "cus_8f2a" });