Quickstart
There are exactly two steps. Load the widget script
once on the page, then place a
<table-ai> element wherever you
want the AI panel, pointing its
target at an existing table. That is the
whole integration.
<!-- 1. Load the widget -->
<script src="https://widget.tablearth.ai/v1.js"></script>
<!-- 2. Point it at a table -->
<table-ai
api-key="pk_live_…"
target="#revenue-table"
user="u_8124"
customer="acme"
theme="dark" />
The script registers the
<table-ai> custom element. When the
element mounts it reads the table named by
target, attaches the question box, and
streams answers back from tableArth.ai. Nothing else
on the page changes.
The <table-ai> element
The element is configured entirely through
attributes. The two required attributes are
api-key and target; the rest
scope sessions, set the look, and control how much the
model sees.
| Attribute | Description |
|---|---|
api-key |
Your pk_live_… public key. Origin-bound and safe to ship in the browser. Required. |
target |
CSS selector of the table to attach to, for example #revenue-table. Required. |
user |
An end-user identifier. Scopes the session and tracks usage per user. |
customer |
A customer or workspace identifier. Scopes the session and tracks usage per customer. |
theme |
Visual theme for the panel, for example dark. Pairs with CSS-variable theming below. |
mode |
Privacy mode for this widget: full_ai, masked, hybrid, or local_template. See Privacy mode. |
Frameworks
<table-ai> is a standard custom
element, so it works the same in every framework — and
in plain HTML. The script registers the element once;
you render the tag like any other markup.
- Plain HTML. Add the script tag and the element directly to your page, exactly as in the quickstart above.
- React. Render
<table-ai api-key="pk_live_…" target="#revenue-table" />in JSX. Load the script once (in your document head or a top-level effect). Attributes are plain strings, so kebab-case names likeapi-keypass straight through. - Vue. Use the element in your template as-is. Bind attributes with
:api-keywhen the value is dynamic, or write them as static attributes otherwise. - Angular. Use the element in a template and add
CUSTOM_ELEMENTS_SCHEMAto the module so Angular allows the unknown tag. Attributes bind the same way as in plain HTML.
Whichever framework you ship, the engine, the answer quality, and the privacy controls are identical. The only difference is how you load the script and render the tag.
Theming
The panel is white-labelable on your own domain and
themeable through CSS variables, so it inherits your
product's look rather than imposing ours. Set the
theme attribute for a base light or dark
treatment, then override individual tokens — colors,
radius, typography — with CSS custom properties scoped
to the element. Because the widget renders on your
domain under your brand, customers never see a
third-party origin.
Privacy mode
The mode attribute controls how much of
the table the model sees, per widget. It can also be
set per customer, workspace, or table on the server
side. The four modes:
full_ai— the model sees the full table for the richest answers.masked— text is tokenized before it reaches the LLM and restored in the output, so raw values never leave your environment.hybrid— the model sees only column statistics; rows render locally.local_template— pure server-side answering with zero external AI calls.
For the full picture of how each mode handles data, see the security page.
Security
The widget ships your pk_live_… public
key in the browser, which is by design. An origin
guard binds that key to the domains you register, so a
widget loaded on any other origin is rejected. That
makes the public key safe to expose in client-side
code.
Never put a sk_live_… secret key in the
widget or anywhere in the browser. Secret keys are for
server-side calls to the REST API only. If you need to
call tableArth.ai from your own backend, see the
REST API reference. You can also
cap spend per widget and set usage alerts; more on keys
and budgets in the docs and on the
security page.
Troubleshooting
A few common things to check when a widget does not behave as expected:
- The panel never appears. Confirm the script tag loaded before the element renders, and that the
targetselector matches a table that exists in the DOM when the element mounts. - Requests are rejected. The origin guard binds your
pk_live_…key to specific domains — make sure the page's origin is registered for that key. - No data is read. Check that
targetpoints at the right table and that the table has rendered, not just been requested. - Answers look unexpectedly limited. Review the
modein effect — a stricter privacy mode intentionally shows the model less of the table. - Theme overrides aren't applying. Confirm your CSS variables are scoped to the element and not overridden by a later, more specific rule.
Next: REST API reference — call the streaming endpoint from your own backend and power custom UI.