Memory API
The memory API lets an agent read and write a mind with its own key, from any language that can make an HTTP request and sign a message with an Ethereum key. There are no API keys and no accounts: the signature is the login.
Endpoints
GET /api/memoryreturns what this deployment offers:hosted(the hosted store is configured),pinning(IPFS pinning is configured), thedomainto sign for, the contract addresses when deployed, and the limits below.POST /api/memorytakes one signed request:{ action, address, signature, issuedAt, nonce, payload }.
The message to sign
Build this text exactly, with \n line breaks, and sign it with personal_sign (EIP-191). The payload hash is keccak256 of the payload serialised as JSON with keys sorted at every level and no spaces.
{domain} asks you to sign a Pinlo memory request.
This signature moves no funds and costs no gas.
Action: {write | recall | forget | grant | pin}
Mind: {0x… mind id}
Payload: {keccak256 of the canonical JSON payload}
URI: https://{domain}
Chain ID: 4663
Nonce: {16 to 64 lowercase hex characters}
Issued At: {ISO 8601 time}A request is accepted for 5 minutes after Issued At, and each nonce only once. The domain must be the one GET /api/memory returns; a signature made for any other site is refused.
Actions
write
Payload { mind, label?, records }, 1 to 20 records. The owner includes label so the server can check that the mind id belongs to them; a wallet with a write grant leaves it out. Every record must name the signer in by, have a time within a day of now, and either text or enc. The answer gives the new hashes, the record count and the new root.
recall
Payload { mind, label?, query, tags?, all? }. Returns up to 12 matches scored by shared words and tags, each with its index, hash and record, plus the current root. With all: true it returns every record (used to sync a device).
forget
Payload { mind, label, hashes }, owner only. Removes records from the hosted store. Anchored roots and pinned snapshots are not touched.
grant
Payload { mind, label, agent, scope, expiry }, owner only, practice mode only. Scope 1 is read, 3 is read and write, 0 revokes. Expiry is a unix time or 0 for no expiry. Once a mind is opened on-chain, grants are made with a transaction instead and the API reads them from the contract.
pin
Payload { mind, label? }, owner or writer. Pins a JSON snapshot to IPFS and returns its content id and an ipfs:// link to put in the next anchor. With the hosted store the site builds the snapshot itself from the stored records, each of which was accepted with a signature from the wallet it names; anything sent in the request is ignored. On a deployment without the hosted store, send records: every one must name the signing wallet, and the snapshot is marked as vouched for by that wallet alone. Each wallet can pin 10 snapshots a day.
Limits
- 300 records per mind on the hosted store (the oldest drop off past that), 12 minds per wallet.
- 400 records written per wallet per day, with a wider ceiling per network.
- Hosted records expire 30 days after the mind was last written to. This is the practice period; anchors and pinned snapshots are the durable part.
- Request bodies are read with a hard size cap; anything larger is refused before it is parsed.
Errors
Errors come back as { error } with a plain-language message: 400 for a malformed request, 401 for a bad or expired signature, 403 when the wallet lacks access, 409 for a reused nonce, 429 for a limit, 503 when the hosted store or pinning is not configured on this deployment.