docs: document embed user pre-provisioning and the split AI billing tabs - #11711
docs: document embed user pre-provisioning and the split AI billing tabs#11711keydunov wants to merge 2 commits into
Conversation
- reference/embed-apis: document POST .../user and .../users for provisioning embed users ahead of their first session (CUB-4148) - admin/account-billing/ai-tokens: the AI Tokens Usage tab was split into AI Usage and AI Requests (CUB-3881); update the tab names accordingly
|
Preview deployment for your docs. Learn more about Mintlify Previews.
💡 Tip: Enable Workflows to automatically generate PRs for you. |
|
Claude finished @keydunov's task in 1m 31s —— View job Review: docs-only, no blockers — 0 high, 2 medium, 2 lowDocs-only change, both edits land in the right place and match the surrounding style. Main issue: the new section points at a Full reviewTodos
What's good
Findings
Pre-existing, not introduced here
Not verifiable hereThe AI Usage / AI Requests tab split, and the "per user or per role", "chart or table", "live tail" specifics, come from Checks not runNo tests or lint — the diff touches only |
|
|
||
| The singular endpoint provisions one user; the plural endpoint provisions up to 100 in a single request and is partially successful — it returns `succeeded` and `failed` arrays instead of failing the whole batch for one bad entry, with each failure keyed by `externalId`. | ||
|
|
||
| Each user takes the same fields as `generate-session` above — `externalId`, `email`, `userProfile`, `groups`, `tenantGroups` — except `userAttributes` and `securityContext`, which every session re-applies and so are not accepted here. Provisioning is idempotent: an existing `externalId` is updated rather than rejected, `email` and `userProfile` are overwritten only when supplied, and each group field is replaced when supplied, left untouched when omitted, and cleared with `[]`. Omit `email` and Cube derives a placeholder address instead, which makes the user harder to recognize in a list. |
There was a problem hiding this comment.
tenantGroups is presented as one of "the same fields as generate-session above", but it doesn't appear anywhere above on this page — the Request Body table (lines 35–49) documents groups but not tenantGroups. A reader following the "above" pointer to find out what it means comes up empty.
It does exist in the API (api.yaml:8859, and GenerateSession accepts it per api-reference/changelog.mdx:199) — so the fix is to add the missing row to the Request Body table rather than to drop it here:
| tenantGroups | string[] | No | Per-embed-tenant groups for sharing and organizing content within a single embed tenant (creator mode), namespaced separately from the account-wide groups. |
Same page also omits tenantGroupDefinitions and embedTenantProfile from that table for the same reason.
| ## Provisioning users ahead of their first session | ||
|
|
||
| An embed user is normally created only when they generate their first session — so you cannot add them to a group or share a workbook or dashboard with them until they have opened the embed at least once. To make a user addressable immediately, provision them directly: | ||
|
|
||
| ```text | ||
| POST /api/v1/embed-tenants/{embedTenantName}/user | ||
| POST /api/v1/embed-tenants/{embedTenantName}/users | ||
| ``` | ||
|
|
||
| The singular endpoint provisions one user; the plural endpoint provisions up to 100 in a single request and is partially successful — it returns `succeeded` and `failed` arrays instead of failing the whole batch for one bad entry, with each failure keyed by `externalId`. | ||
|
|
||
| Each user takes the same fields as `generate-session` above — `externalId`, `email`, `userProfile`, `groups`, `tenantGroups` — except `userAttributes` and `securityContext`, which every session re-applies and so are not accepted here. Provisioning is idempotent: an existing `externalId` is updated rather than rejected, `email` and `userProfile` are overwritten only when supplied, and each group field is replaced when supplied, left untouched when omitted, and cleared with `[]`. Omit `email` and Cube derives a placeholder address instead, which makes the user harder to recognize in a list. | ||
|
|
||
| These endpoints use the same `Api-Key` authentication as Generate Session and require admin access. |
There was a problem hiding this comment.
Both endpoints are already documented in the generated API reference — provisionEmbedUser (api-reference/api.yaml:3048) and provisionEmbedUsers (:3147), including the 1–100 batch bound, the succeeded/failed shape, and per-field idempotency semantics. This section restates all of it in prose with no link between the two, so they'll drift.
Worth adding a link to the reference (e.g. /api-reference/embed-tenants/provisionembeduser) and trimming the per-field rules here to the pointer plus the one thing the reference doesn't convey — why you'd provision ahead of a session. That's also closer to the docs-mintlify guidance to say it once.
Two details the prose drops that are load-bearing:
- The embed tenant is created on demand, so
{embedTenantName}need not exist yet (api.yaml:3092). tenantGroupsentries must be created first viaPOST /embed-tenants/{embedTenantName}/groups(api.yaml:8867) — otherwise the call fails, and the admin-API section right below this one only documentsGET/DELETEfor groups.
| - Total token usage over time | ||
| - Remaining allocation from per-seat grants and token packages | ||
| - Breakdown by usage dimension | ||
| - **AI Usage** shows spend per user or per role over a billing period, as a |
There was a problem hiding this comment.
"spend" is ambiguous on this page — it's used a few lines up (line 55) for actual money, in "monthly on-demand spending limit". Here it means token consumption, which is what the sentence above it says ("monitor token consumption"). Suggest keeping the vocabulary consistent:
| - **AI Usage** shows spend per user or per role over a billing period, as a | |
| - **AI Usage** shows token consumption per user or per role over a billing | |
| period, as a chart or table, including remaining allocation from per-seat | |
| grants and token packages |
…rkbook menu, and calculated-field SQL editor - admin/deployment: document the account-wide and per-user default deployment pin (CUB-4183-ish landing-deployment feature) - docs/integrations/dbt: document the Validation level / Validation schema push settings and authoring dbt models from Analytics Chat - embedding/iframe/creator-mode: document the workbook header actions menu (Rename, Duplicate, View all, New workbook, Delete) in embedded Creator Mode - docs/explore-analyze/workbooks/calculated-fields: distinguish the structured bins/groups editor from the SQL-only fallback editor
|
Claude finished @keydunov's task in 1m 59s —— View job Review of
|
| # | Severity | File | Issue |
|---|---|---|---|
| 1 | Medium | dbt.mdx:615 |
New Parse/Compile/Build setting contradicts two earlier statements (:576 intro and the Push step at ~:666) that still describe validation as dbt parse only. |
| 2 | Medium | calculated-fields.mdx:150-153 |
"that same structured editor, letting you change its name and SQL expression" — the bins/groups panel edits boundaries and group membership, not a raw SQL expression; wording looks carried over from the generic editor. Also restates the split already made at :144. |
| 3 | Medium | deployment/index.mdx:28-37 |
Precedence prose is hard to follow: bullets run account-wide → per-user but resolution runs the reverse, so "the next one in this order" points backwards; "so it only applies until…" has three candidate antecedents. |
| 4 | Low | creator-mode.mdx:29-31 |
Manage / Edit workbook permissions are named but defined nowhere else in docs-mintlify; no link to how an embed user acquires them. |
| 5 | Low | creator-mode.mdx:29-31 |
Dashboard section above ends with a "hide header controls" pointer; the workbook section is silent on whether the same is possible. |
| 6 | Low | dbt.mdx:616 |
"Required when validation level is Build" vs. the fallback note — unclear whether the schema is still required when the warehouse silently falls back to Parse. |
Still open from the previous commit
All three threads on 52aa2a0 remain unresolved and still apply to the current diff — nothing in 1e995ae touched generate-session.mdx or ai-tokens.mdx:
generate-session.mdx:282— danglingtenantGroupsreference (not in the Request Body table).generate-session.mdx:284— duplicatesprovisionEmbedUser/provisionEmbedUsersfromapi-reference/api.yamlwith no cross-link; drops the on-demand tenant creation and group-must-exist-first details.ai-tokens.mdx:81— "spend" collides with the money sense used at:55.
Not verifiable here
The Analytics Chat dbt-authoring loop (live sandbox, confirm-before-commit), the workbook actions menu and its permission gating, the default-deployment pinning UI, and the calculated-field editor split all come from cubedevinc/cubejs-enterprise and can't be checked against this repo. Taking those on the author's word; the findings above are internal-consistency issues, not disputes about behavior.
Checks not run
No tests or lint — the diff is .mdx content only and this repo has no docs test suite. A yarn dev render check in docs-mintlify/ would confirm the MDX parses, but the new <Note> and table syntax are structurally identical to what already renders on these pages.
| | --- | --- | | ||
| | **Models path** | Directory in the dbt project where generated model files are written. Defaults to `models/marts/cube/`. | | ||
| | **Delivery mode** | **Open a pull request** (default) pushes to a `cube/dbt-push/*` branch and opens a PR/MR. **Commit directly to a branch** commits straight to a branch you name — validation still runs. | | ||
| | **Validation level** | How thoroughly a model is checked before it's committed: **Parse** only confirms the project still parses; **Compile** also compiles the generated SQL; **Build** additionally runs the model (and its tests) against your warehouse, in the **validation schema** below, so a broken model is caught before the PR opens. | |
There was a problem hiding this comment.
Adding configurable validation levels leaves two earlier statements on this page describing only the Parse case as if it were the whole story:
- Line 576 (section intro): "validated by a real
dbt parsein Cube's sandbox before the PR is opened". - The Push step (line ~666): "runs
dbt deps+dbt parse. If parse fails, the push stops with dbt's own output and no pull request is opened."
A reader who sets Build and then reads the Push step is told their model is only parsed. Both should generalize to "the configured validation level" and point back to this row — otherwise the page contradicts itself on what actually gains the PR its green status.
| Select a calculated field in the sidebar to open its editor. A field created by | ||
| the **bins** or **groups** panel reopens that same structured editor, letting you | ||
| change its **name** and **SQL expression**. Any other calculated field — a `CASE` | ||
| expression, a calculation like **% of total**, or a field saved to the workbook — |
There was a problem hiding this comment.
Two problems in the structured-editor half of this sentence:
-
"that same structured editor, letting you change its
nameandSQL expression" — "that same" points at the bins/groups panel described immediately above (line 144, "Edit bins… or Edit groups…"), but that panel edits boundaries, ranges, label style, group membership — not a raw SQL expression. The old text's "name and SQL expression" reads like it was carried over from the generic editor and reattached to the wrong one. If the structured editor really does expose a SQL box alongside the bins controls, worth saying so explicitly, since line 144 has just told the reader that panel is the structured alternative to hand-written SQL. -
This paragraph now overlaps the one at line 144–146, which already says only panel-generated fields offer Edit bins…/Edit groups…. Consider folding the two together rather than restating the same split from the other direction.
| list and chooses **Set as default** (or **Remove as default**). The pinned | ||
| deployment is marked with a home icon and becomes the landing deployment for | ||
| anyone who hasn't chosen one of their own. | ||
| - **Per user** — anyone can pin their own default from their account | ||
| **Preferences**, which takes precedence over the account-wide pin. The | ||
| deployment you most recently switched to also counts as a personal choice and | ||
| outranks the account pin, so it only applies until you actively switch to | ||
| something else. | ||
|
|
||
| Draft deployments are never candidates for either pin, and a pin you no longer |
There was a problem hiding this comment.
The precedence story is hard to follow as written:
- The bullets run Account-wide → Per user, but resolution runs the other way (per-user pin, then most-recent, then account pin). The closing "skipped in favor of the next one in this order" then points back at a list that reads in the opposite direction of the order it means.
- "The deployment you most recently switched to also counts as a personal choice and outranks the account pin, so it only applies until you actively switch to something else" — "it" has three candidate antecedents (the personal pin, the most-recent deployment, the account pin). Given "outranks the account pin", the intended subject seems to be the account pin, but the nearest noun is the wrong one.
An explicit ranked list would carry this better than prose, e.g.:
Cube picks the landing deployment in this order, skipping drafts and any deployment you no longer have access to:
- Your own default, pinned in account Preferences
- The deployment you most recently switched to
- The account-wide default, pinned by an admin from the ⋯ menu in the deployments list (marked with a home icon)
| **Duplicate**, **View all**, **New workbook**, and **Delete**. Rename and Delete | ||
| require the embed user's **Manage** permission on the workbook; Duplicate | ||
| requires **Manage** or **Edit**. Double-clicking the workbook name also renames |
There was a problem hiding this comment.
Manage and Edit are introduced here as named workbook permissions, but nothing else in docs-mintlify defines them — grep -rn "Manage" docs/explore-analyze/workbooks/ embedding/iframe/ matches only these two lines. An embed integrator reading this has no way to find out how an embed user acquires Manage vs Edit on a workbook. Worth linking to wherever workbook sharing/permissions are described (or to the group-based sharing model, since the section right below is about embed-tenant groups).
Also, the Dashboard header controls section directly above ends with a pointer to Show or hide header controls. This new section is silent on whether the workbook actions menu can be hidden the same way — a reader will reasonably assume it can. Worth saying either way.
Check List
Description of Changes Made
Documentation gaps found while cross-checking recent
cubedevinc/cubejs-enterprisechanges against the docs. All are surgical edits to existing pages — no new pages, nodocs.jsonchanges.reference/embed-apis/generate-session.mdx: documents the two new admin endpoints for provisioning an embed user ahead of their first session —POST /api/v1/embed-tenants/{embedTenantName}/userand.../users(bulk).admin/account-billing/ai-tokens.mdx: the single "AI Tokens Usage" tab was split into two tabs, AI Usage and AI Requests; updated the doc to match.admin/deployment/index.mdx: documents the account-wide and per-user default deployment pin (which deployment people land on) and its precedence order.docs/integrations/dbt.mdx: documents the Validation level / Validation schema dbt-push settings, the per-warehouse support caveat, and authoring/validating dbt models conversationally from Analytics Chat.embedding/iframe/creator-mode.mdx: documents the workbook header actions menu (Rename, Duplicate, View all, New workbook, Delete) now available in embedded Creator Mode, and its permission gates.docs/explore-analyze/workbooks/calculated-fields.mdx: distinguishes the structured bins/groups editor from the new SQL-only fallback editor used forCASEexpressions, computed calculations, and saved workbook fields.