Witbitz docs HomeTrustAll docs

Run Spaces as your own tenant

Spaces — the multiplayer-AI room — is the reference app on Witbitz. This page runs it as you: your own origin, your own key vault, your own keys. You write no code; Witbitz builds and hosts it, and you can prove what it deployed.

Get Started: this → Verify it. Reference: HTTP API · SDK.


One paste

Needs curl and python3. Nothing to clone, no Cloudflare account.

bash
# 1) Register (free). The secret is shown ONCE and cannot be reissued — this saves it.
resp=$(curl -sX POST https://api.witbitz.chat/v1/tenants/demo \
  -H 'content-type: application/json' -d '{"name":"My Space"}')
export TENANT_KEY=$(echo "$resp" | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["keys"]["secret"])')
export TENANT_ID=$(echo "$resp"  | python3 -c 'import sys,json;print(json.load(sys.stdin)["data"]["tenant"]["tenant_id"])')
umask 077
{ echo "# $(date -u +%Y-%m-%dT%H:%M:%SZ)"; echo "TENANT_ID=$TENANT_ID"; echo "TENANT_KEY=$TENANT_KEY"; } >> ~/.witbitz-tenants
echo "saved → ~/.witbitz-tenants  (the only copy — lose it and this tenant is unreachable)"

# 2) Ask for your app. Names are first-come, first-served; set SLUG=yourname for a specific address.
SLUG="${SLUG:-myspace-$(od -An -N2 -tu2 /dev/urandom | tr -d ' ')}"
r=$(curl -sX POST https://api.witbitz.chat/v1/tenant/app \
  -H "authorization: Bearer $TENANT_KEY" -H 'content-type: application/json' \
  -d "{\"slug\":\"$SLUG\"}"); echo "$r"

# 3) Watch it — two builds and two deploys, about 90 seconds.
while s=$(curl -s https://api.witbitz.chat/v1/tenant/app -H "authorization: Bearer $TENANT_KEY"); echo "$s"; ! echo "$s" | grep -qE '"status":"(live|failed)"|"error"'; do sleep 20; done

It ends with your address:

json
{"status":"live","slug":"myspace-41287","url":"https://myspace-41287.witbitz.chat", …}

What you got

While you wait

A workflow runs it one named step at a time: create the projects and the domain, mint your keys, build and deploy the vault, configure it and redeploy, the same for the app, then admit your origins, register your issuers and grant your permissions. If any step fails the ones before it are undone — projects, namespaces, keys and secrets deleted rather than left as debris — and the poll tells you which step failed.

status
queued · provisioning still running — keep polling
live deployed, configured and admitted; url is your address
failed error names the step; everything it created has been undone

When it refuses: refused — the slug is malformed or reserved. conflict — that name is another tenant's. too_many_requests — ten apps per address per day; registering a fresh tenant does not reset it. A refusal queues nothing, so there is no job to poll.

One app per tenant. Re-asking with the same slug re-provisions it, keeping your K_eco so existing rooms still open.

Taking it down

Three levels, because they are three decisions. Each needs the key for that tenant.

bash
# 1. The app: projects, domain, admission, its key. KEEPS K_eco, so your rooms survive.
curl -sX DELETE https://api.witbitz.chat/v1/tenant/app -H "authorization: Bearer $TENANT_KEY"; echo
while s=$(curl -s https://api.witbitz.chat/v1/tenant/app -H "authorization: Bearer $TENANT_KEY"); echo "$s"; ! echo "$s" | grep -qE '"status":"(deleted|live)"|"error"'; do sleep 10; done

# 2. The rooms and everything in them. GET first — it deletes nothing and returns the confirmation value.
curl -s  https://api.witbitz.chat/v1/tenant/rooms -H "authorization: Bearer $TENANT_KEY"; echo
curl -sX DELETE https://api.witbitz.chat/v1/tenant/rooms -H "authorization: Bearer $TENANT_KEY" \
  -H 'content-type: application/json' -d "{\"confirm\":\"$TENANT_ID\",\"slug\":\"$SLUG\"}"; echo

# 3. The account: every key, every row.
curl -sX DELETE https://api.witbitz.chat/v1/tenant -H "authorization: Bearer $TENANT_KEY" \
  -H 'content-type: application/json' -d "{\"confirm\":\"$TENANT_ID\"}"; echo

Taking the app down keeps K_eco, the key your rooms' halves are sealed under — deleting it would not delete the rooms, it would make them permanently unopenable. Put the same slug back and they open again. Step 2 is what removes them, and it takes K_eco last. Step 3 refuses while an app or rooms remain, and tells you what is left.

Steps 2 and 3 are irreversible, so each must name the tenant it is destroying. Ask without the confirmation and the reply gives you the value.

In a new shell: set -a; . ~/.witbitz-tenants; set +a.

Proving what it deployed

Your app ships an asset manifest — every file hashed, stamped with the commit it was built from:

bash
curl -s https://<slug>-app.witbitz.chat/assets-manifest.json | head -3
# → {"v":1,"gitCommit":"…","algo":"sha256", …}

That commit is the platform build your app was made from, and that build is fully verifiable: rebuild the published source and get the hash AWS runs (Verify it, Tests 6–7). The client is served unminified, so you can also just read it.

Your origin also serves its own signed certificate, bound to that origin, committing to the exact bytes above:

bash
curl -s https://<slug>.witbitz.chat/cert.json | python3 -c 'import sys,json;print(json.load(sys.stdin)["signed"])'
# → {"service":"witbitz-vault","env":"tenant","origin":"https://<slug>.witbitz.chat","frontendSha256":"…", …}

So the verified-client extension reports your origin as verified, and builds the policy it enforces from that signed manifest rather than from your page.

Two limits, stated plainly rather than left to be discovered:

Everything else on the Verify it page — the admission gate, the egress lock, the sealed store — is checkable against your own Space today.

Keeping it

A demo tenant is real and works immediately, but auto-purges at its expires_at. To make it permanent — same id and keys — upgrade with an author coupon, or sign up non-expiring from the start with POST /v1/tenants/signup:

bash
curl -sX POST https://api.witbitz.chat/v1/tenant/upgrade \
  -H "authorization: Bearer $TENANT_KEY" -H "X-Author-Coupon: <code>"

No coupon? Email hello@witbitz.chat.

Not locked in. Witbitz-hosted is the easy default, not the only one. The same app is portable: point its one backend switch at your own boundary and run the entire stack yourself — same code, same verifiable-privacy properties. To embed a Space in a page you already have, see embed.

Next

Machine-readable source: vault-spaces.md · Generated 2026-10-27T07:05:42Z · build f301388c · every doc in one fetch: llms-full.txt (HTML)