Docs

Give a model memory in four calls

Store a rule, read it back exactly, delete it with a receipt. No prompt engineering, and the cost does not grow as you add rules.

Sixty seconds

Create an account, make a key, then:

export HEBB_KEY=hebb_live_...
export BASE=https://hebb-site.pages.dev/v1

# teach it something
curl -s -X POST $BASE/rules -H "Authorization: Bearer $HEBB_KEY" \
  -H 'content-type: application/json' \
  -d '{"slot": "refund window", "value": "60 days"}'

# ask for it, by name
curl -s -X POST $BASE/ask -H "Authorization: Bearer $HEBB_KEY" \
  -H 'content-type: application/json' \
  -d '{"question": "how long do refunds take?", "slot": "refund window"}'
# {"value": "60 days", "confidence": 1.0, "latency_ms": 0.4, ...}

How to think about it

A rule is a named fact your application owns: slot is the name, value is the fact. Teaching the same slot twice revises it rather than opening a second one, so there is never a stale copy to reconcile.

Name the slot when you know it. Your application almost always does — it knows it is answering a refund question. That path returns the stored value exactly and makes no model call, which is why it runs in well under a millisecond. Leaving slot out asks the memory to work out which rule you meant, and the response says which one it picked and how sure it is so you can decide whether to trust it.

The credential identifies you. There is no tenant parameter anywhere in this API, which is deliberate: an endpoint that accepted one would be a single forged field away from serving another customer's data.

Why not just put it in the prompt

Because the prompt is charged for on every request, and it grows every time you add a rule. Hebb’s cost does not: the read is the same work whether you have stored three rules or three hundred.

That means the two cross. Below roughly a dozen rules per customer, prompting is cheaper and you should use it. Above it, the gap widens with every rule you add — which is the unusual part, because most things get relatively more expensive as an account grows rather than less. The measured numbers, including the ones that went against us, are on the benchmarks page.

Authentication

Authorization: Bearer hebb_live_<your key>

Keys are shown once, at creation. Only a hash is stored, so a lost key is replaced rather than recovered. An account holds up to three — development, staging, production — and revoking one frees the slot.

A key cannot create or list keys. That is the point of the limit: if it could, revoking a leaked key would achieve nothing, because whoever held it would issue themselves another first. Key management needs a signed-in session.

Endpoints

POST /v1/rules — teach a rule

{"slot": "refund window", "value": "60 days"}
→ {"slot": "refund window", "version": 1, "bytes": 7}

Repeating a slot increments version. Revising a rule is allowed even at your memory limit, because a full account has the most rules worth keeping correct.

POST /v1/ask — read one back

{"question": "how long do refunds take?", "slot": "refund window"}
→ {"value": "60 days", "confidence": 1.0, "page_used": "refund window",
     "latency_ms": 0.4, "note": "slot supplied by the caller..."}

slot is optional. With it the answer is exact. Without it, check page_used and confidence before you use the answer — and value is null when nothing matched, rather than a guess.

GET /v1/rules — everything you have stored

→ {"rules": [{"slot": "refund window", "value": "60 days", "version": 1}]}

DELETE /v1/rules/{slot} — forget, with proof

→ {"deleted": true,
     "receipt": {"receipt_id": "rcpt_...", "store_entry_removed": true,
                 "verified": true, "issued_at_iso": "..."}}

The receipt reports the result of re-reading after the delete, not the intention to delete. Retrieval-into-context cannot report this and a merged adapter cannot do it at all. Deletion is never refused for being over a limit, on any plan, for any reason.

GET /v1/usage — what you have spent

→ {"quota": {"plan": "free",
                "requests": {"used": 12, "allowed": 10000},
                "writes":   {"used": 3,  "allowed": 500},
                "memories": {"used": 3,  "allowed": 50}}}

Errors

Every failure is RFC 9457 application/problem+json, with a detail written to be read by a person.

StatusMeansDo
400the request is malformedread detail
401the key was not acceptedcheck it, or that it is not revoked
402a plan limit is spentthe body names which one and when it resets
409you already hold three keysrevoke one to free a slot
429too fastback off; Retry-After says how long

A spent quota is 402 and not 429 on purpose: a correct client retries a 429 forever, and a month that is spent is not a timing problem.

Free plan

LimitFreeWhy
Questions10,000 / monthnaming the rule makes no model call, so these cost almost nothing to serve
Rules taught500 / montha write is the expensive operation
Rules stored50kept inside the range where finding a rule from plain English still works
Rate5 / seconda month of quota spent in a minute is an outage for everybody else
API keys3development, staging, production

What the hosted tier is, and is not

The hosted free tier stores your rules in a database. Naming the slot behaves exactly as it does in the full build — that path returns the stored value and makes no model call there either — so anything you build against it keeps working.

What is not here is the model. Free-text questions are answered by matching against rule names, and the response says so rather than presenting a guess as memory. A model that reads this memory while it generates, with the memory held as page tensors rather than rows, is the self-hosted build below.

Running it yourself

One container, no GPU required, and the same console behind the same sign-in at your own address. Nothing is held back from the self-hosted build.

docker run -p 8080:8080 \
  -e HEBB_ACCOUNTS=1 \
  -e HEBB_KEK="$(python -m hebb.serve.crypto --new-kek | tail -1)" \
  -e HEBB_ADMIN_KEY="$(openssl rand -base64 32)" \
  hebb-serve

There, memories are encrypted page tensors on your disk, reads run through the model, and deletion zeroes and releases the page before the receipt is written. Your data does not leave your perimeter and there is no per-request ceiling, because it is your hardware. Ask about a licence.