The tableArth.ai REST API exposes one core capability: send a question in plain English and get back an answer, an insight, and a chart. Use it when you want full control of your own front end — the streaming endpoint does the natural-language-to-SQL work and you render the result however you like. If you would rather drop in a ready-made UI, see the widget integration guide instead.
Authentication
Every request authenticates with a secret
key in the Authorization header,
using the Bearer scheme. Secret keys are
prefixed sk_live_.
Authorization: Bearer sk_live_…
The secret key is server-side only.
Never expose it in the browser, in client-side
JavaScript, in a mobile app bundle, or in a public
repository — a leaked secret key can run questions
against your data and consume your budget. Keep it in
an environment variable or secret manager and make
every /v1/ask call from your own backend.
The browser-safe public key, prefixed
pk_live_ and origin-bound, is used only by
the widget and the Chrome extension — not by this REST
API. If you need to call the engine from the front end,
use the widget rather than shipping a secret key.
Base URL
All REST endpoints are served from a single base URL over HTTPS:
https://api.tablearth.ai
Paths in this reference are relative to that base. The
ask endpoint, for example, is the full URL
https://api.tablearth.ai/v1/ask.
Ask a question — POST /v1/ask
POST /v1/ask is the single endpoint you
need. Send a JSON body describing the table, who is
asking, the question, and how the data should be
handled. The response is the streamed answer (see
streaming responses below).
The request body accepts these fields:
| Field | Type | Description |
|---|---|---|
table |
string | The table or dataset the question runs against. The engine reads its schema to write the SQL. |
user |
string | Your end user's id. Scopes context and usage to a single user. See sessions. |
customer |
string | Your customer (tenant) id. Scopes context, budgets, and usage analytics per customer. |
question |
string | The plain-English question. The engine writes and runs the SQL; no SQL is required from the caller. |
mode |
enum | Privacy mode: full_ai, masked, hybrid, or local_template. See privacy modes. |
stream |
boolean | When true, the answer streams token-by-token over Server-Sent Events. |
A complete request with curl:
curl -X POST https://api.tablearth.ai/v1/ask \
-H "Authorization: Bearer sk_live_…" \
-H "Content-Type: application/json" \
-d '{
"table": "revenue",
"user": "u_8124",
"customer": "acme",
"question": "Which regions grew fastest year over year?",
"mode": "full_ai",
"stream": true
}'
Streaming responses
With stream set to true, the
engine returns a Server-Sent Events
(SSE) stream. The answer arrives
token-by-token as it is generated, so your UI can render
it live instead of waiting for the full response — the
same sub-five-second experience the widget gives.
Read the response as an event stream rather than a
single JSON body. Consume events as they arrive, append
the streamed answer text to your UI, and use the chart
and result data carried on the stream to render the
visualization once the answer completes. Set
stream to false if you would
rather receive the answer as one response after the
engine finishes.
Privacy modes
The mode field controls how much of your
data reaches the model on each request. Set it per call,
and govern defaults per customer, workspace, or table:
full_ai— the model sees the full table; best answer quality.masked— text is tokenized before the LLM and restored in the output, so raw values never reach the model.hybrid— the model sees only column statistics; rows are rendered locally.local_template— pure server-side templates with zero external AI calls.
Full details on what each mode sends, where it runs, and how to set defaults live on the security page.
Sessions
The user and customer ids on
every request define a session. They scope the context
the engine uses to answer and the budgets and usage
analytics tracked against the request. Passing both on
each call lets you cap and report spend per customer and
per user, and keeps one customer's context isolated from
another's. Reuse the same ids across a conversation so
follow-up questions stay in context.
Errors & retries
Generated SQL is sometimes wrong on the first pass — a misnamed column, a type mismatch, a dialect quirk. The engine detects a failed query and self-corrects, retrying up to three times before falling back gracefully, so a single bad query does not surface an error to your user. This happens inside the engine; you do not need to implement the retry yourself.
Handle API-level errors the way you would any HTTP service. Check the response status, surface a friendly message to your user on failure, and retry idempotently on transient network or server errors with sensible backoff. Authentication failures point to a missing or wrong secret key; budget errors mean a cap was reached — raise or adjust caps from your dashboard.
SDKs
Official SDKs wrap authentication, the request body, and
SSE parsing so you can call the engine in a few lines.
They are available for Node,
Python, and Go, with a
Ruby SDK coming. Until the Ruby SDK
ships, you can call /v1/ask directly over
HTTP from Ruby — the REST contract above is all you need.
Prefer a drop-in UI over wiring up the API yourself? The widget embeds the same engine in two lines of code. And whichever path you take, the deploy guide walks through getting keys and going live.
Next: privacy modes — how each mode handles your data, and how to set defaults per customer, workspace, or table.