Platform API — the /v1 surface
The tenant-keyed HTTP API a third-party app builds on. JSON in, JSON out, over HTTPS. This page is the map; the machine-readable spec is canonical — point tooling at it:
- Production spec (only ops callable today):
https://api.witbitz.chat/v1/openapi.json(.yaml) - Full design spec (every op,
x-status-labelled):https://api.witbitz.chat/v1/openapi.full.json - Discovery index:
https://api.witbitz.chat/v1/
The Bridge is a separate contract (party signatures, not tenant keys) — see the Bridge.
Base + envelope
- Base URL:
https://api.witbitz.chat/v1 - Success is enveloped
{ "data": <payload>, "meta"?: {...} }; errors are{ "error": { "code", "message", "request_id"? } }. One exception:POST /space(x-envelope: false) returns a raw payload and a flat error shape — unifying it is a tracked follow-up. - Version
1.0.0-beta. Private beta — the contract may change (coordinated with invited integrators) until GA.
Authentication
Two tenant API keys, resolved by the /v1 authorizer to a tenantId:
- Secret key
wsk_— full scope, server-side only. - Publishable key
wpk_— browser-safe, public reads + funnel-entry writes. It identifies a tenant; it does not authenticate an end user. - Per-collection capability tokens (
x-collection-token): the owneradmin_tokenor the add-onlycontributor_token, for owner/contributor actions on a collection. Wallet/license credentials travel in the request body, never a URL.
Capability tokens + raw keys are shown once at creation and stored only as a hash (or KMS-sealed). Store them server-side; lost = re-create.
Operational contract
- Idempotency: money/billable ops (
POST /sessions,/wallets/grant,/collections/{id}/paint) require anIdempotency-Key; same key + same body replays the first 2xx byte-for-byte. - Rate limiting + kill switch: throttled at the gateway; per-tenant/per-key-type limits at the authorizer; an
operator can suspend a tenant (
POST /tenants/{tenant_id}/status) — every key is denied within ~15s. That op andPOST /tenantsare operator-only (X-Admin-Token, not a tenant key) and are deliberately absent from the published spec, so don't go looking for them inopenapi.json. - Secret handling: one-time-secret responses are
Cache-Control: no-store; sensitive fieldsx-sensitive; BYOK provider keys + the webhook secret are KMS-sealed at rest.
The surface (by area)
Agents
- GET /catalog — the public agent catalog (publishable).
Collections — the generic content primitive (opaque metadata + items + curation + a keyless render page)
- POST /collections · GET /collections/{id} · DELETE /collections/{id}
- GET /collections/{id}/render — keyless share page for published content (public)
- items: GET/POST /collections/{id}/items · PATCH/DELETE /collections/{id}/items/{itemId}
- POST /collections/{id}/state — merge opaque app state onto the collection
Artifacts — produced media on a collection
- GET/POST /collections/{id}/artifacts · GET/PATCH/DELETE .../artifacts/{artifactId}
- POST /collections/{id}/paint · POST /collections/{id}/produce
- POST /collections/{id}/artifacts/upload → presigned S3 PUT, then
POST /collections/{id}/artifacts/{artifactId}/ready to stamp it complete — both halves are required
Sessions
- POST /sessions — launch (or re-summon) an agent; metered, idempotent. Accepts either key: the spend
credential is the coupon in the body, so a publishable key launches nothing without a funded wallet.
Credits
- POST /wallets/lookup · POST /wallets/redeem · POST /wallets/grant · POST /checkout · GET /usage
Tenants (onboarding + key management)
- POST /tenants/signup · POST /tenants · POST /tenants/{tenant_id}/status
- GET /tenant · GET/POST /tenant/keys · DELETE /tenant/keys/{keyId}
- PUT /tenant/provider-keys (BYOK, KMS-sealed) · PUT /tenant/webhooks
Spaces — POST /space, the async Space's single op-dispatched endpoint. It is in /v1 but keyless: it
authenticates by key possession, not a tenant key (see the note below).
Infra — GET /turn (ephemeral TURN credentials).
Not at
/v1: ratings,/agents/*,/earningsand/sessions/{id}arex-status: legacy— they exist on the older surface but are not routed here, and calling them returns 404. They appear inopenapi.full.jsonlabelled as such, never in the production spec.
Access
Invite-only during private beta. Email hello@witbitz.chat for keys. Everything above is served openly as a contract; the keys are what's gated.
Notes
- The async Spaces runtime (
/space) is a separate, content-blind surface (key possession, not tenant keys) — see async Spaces and the Space link is the auth. - This page is a summary; the OpenAPI at
/v1/openapi.jsonis the source of truth (schemas, per-op auth, examples).
Machine-readable source: api-reference.md · every doc in one fetch: llms-full.txt · ← on-prem · the-bridge →