For developers

Roux API documentation

Hosted data and administration routes are authenticated, workspace-scoped, and enforced server-side. Liveness, readiness, the operation-channel health check, and profile-gated native configuration, login, activation, or local development login entry points are intentionally pre-session; Host, Origin, input, policy, and deployment gates still apply. Availability depends on the selected authentication provider, tenancy mode, deployment profile, and caller capability.

Contract boundary: this page describes the API as it is implemented today, while Roux is prerelease software. Request a versioned integration contract before relying on it as a long-term compatibility guarantee.
On the Roux hosted service: the API uses native sign-in. Requests carry the signed-in session cookie and its CSRF value, and the only bearer tokens accepted are those carried in Roux-signed publication and embed links. The identity-provider bearer profile and signed webhooks described below apply only to deployments that enable them. The JavaScript client sends a bearer token and does not implement native sign-in, so on the hosted service it can use only a Roux-signed embed or publication credential; both are read-only and limited to what they were issued for.

Authentication profiles

Roux does not use one universal credential model. The operator selects exactly one ordinary authentication provider.

ProfileOrdinary browser/API credentialImportant boundary
NativeOpaque server-side session in a Secure, HttpOnly, SameSite=Lax cookieEvery authenticated native-session POST /call and upload request also requires the session-bound CSRF value, including read operations sent through /call; the public health operation is the exception. The public JavaScript SDK does not implement this lifecycle.
External bearerJWT issued by the configured identity provider and sent as Authorization: Bearer or x-roux-sessionSignature, allowed algorithm, and expiry are always verified. Issuer and audience are checked when configured and are mandatory in the public-key/JWKS and multi-tenant topologies that require them. Admission and current authorization-store status are also checked when the Roux user directory is enabled.
Development bearerLocal development tokenLoopback-only. It is not a production login path.
No self-asserted embed access: an ordinary identity-provider token with embed:true is not an embed credential, and is refused.

Operational routes

GET /healthz
Canonical external process liveness. This response does not assert that authentication or persisted data is ready.
GET /readyz
Canonical external deployment readiness. The public-demo profile additionally validates its exact identity, workspace, project, and dataset contract. The edge uses /readyz/core only for an internal subrequest; it and the backend aliases /health, /livez, and /ready return 404 externally in this deployment profile.

Native session routes

These routes exist when native authentication is enabled. They are browser-session endpoints, not a public token-minting API.

GET /auth/config
Returns the public authentication capability description; never passwords, peppers, signing secrets, or TLS keys.
GET /auth/session
Returns the server-authoritative projection for a valid native cookie session.
POST /auth/login
Authenticates organization, login, and password and establishes the opaque server session. When the account has two-step verification, the response is instead 401 with code AUTH_MFA_REQUIRED and a short-lived mfaToken.
POST /auth/mfa/complete
Exchanges the mfaToken and a code from the authenticator app, or an unused recovery code, for the session. The step-up token grants nothing on its own; by default it expires after five minutes and allows five attempts.
GET /auth/mfa
Returns the current session's two-step verification enrollment status.
POST /auth/mfa/enrol · /auth/mfa/enrol/confirm
Begin enrollment with the account password, which returns the secret, its provisioning URI and the recovery codes exactly once, then confirm it with a code from the authenticator app. Where a deployment requires two-step verification, a password-only session can only read its own session and enrollment status, enroll, or sign out until enrollment is complete and the user signs in again with a code.
POST /auth/mfa/recovery-codes · /auth/mfa/disable
Replace every recovery code, or remove the second factor. Both require the account password and a session that completed two-step verification.
POST /auth/logout
Requires the current native session and CSRF value, revokes it, and clears the cookie.
POST /auth/activate · /auth/change-password
Complete the operator-issued activation flow or change a password under the configured password and lifecycle policies.
POST /login
A loopback-only development bearer issuer, present only when explicitly enabled with a symmetric secret and no real identity provider, public key, or JWKS. It returns an ordinary admitted development token and never an embed credential.

