Skip to main content

Backend SDK

@dataira/node is an optional server-only wrapper around the REST API. Keep its API key in a secret manager; never import this package into a browser bundle.

The package is public on npm.

The live demo uses this same server-to-browser token boundary with a dedicated demo Project, Environment, and datasource.

npm install @dataira/node

Mint an end-user token

import { Dataira } from "@dataira/node";

const dataira = new Dataira({
apiKey: process.env.DATAIRA_API_KEY!,
baseUrl: "https://api.dataira.ai",
});

const { token } = await dataira.createToken({
endUserId: user.id,
endUserOrgId: user.organizationId,
datasourceId: "ds_123",
scopeColumn: "account_id",
scopeValue: user.accountId,
});

Your runtime API key already fixes the Partner organization, Project, and Environment. Dataira derives those values from the key; the browser or request body cannot override them. The token adds the end-user organization, end user, datasource, and row-level data scope. If your product has no organization model, omit endUserOrgId; it defaults to endUserId.

The first valid mint registers the user beneath that Partner and Environment. Later attempts to silently move the same Environment user to a different end-user organization are rejected. This prevents a key or token from reading assets outside its full identity scope.

Showing or hiding SQL evidence

allowSqlEvidence is a boolean field on createToken. It controls what the end user sees in chat answers, conversation titles, and asset names.

Default: true. Omit the field and evidence is visible. Nothing to configure.

Two conditions decide the outcome. The table is exhaustive:

Key has embed.sql_evidence.readallowSqlEvidence at mintSession shows
yes (runtime keys: yes by default)omitted or trueFull answer: assistant analysis, generated SQL, real conversation titles, real asset names
yes (runtime keys: yes by default)falseNeutral "analysis complete" placeholder instead of answer text; SQL hidden; asset names neutralized
noany valueSame as the row above. The permission is the hard gate: no permission, no evidence, regardless of the flag

Exact behavior when evidence is hidden:

  • Chat answers: the user sees "Analysis complete. Model-authored text and restricted query evidence are hidden by this embed session's evidence policy." — the analysis itself is withheld, not just the SQL.
  • Conversation titles: replaced by a neutral name.
  • Metric and dashboard names: replaced by neutral names.

Use false only when your end users must never see SQL or model text, for example a non-technical audience. If you are building an analytics tool where users want to verify the SQL, leave the default.

const { token } = await dataira.createToken({
endUserId: user.id,
datasourceId: "ds_123",
scopeColumn: "account_id",
scopeValue: user.accountId,
allowSqlEvidence: false, // hide SQL and model-authored text for this session
});

Note for integration agents: if your users report seeing the "Analysis complete … hidden by this embed session's evidence policy" message, the cause is one of: (1) the minting key lacks embed.sql_evidence.read — recreate the key with runtime permissions, or (2) your mint call passes allowSqlEvidence: false — remove it. Since the default flip (2026-08-22), omitting the field shows evidence.

Use dataira.dataPolicies.list/create/update for typed, generation-CAS policy management. Bind a trusted server identity with dataira.setUserAccess({ endUserOrgId, endUserId, datasourceIds, policyId, roles, attributes }). Policy documents and role/attribute bindings stay server-side; never recreate them in browser code.

Public SDK functions and JSON use camelCase. Database columns and JWT claims use snake_case; HTTP paths and package/file names use kebab-case.

Provision Projects and Environments

Use the tenant-level management credential from the Partner portal for this section. It may provision scopes and runtime keys, but it cannot mint end-user tokens itself.

const project = await dataira.projects.create("Acme Analytics");
const production = project.environments[0]; // created automatically
const staging = await dataira.projects.createEnvironment(project.id, {
name: "Staging",
slug: "staging",
});

Environments are optional beyond production. Use them when credentials, access policy, or end-user assets must be isolated between deployments.

Create an environment-scoped API key

const created = await dataira.apiKeys.create({
name: "Acme production backend",
projectId: project.id,
environmentId: production.id,
});

storeSecret(created.token); // returned once

Both IDs are required and the Environment must belong to the Project. List and revoke keys with dataira.apiKeys.list() and dataira.apiKeys.revoke(id). Construct the token-minting Dataira client with created.token; that key is then fixed to the selected Project and Environment.

