Witbitz docs HomeTrustAll docs

Quickstart — open a Space and call the runtime

This quickstart gets you through the live path without pretending there is a finished public SDK. Today, the working browser client is the thin client used by the Spaces app (spaces/public/spaceClient.js), and the lower-level HTTP surface is a single /space op-dispatched endpoint.

Use this page to understand the flow. For production integration access to the tenant-keyed /v1 API, see Platform API.


1. Open the reference app

The fastest way to see the runtime is the hosted Spaces app:

https://witbitz-spaces.pages.dev

Create a Space, post a message, and watch the AI answer. That exercises the same primitives your own app would use:

2. Discover the Space endpoint

The app discovers its runtime endpoint from a public config file:

curl -s https://witbitz-spaces.pages.dev/space-config | python3 -m json.tool
# {
#     "spaceEndpoint": "https://api.witbitz.chat/v1/space"
# }

The response includes the spaceEndpoint the client posts to. In hosted production that endpoint fronts the /space Lambda. In an on-prem deployment it is usually same-origin, commonly /v1/space or /space.

3. Check the running service

The attest op reports the source/build identity the running render was built from:

SPACE=$(curl -s https://witbitz-spaces.pages.dev/space-config \
  | python3 -c 'import sys,json; print(json.load(sys.stdin)["spaceEndpoint"])')

curl -sX POST "$SPACE" \
  -H 'content-type: application/json' \
  -d '{"op":"attest"}' \
  | python3 -m json.tool
# {
#     "service": "witbitz-space",
#     "gitCommit": "...",
#     "runtime": "aws-lambda",
#     "note": "..."
# }

That does not create a room and does not require a key. It is the first sanity check that you are talking to the runtime described in these docs. The stronger build checks are in Verify it yourself.

4. Create a Space from a static app

The working client flow is:

  1. The browser mints a room key mk.
  2. The browser computes commit(mk).
  3. The browser registers only the room, commitment, and sealed config with op:'create'.
  4. The share link carries the room in the URL query and the key material in the fragment.

The server never receives mk at create time.

In the current codebase, this is wrapped by makeSpaceClient().create():

import { makeSpaceClient } from './spaceClient.js'

const client = makeSpaceClient({ endpoint: '/space' })

const space = await client.create({
  keyModel: '1-of-1',
  agentName: 'Witbitz',
  persona: 'A concise collaborative assistant.',
  tools: []
}, {
  base: location.origin
})

console.log(space.room)
console.log(space.links[0])

For a hosted third-party app, treat this as the reference client pattern rather than a package contract. The formal developer SDK should wrap this shape.

5. Post a turn

Once a client has opened a member link and reconstructed mk, a turn posts the member message and the room key for the decrypt-once render:

const { room, mk } = await client.open(space.links[0])

const reply = await client.turn(room, mk, {
  from: 'Ada',
  text: 'Plan a simple two-day trip to Paris.'
})

The render opens the sealed ledger, appends the member entry, runs the agent, appends the reply, re-seals the ledger, and drops the key.

6. Poll for changes

The preferred read path is pollSealed: the server returns the sealed ledger and the client opens it locally. For gated rooms, the request also carries identity so the server can enforce the read gate before returning anything.

let etag = ''
let count = 0

const r = await client.pollSealed(room, mk, etag, count)
if (r.changed) {
  etag = r.etag
  count = r.version
  console.log(r.entries)
}

The legacy poll path still exists and returns plaintext from the render. Use pollSealed for the hot read loop.

Next

Machine-readable source: quickstart.md · every doc in one fetch: llms-full.txt (HTML) · ← platform · create-space