Skip to main content
@conduit/client is a thin, typed TypeScript and JavaScript client for the Conduit API. It is read-only and has no runtime dependencies: it uses the global fetch (Node 18+ or browsers). It targets the same response envelope and the same stable error codes as the HTTP API, so what you learn from the REST surface carries over directly. The SDK adds three things over raw fetch: typed methods for each endpoint, a ConduitError thrown on non-2xx responses, and an async iterator that auto-follows cursor pagination.

Install and build

cd clients/typescript
npm install
npm run build   # emits dist/index.js + dist/index.d.ts

Construct the client

Pass your API key. The base URL defaults to https://data.quantoraresearch.com, and the key is sent as x-api-key on every request.
import { ConduitClient } from "@conduit/client";

const conduit = new ConduitClient({
  apiKey: process.env.CONDUIT_API_KEY,
  // baseUrl defaults to https://data.quantoraresearch.com
  // fetch: customFetch, // optional: override the fetch implementation (e.g. for tests)
});
The constructor accepts apiKey, baseUrl, and fetch. On a runtime older than Node 18 with no global fetch, pass your own implementation via the fetch option or the client throws at construction.

Make a call

Every typed method returns the full envelope, so you read data and meta exactly as you would from the HTTP API.
const { data, meta } = await conduit.getLatestObservations({ country: "USA" });
console.log(data);            // latest public reading per canonical indicator
console.log(meta.api_version); // "v1"
Typed methods include listIndicators, listCountries, countryIndicators, resolveEntity, getObservations, getLatestObservations, getProvenance, screen, screenerFields, crossCountry, ratesAnalytics, economicCalendar, officialEvents, coverage, and sourceHealth. The low-level request(path, params) escape hatch returns the same envelope for any endpoint not yet wrapped.

Auto-paginate with the async iterator

paginate is an async generator that walks every page of a list endpoint for you, following meta.pagination.next_cursor until it is exhausted. It yields one item at a time, so you never touch a cursor.
for await (const observation of conduit.paginate("/v1/public/observations", {
  indicator_id: "cpi_inflation_yoy",
  country: "GBR",
})) {
  // each observation across all pages, in order
  console.log(observation);
}
Set limit (1 to 500) in the params to control page size. The iterator still returns every matching item regardless of page size; a larger limit just means fewer round trips.

Build screener filters

The screener takes a filter DSL of comma-separated field:operator:value clauses that are AND-ed together. buildScreenerFilter serializes structured clauses into that string so you do not assemble it by hand. The screen method accepts either form.
import { ConduitClient, buildScreenerFilter } from "@conduit/client";

const conduit = new ConduitClient({ apiKey: process.env.CONDUIT_API_KEY });

const filter = buildScreenerFilter([
  { field: "cpi_inflation_yoy", operator: "gt", value: 3 },
  { field: "unemployment_rate", operator: "lt", value: 5 },
]);
// "cpi_inflation_yoy:gt:3,unemployment_rate:lt:5"

const result = await conduit.screen(filter);
Operators are gt, lt, gte, lte, eq, and in. For in, pass an array; buildScreenerFilter joins it with the pipe separator the DSL expects. Discover the screenable canonical-indicator fields with conduit.screenerFields().
The screener screens public canonical-indicator values only. It never exposes any internal scoring.

Handle errors

Non-2xx responses throw a ConduitError carrying the stable code, the HTTP status, the message, the requestId, and any details. This is the same error contract as the REST API.
import { ConduitError } from "@conduit/client";

try {
  await conduit.screen("oops");
} catch (error) {
  if (error instanceof ConduitError) {
    console.error(error.code, error.status, error.message, error.requestId);
    // e.g. "bad_request" 400 "..." "<uuid>"
  } else {
    throw error;
  }
}
The code is one of the stable values shared with the HTTP API: bad_request, unauthorized, forbidden, not_found, rate_limited, internal_error. Branch on code, not on the human-readable message.
Unknown query parameters are rejected, not ignored. A typo in a param name throws ConduitError with code bad_request rather than silently returning unfiltered data. Catch it early in development.

MCP server

Native read-only tools for Claude Code, Claude Desktop, and Cursor.

llms.txt

The keyless text indexes that describe the API to an agent.