Backends in other languages can call the same /api/v1/embed/* endpoints directly; no Dataira backend SDK or Dataira-hosted user database is required.

Choose an API integration track

TrackIdentity and transportStatus
Service credentialDataira stores a least-privilege API token; user scope comes from a governed server policyCurrent OpenAPI preview
Delegated identityAllowlisted partner JWT, or trusted assertion exchanged for a short-lived upstream tokenSpecified, later
GraphQLPersisted operations with field/depth/cost limits; reuses governed identitySpecified, later; not an auth mode

Never forward a browser session token as an upstream credential. The later JWT profile pins issuer, audience, algorithms, JWKS, claims, rotation, and revocation. The later delegated exchange keeps both assertions server-to-server.

Add a governed OpenAPI source

The public preview is spec-driven. Dataira fetches the same-origin JSON or YAML spec, resolves local references, compiles only your selected operations, pins the public addresses, and stores upstream headers encrypted. Check capabilities instead of assuming the environment is enabled.

const capabilities = await dataira.sourceConnectors.capabilities();
if (!capabilities.openapi.configuration || !capabilities.openapi.execution ||
!capabilities.openapi.canonicalSpec || capabilities.openapi.egress !== "private_pinned_ip") {
throw new Error("OpenAPI is unavailable");
}

await dataira.sourceConnectors.preflightOpenApi({
origin: "https://billing.example.com",
specUrl: "https://billing.example.com/openapi.json",
});

const source = await dataira.sourceConnectors.createOpenApi({
name: "Partner billing",
origin: "https://billing.example.com",
specUrl: "https://billing.example.com/openapi.json",
headers: { Authorization: `Bearer ${process.env.BILLING_READ_TOKEN!}` },
timeoutMs: 3000,
maxRows: 100,
maxBytes: 250000,
selectedOperations: [{
operationId: "listInvoices",
policyTables: ["invoices"],
parameters: [{ name: "account_id", location: "query", source: "policy",
key: "invoices.account_id", required: true, valueType: "string" }],
kind: "query", sideEffect: "none", mode: "sync", responseShape: "rows",
idempotency: "not_applicable", evidenceFields: ["invoice_id"],
responseFields: ["invoice_id", "amount", "currency", "issued_at"],
}],
}, { idempotencyKey: crypto.randomUUID() });

OpenAPI v2 accepts reviewed GET and POST operations declared as synchronous, side-effect-free queries or computations. It records immutable source/spec revisions and rejects remote references, unsafe destinations, redirects, and contract drift. async can be described but is rejected by the current runtime.

Author and execute an Analytical Pack

Construct dataira.analyticalPacks({ projectId, environmentId }) with a management key. Create an empty draft, resolve a preset with listPresets(), import its exact digest, and call analyzeOpenApi() with the registered source's exact generation, spec revision, and reviewed operation IDs. JSON/YAML, structured Markdown, and agent proposals are bounded untrusted inputs. Preview diagnostics and conflicts before validate(), submitReview(), and publish(). No import publishes automatically and no conflict uses silent last-write-wins.

Mutations require an idempotency key and revision CAS; publish and rollback also require the active generation returned by getActive(). The same published context is used by embed, SDK, REST, and MCP. Follow the complete, reproducible FretGuard OpenAPI pilot.

Execute a published operation with dataira.analyticalRuntime.execute. This method requires the short-lived end-user access token, an idempotency key, and source.datasourceAuthorizationVersion returned by sourceConnectors.list() or create/update. It returns the normalized result and persisted execution receipt; it never accepts a management key as a substitute for end-user identity.

Publication currently evaluates structure, selected operations, side effects, and output fields after exact source-contract validation. It does not call the partner API. A safe server-owned principal and policy for post-publish live conformance remain a product decision. Packages are not public, capabilities are not promoted, and this documentation does not imply a production deploy.

Run pnpm --filter @dataira/node example:conformance before launch. Replace the example adapters with trusted SQL and OpenAPI callbacks for the same two test users. The runner proves own-marker visibility, cross-scope override denial, revocation, and continuity for the unaffected peer.