Skip to main content

Use the TypeScript SDK

Goal​

You'll install the official @dq-cloud/sdk package, authenticate with a personal API key, and run three worked examples — listing datasources, running a validation, and following its execution runs — without writing any HTTP code yourself.

Prereqs​

  • Node 18 or newer (or any runtime with a global fetch: modern browsers, Cloudflare Workers, Deno, Vercel Edge).
  • A running Measured Cloud instance and an org you can see in the UI.
  • A personal API key — mint one under Settings → API keys (see Create an API token). The key starts with dqk_. Agent tokens (dqa_) work too; JWT session tokens do not.

Install​

npm install @dq-cloud/sdk

The package targets Node 18+ and any environment with a global fetch. It ships ESM and CJS builds with TypeScript declaration files. Zero runtime dependencies.

Authenticate​

The SDK takes the API key and the base URL of your install:

import { DQCloudClient } from "@dq-cloud/sdk";

const client = new DQCloudClient({
apiKey: "dqk_...",
baseUrl: "https://dq.example.com",
});

429 and 503 responses are retried automatically with exponential backoff (plus jitter). Pass retryCount: 0 to opt out, or tune backoffBaseMs / backoffCapMs to fit your environment.

Browser caveat: putting a dqk_ directly in shipped browser code exposes it to anyone with devtools. For browser-side use, scope the key narrowly or proxy through your own backend. Read-only public dashboards that already accept anonymous traffic are fine.

Example 1 — list datasources​

import { DQCloudClient } from "@dq-cloud/sdk";

const orgId = "11111111-1111-1111-1111-111111111111";

const client = new DQCloudClient({
apiKey: "dqk_...",
baseUrl: "https://dq.example.com",
});

for (const ds of await client.datasources.list({ orgId })) {
console.log(ds.name, ds.type, ds.execution_mode);
}

If the key is wrong you'll see an AuthError. If the org doesn't exist (or your key isn't scoped to it) you'll see NotFoundError.

Example 2 — run a validation and wait​

Validations are exposed as client.validations, and their runs as client.executionRuns:

import { DQCloudClient, DQCloudError, EXECUTION_RUN_FAILED_STATUSES } from "@dq-cloud/sdk";

const client = new DQCloudClient({
apiKey: "dqk_...",
baseUrl: "https://dq.example.com",
});

try {
const run = await client.validations.run("validation-uuid", {
orgId: "org-uuid",
workspaceId: "ws-uuid",
wait: true,
timeoutMs: 300_000,
});

console.log("status:", run.status, "health:", run.health_score);
if (EXECUTION_RUN_FAILED_STATUSES.has(run.status)) process.exitCode = 1;
} catch (err) {
if (err instanceof DQCloudError) {
console.error("could not start the run:", err.message);
}
throw err;
}

wait: true polls the execution run every 2 000 ms (change it with pollIntervalMs) and throws if it hasn't finished within timeoutMs. A failed run is returned, not thrown, so check its status. Without wait, the call returns as soon as the run is queued, with its execution_run_id and parent_result_id; follow it later with client.executionRuns.wait(...). Pass rule_ids to run only some of the validation's rules. Stop a run with client.validations.cancelRun(validationId, { orgId, workspaceId, parentResultId }).

To check one table, run its default validation: every data asset with rules has one.

Example 3 — list a validation's recent runs​

import { DQCloudClient } from "@dq-cloud/sdk";

const client = new DQCloudClient({ apiKey: "dqk_...", baseUrl: "https://dq.example.com" });

const page = await client.executionRuns.list("validation-uuid", {
orgId: "org-uuid",
workspaceId: "ws-uuid",
limit: 10,
});

for (const run of page.data) {
console.log(run.id, run.trigger, run.status, run.health_score);
}

Each run records what started it (trigger: manual, schedule, api, asset or rule). client.executionRuns.results(runId, { orgId, workspaceId }) returns a run's per-asset and per-rule results.

Deprecated: client.checkpoints. Checkpoints were retired (see Checkpoints (retired)). client.checkpoints and client.results.forCheckpoint still work for one release: a checkpoint's run runs the validation it maps to and returns its execution_run_id, and checkpoint writes throw without calling the API (the server answers them with 410 Gone). They are removed in the next major release — switch to client.validations and client.executionRuns.

Example 4 — add a rule to an asset​

Rules are exposed as client.rules. A rule lives on its data asset; it always joins the asset's default validation, and validation_ids adds it to other validations too:

const rule = await client.rules.create("asset-uuid", {
orgId: "org-uuid",
workspaceId: "ws-uuid",
data: {
rule_type: "expect_column_values_to_not_be_null",
kwargs: { column: "order_id" },
validation_ids: ["validation-uuid"],
},
});

const { data: rules } = await client.rules.list({
orgId: "org-uuid",
workspaceId: "ws-uuid",
validationId: "validation-uuid",
});

const run = await client.rules.run("asset-uuid", rule.id, {
orgId: "org-uuid",
workspaceId: "ws-uuid",
wait: true,
});

client.rules.list filters by dataAssetId or validationId and pages with limit / cursor; get returns one rule with the validation_ids that hold it, update edits a rule in place, delete removes it, and setValidations sets which validations hold it.

Deprecated: client.ruleSuites. Rule suites were retired (see Rule suites (retired)). For one release client.ruleSuites reads the API's read-only alias (list, get, validate); its writes throw without calling the API (the server answers them with 410 Gone). Switch to client.rules.

Verify​

  • npm ls @dq-cloud/sdk reports a version starting at 0.1.0.
  • npx tsx examples/01-list-datasources.ts (in the SDK repo) prints your datasources.
  • Errors raise typed exceptions (AuthError, NotFoundError, RateLimitError, ValidationFailedError, ServerError) — your catch clauses don't need to inspect response.status.

Caveats​

  • Streaming endpoints (data-docs blobs, large export downloads) aren't exposed yet. Use a plain fetch call for those for now.
  • Token revocation isn't instant on the server (HARDEN-7 cache). A revoked key may keep working for up to TOKEN_CACHE_TTL_SECONDS (default 5 seconds) after revocation.
  • For browser builds, prefer wrapping the SDK in a server-side proxy so your API key never reaches the client.