Data-plane API for Wazoo worlds. This repo owns the data.wazoo.dev
Cloudflare Worker and the optional Docker image used by VPS compositions.
- World data metadata inside the data plane.
- Quad/chunk storage backed by Cloudflare D1.
- Search, import, and export endpoints.
- World-scoped API keys with the
wzw_prefix. - Deployment config for this one service:
wrangler.toml,Dockerfile,docker-compose.yml, and CI.
This service treats namespace as an opaque grouping string. In Wazoo private
beta, wazoo-api passes namespace = user.uid.
The Wazoo Worlds surface is split into two planes, each with its own auth surface and its own client package:
| Plane | Service | Auth | Owns | Client |
|---|---|---|---|---|
| Platform (management) | wazoo-api (api.wazoo.dev) |
platform tokens (wzp_) |
accounts, platform tokens, usage/limits/billing, and the policy facade over worlds | @wazoo/client (generated from the platform OpenAPI) |
| Data plane | worlds-api (data.wazoo.dev) |
world keys (wzw_) |
world data in shared Cloudflare D1, metadata, keys, quad/chunk storage, search/SPARQL/import/export/reindex, lifecycle + purge | the generated @worlds/client data-plane HTTP client and the embeddable @worlds/sdk |
- The data plane is the single writer of world lifecycle and world keys.
POST /worldsinserts world metadata into the shared D1worldstable;/api-keysmints data-plane keys. A self-hostedworlds-apiis therefore fully functional standalone — worlds, keys, and data operations — with zero management-plane dependency. That is the original design goal: people can self-host the data plane without running the platform. - The platform plane is a policy facade over the data plane.
wazoo-api/v1/worldsCRUD and world-token endpoints callworlds-apiadmin endpoints (/api-keys, world lifecycle) withWORLDS_API_ADMIN_KEY, then layer platform policy on top: quotas, usage/limits, billing gates, andMAX_WORLDS_EXCEEDED. The two/worldssurfaces are not peers — one is storage ownership, the other is policy. namespaceis the tenancy boundary between the planes: an opaque grouping string (in the hosted beta,wazoo-apipassesnamespace = user.uid). Data-plane keys resolve namespace from the key; admin calls pass it explicitly.
The historical confusion about "where do cuts go" comes from three overlaps that were never explicitly resolved. This section resolves them:
- World CRUD appears twice.
/worlds(data plane) and/v1/worlds(platform) look duplicated. Decision: keep the data plane as the sole writer of world lifecycle and metadata; the platform facade must not persist its own world state. Platform-side world policy (quotas, billing, usage) is derived state, not a second world record. - World keys are minted in two places.
worlds-api /api-keysis the minting authority;wazoo-api /v1/worlds/{worldId}/auth/tokensis a scoped facade that already mints through the data-plane admin surface. Keep one mint (the data plane); the platform endpoint stays a thin alias and must not mint independently. - The hosted beta is a proxy, not the model. In the hosted beta,
wazoo-apiprovisions everything throughWORLDS_API_ADMIN_KEY. That admin surface is an implementation detail of the platform facade, not a second public API; self-hosted deployments use the same endpoints with their own admin key.
@wazoo/clientcovers the platform plane only (management-plane operations).- The data plane needs its own typed HTTP client generated from this repo's
OpenAPI document (
GET /openapi.json), replacing hand-rolledfetchin consumers such aswazoo-cli. @worlds/sdkis the embeddable SDK (in-process graph operations over any backend). Itsimport/export/search/sparql/reindexmethods must stay shape-identical with the data-plane HTTP endpoints so the SDK and the HTTP client expose one contract.
- Worlds:
/worlds,/worlds/:worldId - Search:
/worlds/:worldId/search - Import:
/worlds/:worldId/import - Export:
/worlds/:worldId/export - API keys:
/api-keys - Liveness:
/health - Readiness:
/ready
Worlds API mints w_<ULID> IDs; clients provide display name and optional configuration, not a slug or ID. World responses expose the value as id, storage uses world_id, and every world-scoped route uses the same value as its worldId path parameter. There is no slug or legacy-identity fallback.
Normal data-plane keys resolve namespace from the key. Admin calls pass
namespace in the request body or query string.
The /admin/namespaces/{namespace}/delete and /admin/purge endpoints are
admin-only and exist for the platform facade and account-deletion flows.
WORLDS_API_ADMIN_KEY: admin key used bywazoo-apifor provisioning and API-key management. This is the only secret worlds-api reads.
Secrets are stored centrally in Infisical and injected at process start; they
are never written to a local file. See CONTRIBUTING.md for CLI
setup and the wrapped commands (.infisical.json, the committed project link,
holds no secret values), and secret-registry.md for how
local dev, the Workers Secret Sync, and CI each receive it.
Worlds API's control-plane DDL is defined in src/lib/d1-schema.ts. The
@worlds/cloudflare package owns data-plane tables, indexes, and schema
compatibility checks. Schema initialization is not an in-place migration; any
database reset remains a separately approved rollout action.
- Local:
pnpm run health:local - QA:
pnpm run health:local https://data-qa.wazoo.dev
/health checks liveness and database connectivity. /ready checks that the
control-plane schema matches this service. The health script probes both and
requires WORLDS_API_ADMIN_KEY for its authenticated checks, so run it through the
CLI to inject that value:
infisical run --env=dev -- pnpm run health:local
infisical run --env=qa -- pnpm run health:local https://data-qa.wazoo.devpnpm install
infisical login # once per machine
infisical init # once per checkout
pnpm run dev # secrets injected from Infisical at runtime
pnpm run typecheck
pnpm run build.dev.vars is no longer required. If you still have one, rename it to
.dev.vars.backup so local runs are proven to use Infisical rather than disk.
Cloudflare Worker:
pnpm run deploy --dry-run
pnpm run deployDocker component:
docker build -t ghcr.io/wazootech/worlds-api:latest .
docker compose upGitHub Actions validates formatting, typechecking, build, Worker dry deploy,
Docker build, publishes the GHCR image on main, and deploys
data.wazoo.dev on main.