API reference
The API protocol package is the source of truth for hosted API routes and schemas.
Package: @fabricorg/experiments-api-protocol
The hosted API is defined through a zod-backed endpoint registry. The API client consumes the same protocol definitions.
Base URL and route paths
The protocol registry stores paths relative to the Fabric API base, such as
/v1/orgs/{orgId}/experiments. In a combined Studio/API deployment, the
ApiClient.baseUrl must include /api:
const client = new ApiClient({
baseUrl: 'https://studio.example.com/api',
apiKey: process.env.FX_API_KEY,
})That client calls the deployed route
https://studio.example.com/api/v1/orgs/{orgId}/experiments.
Do not add /v1 to baseUrl. The typed client appends it from the endpoint
registry. fx login normalizes a bare Studio origin to the /api base
automatically.
Important route families:
- tenants:
/api/v1/tenants/me - organization helpers:
/api/v1/organizations/generate-slug,/api/v1/organizations/resolve - experiments:
/api/v1/orgs/{orgId}/experiments - manifests:
/api/v1/orgs/{orgId}/manifests - preview links:
/api/v1/orgs/{orgId}/preview/sign - public keys:
/.well-known/jwks/{orgId} - aggregate:
/api/v1/orgs/{orgId}/experiments/{experimentId}/aggregate - API keys:
/api/v1/orgs/{orgId}/api-keys
Organization helpers (generate-slug, resolve) are authenticated routes
implemented as standalone Next.js handlers, not entries in the zod endpoint
registry. Public JWKS and revocation delivery routes are likewise outside the
registry because SDKs must fetch them without a Fabric session.
Authentication
Browser callers use Better Auth session cookies.
CLI and automation callers can use org API keys:
x-api-key: fx_key_...The production API runs on Cloudflare at
api.experiments.fabric.pro. CLI and automation calls present the Fabric
organization API key; no Databricks Apps gateway bearer is required. Databricks
Lakebase remains the operational Postgres system of record through Hyperdrive,
and Databricks OAuth remains an internal server-side credential for governed SQL
and warehouse operations.
Create API keys in Studio at /app/{orgSlug}/settings.
Preview links and public keys
Sign preview token
POST /api/v1/orgs/{orgId}/preview/sign
Content-Type: application/json
{
"experimentId": "homepage-cta",
"variantKey": "treatment",
"ttlSeconds": 900
}Returns a short-lived JWT plus metadata:
{
"token": "eyJhbGciOiJFZERTQSIs...",
"expiresAt": "2026-05-08T20:22:00.000Z",
"keyId": "init",
"jti": "..."
}Studio and fx preview place that token in a URL as:
?fxpreview=<experimentId>:<variantKey>&fxtoken=<jwt>The token is signed with an org Ed25519 private key. The browser verifies it with public JWKS; no preview secret is embedded in customer HTML.
Public JWKS
GET /.well-known/jwks/{orgId}Returns active/retiring Ed25519 public keys for manifest and preview-token verification. The Cloudflare manifest worker can proxy this path at the manifest origin.
API key endpoints
List keys
GET /api/v1/orgs/{orgId}/api-keysReturns active keys with id, name, prefix, role, scopes, createdAt,
lastUsedAt, and expiresAt. Roles are owner, admin, experimenter, or
viewer; scopes are read, write, and admin.
Create key
POST /api/v1/orgs/{orgId}/api-keys
Content-Type: application/json
{
"name": "CLI push from laptop",
"expiresAt": "2026-08-19T00:00:00.000Z",
"role": "experimenter",
"scopes": ["read", "write"]
}role and scopes are optional and otherwise derive from the creator. An
expiresAt value of null creates a non-expiring key and is not recommended in
production. The response returns the same summary fields plus key; the
plaintext key is returned once.
Revoke key
DELETE /api/v1/orgs/{orgId}/api-keys/{keyId}Returns { "ok": true } when revoked.