Skip to main content

HTTP quickstart

llmslim serve: the same memory behind a small JSON API, for apps in any language.

5 min readUpdated November 2026

Install and run

One process and one SQLite file. Without a key it binds only the loopback interface, and needs no key there.

terminalbash
pip install "llmslim[server]"
llmslim serve          # http://127.0.0.1:8080

Serve other machines

To serve a network, set one or more keys; clients then send Authorization: Bearer <key> on every /v1 request. Keys are compared in constant time and must be at least 16 characters; --new-key prints a random 43-character one.

terminalbash
export LLMSLIM_API_KEYS="$(llmslim serve --new-key)"
llmslim serve --host 0.0.0.0 --port 8080 --db /var/lib/llmslim/memory.db

Keyless means this machine only

A keyless server is reachable from any web page the user opens, so it answers only requests addressed to this machine by name (localhost, 127.0.0.1, [::1] or a *.localhost name) that no other web page sent. Other requests get a 403. Clients that send no Origin, such as curl, SDKs and the TypeScript client, are not affected. If clients reach it by another name, such as host.docker.internal from a container, add the name with --allowed-host or LLMSLIM_ALLOWED_HOSTS.

Routes

Bodies and responses are JSON. Errors look like {"error": {"type": "invalid_request", "message": "..."}}. When Postgres or MongoDB can't be reached, the answer is a 503 with "type": "store_unavailable" and Retry-After: 5: retry it.

Method and pathBody or queryReturns
POST /v1/memoriesmessages (a string, a {role, content} object or a list of them), at least one of user_id, agent_id, run_id, optional timestamp, metadata201 {"items": [...]}, the stored messages
GET /v1/memories?user_id=&agent_id=&run_id=&since=&until=&limit=100&offset=0{"items", "total", "offset", "limit"}, oldest first
GET /v1/memories/{id}One message
PATCH /v1/memories/{id}content and/or metadataThe updated message
DELETE /v1/memories/{id}{"deleted": 1}
DELETE /v1/memories?user_id= (or agent_id, run_id; one is required){"deleted": n}
POST /v1/memories/searchquery, the scope, optional budget, relevance ("lexical" or "semantic"), since, until, explain{"text", "tokens", "budget", "history_tokens", "sessions_total", "sessions_kept", "turns": [...]}, and "explanation" with "explain": true (guide)
POST /v1/context/fittext, budget (default 2000), optional query{"text", "tokens", "original_tokens"}, within about 2% of the budget for any text
GET /v1/infoName, version and budgets
POST /v1/chat/completions, GET /v1/modelsAn OpenAI chat-completions requestThe upstream's answer, with memory; 404 unless started with --upstream-url (experimental)
GET /healthz{"status": "ok"}, without a key

Options

Flags win over environment variables.

FlagEnvironment variableDefault
--hostLLMSLIM_HOST127.0.0.1
--portLLMSLIM_PORT8080
--db (a SQLite path or a database URL)LLMSLIM_MEMORY_DB~/.llmslim/memory.db
--api-key (repeatable)LLMSLIM_API_KEYS (comma-separated)none
--budget2000 tokens for search

To run several processes or machines on one memory, point --db at Postgres: see Storage backends.

From Python

create_app gives you the ASGI app, to run with any ASGI server or mount in your own.

app.pypython
from llmslim.memory import Memory
from llmslim.server import create_app

app = create_app(Memory("memory.db"), api_keys=["<a key of 16+ characters>"])  # any ASGI server can run it

Questions

Can I call it from a browser?

No. A key gives full access to every user's memory, so call the server from your backend, and map your own users to user_id there.

Does the server call a model?

Not for memory or fit: they run no model, and nothing leaves your infrastructure.

Does it speak TLS?

No, plain HTTP. Put a reverse proxy or load balancer that terminates TLS in front of it.