Agent index (llms.txt) — fetch this first, then the page it names.
Quickstart
This takes you from nothing to a deployed site and a working database call. It assumes someone runs an Orama cluster you can reach (your own, see Install a cluster from scratch, or one you were given access to). You need its gateway URL, for example https://cluster.example.com.
1. Install the tools
brew install DeBrosDAO/tap/orama # the CLI orama version npm install @debros/orama # the SDK, in your app
You also need a wallet that can sign. Install RootWallet (desktop, or the rw CLI), create a wallet, and leave it unlocked. Orama has no accounts and no passwords: your wallet address is your identity.
2. Tell the CLI which cluster to use
A fresh CLI knows no cluster. Add yours:
orama network add mycluster https://cluster.example.com orama network use mycluster
orama network list and orama network current show what is configured. If the cluster uses Let's Encrypt staging certificates, add --ca-file le-staging.pem (TLS and certificates).
3. Sign in
orama auth login orama auth whoami # asks the gateway who you are and what you may do orama auth status # what is stored on this machine (asks nobody)
The CLI asks RootWallet to sign a challenge from the gateway. What it stores is a session: an access token that lasts 15 minutes and renews itself from a 30-day refresh token. This is the lobby sign-in: you are in, but you hold no namespace yet. On a machine with no wallet (a server over SSH, CI), orama auth login prints a code, and orama auth approve <code> on a machine that has your wallet approves it. See Sign-in and sessions.
4. Create a namespace
A namespace is your own small cluster: a database, a cache and a gateway on three nodes. You own what you create.
orama namespace create myapp orama auth login --namespace myapp
Creating a namespace does not sign you in to it; the second command does. Some clusters allow only their operators to create namespaces; if yours refuses, ask an operator (Cluster administration). See Namespaces.
5. Deploy something
mkdir site && echo '<h1>Hello from Orama</h1>' > site/index.html orama deploy static ./site --name www orama app list orama app get www
orama deploy static publishes a directory as a deployment and prints its URL, a name under the cluster's base domain. Other runtimes: Next.js, Go and Node.js backends (Deployments).
6. Use a database
orama db create appdb
orama db query appdb "CREATE TABLE notes (id INTEGER PRIMARY KEY, text TEXT)"
orama db query appdb "INSERT INTO notes (text) VALUES ('hello')"
orama db query appdb "SELECT * FROM notes"This is a per-namespace SQLite database, reached from the CLI. The namespace also has a replicated SQL database (RQLite) that your code reaches through the SDK, shown next. See Databases.
7. Call it from code
What a key may do depends on its grants. Two keys cover a typical app.
On a server, in CI or in a script: an admin key. It reaches the control plane, including the namespace's RQLite database, so it never goes in a browser or mobile bundle.
orama namespace keys create --scope admin --label server
The command prints the key once, after a short report. Copy the line under API KEY into your secret store; it cannot be shown again.
import { createClient } from "@debros/orama";
const server = createClient({
baseURL: "https://ns-myapp.cluster.example.com",
apiKey: process.env.ORAMA_API_KEY,
});
await server.db.createTable("CREATE TABLE messages (id INTEGER PRIMARY KEY, room TEXT, body TEXT)");
await server.db.exec("INSERT INTO messages (room, body) VALUES (?, ?)", ["general", "hi"]);
const rows = await server.db.query("SELECT * FROM messages WHERE room = ?", ["general"]);In a browser or mobile app: a key with data-plane grants only, named explicitly. The app-runtime profile does not include pubsub or cache, so ask for them.
orama namespace keys create --scope invoke,pubsub,cache --label web
const client = createClient({
baseURL: "https://ns-myapp.cluster.example.com",
apiKey: process.env.ORAMA_WEB_KEY, // injected at build time
});
await client.cache.put("sessions", "alice", { seen: Date.now() }, "1h");
await client.pubsub.publish("room:general", "hello");Storage is different: the gateway refuses a key on its own and wants the signed-in user as well, so upload after the user has signed in with their wallet (Wallet login):
const { cid } = await client.storage.upload(new Blob(["file contents"]), "hello.txt");Where a key may live, and what each profile can do: Access control and keys. The full client: TypeScript SDK.
CI and scripts
Set ORAMA_TOKEN to an API key or a token. A key is exchanged for a session once per run. Mint the key once on your machine (add --expires-in-days to shorten its life, 90 days is the default), put it in your CI system's secret store, and expose it to the job:
orama namespace keys create --scope admin --label ci # prints the key once; store it
export ORAMA_TOKEN="$CI_ORAMA_KEY" # from the CI secret store orama deploy static ./dist --name www --update
Sessions, API keys, members and audit
The CLI signs in with your wallet and stores a session, not a key: an access token that lasts 15 minutes and renews itself from a 30-day refresh token. orama auth login asks which namespace to sign in to; blank signs in without one. With no terminal to ask (a script, a pipe, CI) it does not prompt and signs in without one; pass --namespace <name> to choose.
Which machines are signed in
orama auth sessions # every live session for this wallet orama auth sessions revoke <id> # end one orama auth sessions revoke --all # end all of them
Ending a session stops it minting new access tokens, and refuses the access tokens it already minted — and closes the sockets they hold open — within ten seconds. A session issued before sessions carried an id cannot be named that way: its access tokens work until they expire, at most 15 minutes, and the command says so.
Namespaces and environments
Creating a namespace is its own step, and the wallet that makes it owns it:
orama namespace create myapp orama auth login --namespace myapp
Signing in to a namespace that does not exist used to create it, so a typo made a namespace and one belonged to whoever happened to sign in first. It answers 404 now, naming the command above.
One machine can hold credentials for several environments. orama auth list
shows them, orama auth switch changes the active one, and orama auth logout
clears it. Which gateway a command talks to is decided by the active
environment — see orama network — not by a flag on each command.
Every command and flag is in the CLI reference, which is generated from the command tree rather than written by hand.
API keys for your application
Deploying uses your own credentials. An application that talks to the gateway at runtime needs a key of its own, and which one depends on where the code runs:
# Safe in a browser bundle: data-plane grants only orama namespace keys create --scope app-runtime --label web # Server-side only: the whole control plane orama namespace keys create --scope admin --label ci orama namespace keys list orama namespace keys revoke --id <id>
A key carries a set of grants and the gateway refuses an operation whose grant
the key does not hold, naming the one it needed. --scope takes a profile
(invoke-only, app-runtime, admin) or an explicit grant list. See
Where a key belongs.
Every key expires — 90 days by default, a year at most — and orama namespace keys rotate --id <id> mints a successor with the same grants while leaving the
original alive for a week, so there is a window in which to deploy the new one.
Working with other people
A namespace has one owner and any number of members, and a member holds a role:
orama members list orama members add 0xabc… --role admin # the control plane orama members add 0xdef… --role runtime # the data plane orama members remove 0xabc… orama members transfer 0xabc… # hand the namespace over
admin is everything except ownership; runtime is invoke, storage, push,
webrtc, proxy, pubsub and cache; reader is a member with no grant at all.
Ownership is transferred rather than granted, and it is one step rather than a
removal and a grant, so there is no moment where the namespace has no owner. You
keep an admin grant, so handing a project over does not lock you out of it.
What happened, and who did it
orama audit # oldest first orama audit --follow # and keep printing
Sign-ins, keys minted and revoked, grants given and taken away, deployments, functions, secrets and namespace changes, each with who did it and from where. Events are kept 90 days.
The whole model — identities, roles, grants, tokens, and what each refusal
means — is in the technical reference's authorization chapter (docs/whitepaper/technical-reference/vol1/14-authorization.md).
Where next
| You want to | Read |
|---|---|
| Understand the unit you work in | Namespaces |
| Let your users sign in with wallets | Sign-in and sessions, Devices |
| Invite teammates, scope a key | Access control and keys |
| Build | Deployments, Databases, Functions, Storage, Pub/sub, WebRTC, Push |
| Look up a command | CLI overview |
| See what Orama is and is not | How you talk to the network |