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 checkpoint, and tailing validation results — 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 PLACEHOLDER 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 checkpoint and wait

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

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

try {
const result = (await client.checkpoints.run("checkpoint-uuid", {
orgId: "org-uuid",
workspaceId: "ws-uuid",
wait: true,
timeoutMs: 300_000,
})) as ValidationResult;

console.log("success?", result.success);
console.log("ran at", result.run_time);
} catch (err) {
if (err instanceof DQCloudError) {
console.error("checkpoint failed:", err.message);
}
throw err;
}

wait: true polls validation-results until the worker writes a terminal row. The default poll interval is 2 000 ms — change it with pollIntervalMs. If the checkpoint takes longer than timeoutMs the SDK throws.

Example 3 — tail validation results

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

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

async function* tail(checkpointId: string) {
const seen = new Set<string>();
while (true) {
const page = await client.results.forCheckpoint(checkpointId, {
orgId: "org-uuid",
workspaceId: "ws-uuid",
limit: 25,
});
for (const r of [...page].reverse()) {
if (r.id && !seen.has(r.id)) {
seen.add(r.id);
yield r;
}
}
await new Promise((res) => setTimeout(res, 5_000));
}
}

for await (const r of tail("checkpoint-uuid")) {
console.log(r.run_time, r.success);
}

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.