Governed REST reads

Workspace selection: x-roux-workspace takes precedence over ?ws=, and neither value proves authorization. In ordinary workspace mode, a missing, unknown, or non-member selector resolves to the caller's isolated personal workspace; constrained profiles may impose a fixed target.
GET /api/v1/state?ws=<workspace>
Returns the authorized workspace specification in workspace mode. Where the transport does not expose getState, this route is not available.
GET /api/v1/rows/<dataset-id>?ws=<workspace>
Returns the authorized in-memory row slice and dataset version. Server-side row and column policies apply; workspace owners retain full-row access.

DuckDB-backed datasets deliberately do not materialize their complete contents through getRows. Use the bounded page operation for row windows and query for aggregation.

curl -s https://your-roux-host/api/v1/state?ws=sales \
  -H "Authorization: Bearer $TOKEN"

Capability-gated operation channel

POST /call
Sends { "op": "…", "args": { … } }. health is the only unauthenticated operation. Every other network-allowed operation requires the selected credential, then role, workspace, policy, and resource checks are applied.
curl -s https://your-roux-host/call \
  -H "Authorization: Bearer $TOKEN" \
  -H "x-roux-workspace: sales" \
  -H "content-type: application/json" \
  -d '{"op":"query","args":{"entityId":"d1","dims":["region"],"metrics":[{"name":"total","expr":"SUM([v])"}]}}'

Success uses HTTP 200 with { ok:true, value }. A typed engine failure keeps { ok:false, error } and uses its corresponding HTTP status. Every authenticated native-session POST /call requires the session-bound x-roux-csrf value, including read operations.

Streamed file import

POST /api/v1/upload
A workspace-mode write route for authorized CSV, TSV, Parquet, Excel (.xlsx), or SQLite import. The optional x-roux-filename selects the safe display name and extension; omission defaults to upload.csv. The server authenticates and authorizes before reading the body, then streams with backpressure to a private temporary file before DuckDB ingestion.

The operator controls the byte ceiling, upload directory, free-space reserve, per-user/global concurrency, and idle timeout. The constrained public-demo profile denies upload. A selector or filename never grants permission.

JavaScript client

/roux-sdk.js is a framework-free bearer-auth client with getState, getRows, query, and low-level call. It throws RouxError on a non-success status or error envelope. Use it only with an approved bearer-auth integration; it does not implement native login, cookie, or CSRF lifecycle management.

const roux = RouxAPI.client({
  base: "https://your-roux-host",
  token: TOKEN,
  workspace: "sales"
});

const state = await roux.getState();
const result = await roux.query({
  entityId: "d1",
  dims: ["region"],
  metrics: [{ name: "total", expr: "SUM([v])" }]
});

Embedding and publication links

Publishing outside the organization requires an administrator's permission. Owners and editors publish dashboards to their own organization. A link anyone can hold, a named person in another organization, and an embed credential all reach outside it, so each needs an administrator to allow it for that user; without that permission the server refuses with EXTERNAL_PUBLISH_NOT_PERMITTED. A server whose operator turned publishing off answers 503.

Signed webhooks

Operator-configured subscriptions can receive a best-effort dataset.changed notification after a successful classified write. Payloads identify the event and resource but contain no row data. Deliveries carry x-roux-event, x-roux-delivery, and x-roux-signature; the signed timestamp is inside the signature value.

Delivery is fire-and-forget: Roux currently has no durable webhook queue or automatic retry. Consumers must verify the signature and timestamp, reject replays, and use the delivery identifier for idempotency.

Errors and client behavior

Handle 400, 401, 403, 404, 405, 408, 409, 413, 415, 422, 429, 500, and retryable or non-retryable 503 responses. Error envelopes can include message, code, status, reason, retryable, storage state, conflict information, fallback markers, or version markers. Do not silently fall back to ungoverned data.

Machine-readable and deployment-local documentation

The live Roux host serves the fuller deployment-local guide, SDK assets, and OpenAPI description. Treat its selected profile as authoritative for route availability.